Finishes moving commands to separate classes
This commit is contained in:
parent
db4f080ac8
commit
6c897b4ddf
@ -18,12 +18,12 @@ import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
|
||||
import net.knarcraft.bookswithoutborders.utility.BookFormatter;
|
||||
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
|
||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
@ -40,6 +40,9 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName;
|
||||
|
||||
public class BooksWithoutBorders extends JavaPlugin {
|
||||
protected static int bookDuplicateLimit;
|
||||
//The separating string between the book title and the book author
|
||||
@ -62,7 +65,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
protected static ConsoleCommandSender consoleSender;
|
||||
public static String bookFolder;
|
||||
public static final ChatColor errorColor = ChatColor.RED;
|
||||
protected static final ChatColor successColor = ChatColor.GREEN;
|
||||
public static final ChatColor successColor = ChatColor.GREEN;
|
||||
public static final ChatColor commandColor = ChatColor.YELLOW;
|
||||
|
||||
@Override
|
||||
@ -86,7 +89,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
registerCommand("delete", new CommandDelete(this), null);
|
||||
registerCommand("deletePublic", new CommandDeletePublic(this), null);
|
||||
registerCommand("copy", new CommandCopy(this), null);
|
||||
registerCommand("unSign", new CommandUnSign(this), null);
|
||||
registerCommand("unSign", new CommandUnSign(), null);
|
||||
registerCommand("encrypt", new CommandEncrypt(this), null);
|
||||
registerCommand("setBookPrice", new CommandSetBookPrice(this), null);
|
||||
registerCommand("setLore", new CommandSetLore(), null);
|
||||
@ -96,12 +99,16 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
registerCommand("setTitle", new CommandSetTitle(), null);
|
||||
registerCommand("load", new CommandLoad(this), null);
|
||||
registerCommand("loadPublic", new CommandLoadPublic(this), null);
|
||||
registerCommand("booksWithoutBorders", new CommandBooksWithoutBorders(this), null);
|
||||
registerCommand("reload", new CommandReload(this), null);
|
||||
registerCommand("givePublic", new CommandGivePublic(this), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a command
|
||||
*
|
||||
* @param commandName <p>The name of the command to register</p>
|
||||
* @param executor <p>The executor to register for the command</p>
|
||||
* @param executor <p>The executor to register for the command</p>
|
||||
*/
|
||||
private void registerCommand(String commandName, CommandExecutor executor, TabCompleter tabCompleter) {
|
||||
PluginCommand pluginCommand = this.getCommand(commandName);
|
||||
@ -196,7 +203,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
return loadExistingPlayers();
|
||||
}
|
||||
|
||||
protected boolean loadConfig() {
|
||||
public boolean loadConfig() {
|
||||
this.reloadConfig();
|
||||
try {
|
||||
useYml = this.getConfig().getBoolean("Options.Save_Books_in_Yaml_Format", true);
|
||||
@ -261,7 +268,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
return (eco != null);
|
||||
}
|
||||
|
||||
protected boolean loadExistingPlayers() {
|
||||
public boolean loadExistingPlayers() {
|
||||
File fTest = new File(this.getDataFolder().getAbsolutePath() + SLASH + "Existing Players.txt");
|
||||
existingPlayers = new ArrayList<>();
|
||||
|
||||
@ -325,236 +332,6 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
|
||||
if ((command.getName().equalsIgnoreCase("BooksWithoutBorders") || command.getName().equalsIgnoreCase("bwb"))) {
|
||||
if (args.length == 0 && sender instanceof Player) {
|
||||
//Lists all commands
|
||||
sender.sendMessage(commandColor + "Use: /bwb [Command]");
|
||||
sender.sendMessage(commandColor + "[] denote parameters");
|
||||
|
||||
if (booksHavePrice()) {
|
||||
if (bookPriceType != Material.AIR) {
|
||||
sendErrorMessage(sender, "[" + (int) bookPriceQuantity + " " + bookPriceType.toString() + "(s) are required to create a book]");
|
||||
} else {
|
||||
sendErrorMessage(sender, "[" + BooksWithoutBorders.eco.format(bookPriceQuantity) + " is required to create a book]");
|
||||
}
|
||||
}
|
||||
sender.sendMessage(commandColor + "Commands:");
|
||||
|
||||
if (sender.hasPermission("bookswithoutborders.load")) {
|
||||
sender.sendMessage(commandColor + "\nLoad [file name or number] [# of copies] [true/false]:");
|
||||
sendSuccessMessage(sender, "Creates a book from the specified file and gives it to the player");
|
||||
sendSuccessMessage(sender, "If no file is specified, a list of available files is returned");
|
||||
sendSuccessMessage(sender, "If true is specified the book will be signed, if false it will be");
|
||||
sendSuccessMessage(sender, "unsigned");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.loadPublic")) {
|
||||
sender.sendMessage(commandColor + "loadPublic [file name or number] [# of copies] [true/false]:");
|
||||
sendSuccessMessage(sender, "Same as Load, but views files in the public directory");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.save")) {
|
||||
sender.sendMessage("\n" + commandColor + "Save [true/false]: " + successColor + "Saves the book the player is");
|
||||
sendSuccessMessage(sender, "holding to a text file in a private directory");
|
||||
sendSuccessMessage(sender, "If true is specified, a book of the same name by the same");
|
||||
sendSuccessMessage(sender, "author will be overwritten by the new book");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.savePublic")) {
|
||||
sender.sendMessage(commandColor + "savePublic [true/false]: " + successColor + "Same as Save,");
|
||||
sendSuccessMessage(sender, "but saves files in the public directory");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.give")) {
|
||||
sender.sendMessage("\n" + commandColor + "Give [file name or number] [player name] [# of copies] [true/false]:");
|
||||
sendSuccessMessage(sender, "Gives the selected player a book from your personal directory");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.givePublic")) {
|
||||
sender.sendMessage(commandColor + "givePublic [file name or number] [player name] [# of copies] [true/false]:");
|
||||
sendSuccessMessage(sender, "Same as give, but uses books from the public directory");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.delete")) {
|
||||
sender.sendMessage(commandColor + "\nDelete [file name or number]: " + successColor + "Deletes the specified");
|
||||
sendSuccessMessage(sender, "file in the player's directory");
|
||||
sendSuccessMessage(sender, "If no file is specified, a list of available files is returned");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.admin")) {
|
||||
sender.sendMessage(commandColor + "deletePublic [file name or number]: " + successColor + "Same as Delete,");
|
||||
sendSuccessMessage(sender, "but deletes files in the public directory");
|
||||
sender.sendMessage(commandColor + "\nReload:" + successColor + " Reloads BwB's configuration file");
|
||||
}
|
||||
|
||||
if (sender.hasPermission("bookswithoutborders.unsign")) {
|
||||
sender.sendMessage("\n" + commandColor + "Unsign: " + successColor + "Un-signs the book the player is holding");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.copy")) {
|
||||
sender.sendMessage("\n" + commandColor + "Copy [number of copies]: " + successColor + "Copies the book the player is holding");
|
||||
}
|
||||
|
||||
if (sender.hasPermission("bookswithoutborders.encrypt")) {
|
||||
sender.sendMessage("\n" + commandColor + "Encrypt [key] [style]: " + successColor + "Encrypts the book the player is holding");
|
||||
sender.sendMessage(commandColor + "[key]" + successColor + " is required and can be any phrase or number excluding spaces");
|
||||
sender.sendMessage(commandColor + "[style]" + successColor + " is not required. Possible values are \"DNA\" or \"Magic\"");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.groupEncrypt")) {
|
||||
sender.sendMessage("\n" + commandColor + "groupEncrypt [group name] [key] [style]: " + successColor + "Encrypts book so that only players with the" +
|
||||
"\n bookswithoutborders.decrypt." + commandColor + "[group name]" + successColor + " permission may decrypt the book by holding and left clicking the book");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.decrypt")) {
|
||||
sender.sendMessage("\n" + commandColor + "Decrypt [key]: " + successColor + "Decrypts the book the player is holding");
|
||||
sender.sendMessage(commandColor + "[key]" + successColor + " is required and MUST be IDENTICAL to the key used to encrypt held book");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.setTitle")) {
|
||||
sender.sendMessage("\n" + commandColor + "setTitle [title]: " + successColor + "Sets the title of the book/item the player is holding");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.setAuthor")) {
|
||||
sender.sendMessage("\n" + commandColor + "setAuthor [author]: " + successColor + "Sets the author of the book the player is holding");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.setLore")) {
|
||||
sender.sendMessage("\n" + commandColor + "setLore [lore]: " + successColor + "Sets the lore of the item the player is holding");
|
||||
sendSuccessMessage(sender, "Insert the lore_line_separator character to force a new line\n[\"~\" by default]");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.setBookPrice")) {
|
||||
sender.sendMessage("\n" + commandColor + "setBookPrice [Item/Eco] [quantity]: " + successColor + "Sets the per-book-price to create a book via commands." +
|
||||
"\nIf [Item], the item in the player's hand in the amount of [quantity] will be the price.\nIf [Eco], a Vault based economy will be used for price." +
|
||||
"\nIf neither [Item/Eco] or [quantity] are specified the current price to create books will be removed.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
//lists commands from console
|
||||
sender.sendMessage(commandColor + "Use: /bwb [Command]");
|
||||
sender.sendMessage(commandColor + "[] denote parameters");
|
||||
sender.sendMessage(commandColor + "Commands:");
|
||||
sender.sendMessage(commandColor + "\nReload:" + successColor + " Reloads BwB's config file");
|
||||
sender.sendMessage(commandColor + "givePublic [file name or number] [player name] [true/false]: " + successColor);
|
||||
sendSuccessMessage(sender, "Gives the selected player a book from the public directory");
|
||||
sendSuccessMessage(sender, "If no file is specified, a list of available files is returned");
|
||||
sender.sendMessage(commandColor + "deletePublic [file name or number]: " + successColor + "Deletes the specified");
|
||||
sendSuccessMessage(sender, "file in the public directory");
|
||||
sendSuccessMessage(sender, "If no file is specified, a list of available files is returned");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("reload")) {
|
||||
if (sender instanceof Player) {
|
||||
if (!sender.hasPermission("bookswithoutborders.admin") && !sender.hasPermission("*")) {
|
||||
sendErrorMessage(sender, "You don't have permission to use this command!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (loadConfig() && loadExistingPlayers()) {
|
||||
sendSuccessMessage(sender, "BooksWithoutBorders configuration reloaded!");
|
||||
} else {
|
||||
sendErrorMessage(sender, "Reload Failed!");
|
||||
sendErrorMessage(sender, "See console for details");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("givePublic")) {
|
||||
if (sender instanceof Player) {
|
||||
if (!sender.hasPermission("bookswithoutborders.givePublic")) {
|
||||
sendErrorMessage(sender, " You don't have permission to use this command!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length == 2 || args.length > 5) {
|
||||
sendErrorMessage(sender, "Incorrect number of arguments for this command!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.length == 1) {
|
||||
loadList.put(sender.getName(), listFiles(sender, true, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int x = 0; x < args[1].length(); x++) {
|
||||
if (!Character.isDigit(args[1].charAt(x)))
|
||||
break;
|
||||
if (x == args[1].length() - 1)
|
||||
loadList.put(sender.getName(), listFiles(sender, true, true));
|
||||
}
|
||||
|
||||
ItemStack newBook;
|
||||
Player receivingPlayer = this.getServer().getPlayer(args[2]);
|
||||
if (receivingPlayer == null) {
|
||||
sendErrorMessage(sender, "Player not found!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (receivingPlayer.getInventory().firstEmpty() == -1) {
|
||||
sendErrorMessage(sender, "Receiving player must have space in their inventory to receive books!");
|
||||
return false;
|
||||
}
|
||||
//bwb give [book name] [player] [numCopies] [is signed]
|
||||
try {
|
||||
if (args.length == 5)
|
||||
newBook = loadBook(sender, cleanString(args[1]), args[4], "public", Integer.parseInt(args[3]));
|
||||
else if (args.length == 4) {
|
||||
if (args[3].equalsIgnoreCase("true") || args[3].equalsIgnoreCase("false"))
|
||||
newBook = loadBook(sender, cleanString(args[1]), args[3], "public");
|
||||
else
|
||||
newBook = loadBook(sender, cleanString(args[1]), "true", "public", Integer.parseInt(args[3]));
|
||||
} else
|
||||
newBook = loadBook(sender, cleanString(args[1]), "true", "public");
|
||||
|
||||
if (newBook != null) {
|
||||
receivingPlayer.getInventory().addItem(newBook);
|
||||
sendSuccessMessage(sender, "Book sent!");
|
||||
sendSuccessMessage(receivingPlayer, "Book received!");
|
||||
return true;
|
||||
} else {
|
||||
sendErrorMessage(sender, "Book failed to load!");
|
||||
return false;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
sendErrorMessage(sender, "Invalid number of book copies specified!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sendErrorMessage(sender, "Command not recognized! Use " + commandColor + "/BwB" + errorColor + " for more info!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any special character from a filename
|
||||
* @param fileName <p>The file name to clean</p>
|
||||
* @return <p>The cleaned file name</p>
|
||||
*/
|
||||
public String cleanString(String fileName) {
|
||||
fileName = fileName.replace("/", "");
|
||||
fileName = fileName.replace("\\", "");
|
||||
fileName = fileName.replace("*", "");
|
||||
fileName = fileName.replace(":", "");
|
||||
fileName = fileName.replace("|", "");
|
||||
fileName = fileName.replace("<", "");
|
||||
fileName = fileName.replace(">", "");
|
||||
fileName = fileName.replace("?", "");
|
||||
fileName = fileName.replace("\"", "");
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes spaces to underscores or underscores to spaces, depending on context
|
||||
* @param fileName <p>The file name to fix</p>
|
||||
* @param isLoading <p>Whether loading from a file as opposed to saving to a file</p>
|
||||
* @return <p>The fixed name</p>
|
||||
*/
|
||||
protected String fixName(String fileName, Boolean isLoading) {
|
||||
if (isLoading) {
|
||||
fileName = fileName.replace("_", " ");
|
||||
} else {
|
||||
fileName = fileName.replace(" ", "_");
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
protected void bookToYml(String path, String fileName, BookMeta book) throws IOException {
|
||||
FileConfiguration bookYml = YamlConfiguration.loadConfiguration(new File(path, "blank"));
|
||||
|
||||
@ -650,7 +427,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> pages = new ArrayList<>(cleanList(rawPages));
|
||||
List<String> pages = new ArrayList<>(InputCleaningHelper.cleanList(rawPages));
|
||||
|
||||
bDat.setAuthor(author);
|
||||
bDat.setTitle(title);
|
||||
@ -816,10 +593,90 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
return book;
|
||||
}
|
||||
|
||||
protected Boolean eSave(Player player, BookMeta book, String key) {
|
||||
/**
|
||||
* Makes the player pay for printing a given number of books
|
||||
*
|
||||
* @param player <p>The player printing the books</p>
|
||||
* @param numCopies <p>The number of copies the player is trying to print</p>
|
||||
* @return <p>True if the player cannot pay for the printing of the books</p>
|
||||
*/
|
||||
public boolean cannotPayForBookPrinting(Player player, int numCopies) {
|
||||
//BookPriceQuantity: How many items are required to pay for each book
|
||||
//BookPriceType: Which item is used to pay for the books. AIR = use economy
|
||||
double cost = BooksWithoutBorders.bookPriceQuantity * numCopies;
|
||||
int itemCost = (int) cost;
|
||||
|
||||
if (BooksWithoutBorders.bookPriceType == Material.AIR) {
|
||||
return !payForBookPrintingEconomy(player, cost, numCopies);
|
||||
} else {
|
||||
if (player.getInventory().contains(BooksWithoutBorders.bookPriceType, itemCost)) {
|
||||
payForBookPrintingItem(player, itemCost);
|
||||
return false;
|
||||
} else {
|
||||
BooksWithoutBorders.sendErrorMessage(player, itemCost + " " + BooksWithoutBorders.bookPriceType.toString() +
|
||||
"(s) are required for this command!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses economy to take payment for printing a number of books
|
||||
*
|
||||
* @param player <p>The player which needs to pay</p>
|
||||
* @param cost <p>The cost of the book printing</p>
|
||||
* @param numCopies <p>The number of books the player is printing</p>
|
||||
* @return <p>True if the player had the money and it has been withdrawn</p>
|
||||
*/
|
||||
private boolean payForBookPrintingEconomy(Player player, double cost, int numCopies) {
|
||||
Economy economy = BooksWithoutBorders.eco;
|
||||
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)));
|
||||
return true;
|
||||
} else {
|
||||
BooksWithoutBorders.sendErrorMessage(player, economy.format(cost) + " is required for this command!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes payment for printing a number of books by withdrawing the correct item
|
||||
*
|
||||
* @param player <p>The player which needs to pay</p>
|
||||
* @param itemCost <p>The number of items to pay</p>
|
||||
*/
|
||||
private void payForBookPrintingItem(Player player, int itemCost) {
|
||||
PlayerInventory playerInventory = player.getInventory();
|
||||
|
||||
int clearedAmount = 0;
|
||||
while (clearedAmount < itemCost) {
|
||||
int firstItemIndex = playerInventory.first(BooksWithoutBorders.bookPriceType);
|
||||
ItemStack firstItem = playerInventory.getItem(firstItemIndex);
|
||||
|
||||
if (Objects.requireNonNull(firstItem).getAmount() <= itemCost - clearedAmount) {
|
||||
clearedAmount += firstItem.getAmount();
|
||||
player.getInventory().clear(firstItemIndex);
|
||||
} else {
|
||||
clearedAmount = itemCost;
|
||||
firstItem.setAmount(firstItem.getAmount() - (clearedAmount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves an encrypted book to be decryptable for the given user
|
||||
*
|
||||
* @param player <p>The player encrypting the book</p>
|
||||
* @param bookMetaData <p>Metadata for the book to encrypt</p>
|
||||
* @param key <p>The key to use for encryption</p>
|
||||
* @return <p>The new encrypted metadata for the book, or null if encryption failed</p>
|
||||
*/
|
||||
protected Boolean saveEncryptedBook(Player player, BookMeta bookMetaData, String key) {
|
||||
String path = bookFolder + "Encrypted" + SLASH;
|
||||
String fileName = (!book.hasTitle()) ? "Untitled," + player.getName() :
|
||||
book.getTitle() + titleAuthorSeparator + book.getAuthor();
|
||||
String fileName = (!bookMetaData.hasTitle()) ? "Untitled," + player.getName() :
|
||||
bookMetaData.getTitle() + titleAuthorSeparator + bookMetaData.getAuthor();
|
||||
|
||||
fileName = "[" + key + "]" + fileName;
|
||||
fileName = cleanString(fileName);
|
||||
@ -832,7 +689,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
}
|
||||
|
||||
try {
|
||||
bookToYml(path, fileName, book);
|
||||
bookToYml(path, fileName, bookMetaData);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
sendErrorMessage(player, "Encryption failed!");
|
||||
@ -841,7 +698,15 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected BookMeta groupESave(Player player, BookMeta bookMetadata, String groupName) {
|
||||
/**
|
||||
* Saves an encrypted book to be decryptable for the given group
|
||||
*
|
||||
* @param player <p>The player trying to encrypt the book</p>
|
||||
* @param bookMetadata <p>Metadata for the book to encrypt</p>
|
||||
* @param groupName <p>The group which should be able to decrypt the book</p>
|
||||
* @return <p>The new encrypted metadata for the book, or null if encryption failed</p>
|
||||
*/
|
||||
protected BookMeta saveEncryptedBookForGroup(Player player, BookMeta bookMetadata, String groupName) {
|
||||
String path = bookFolder + "Encrypted" + SLASH + cleanString(groupName) + SLASH;
|
||||
File dirTest = new File(path);
|
||||
//Creates group dir
|
||||
@ -863,15 +728,15 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
fileName = cleanString(fileName);
|
||||
fileName = fixName(fileName, false);
|
||||
|
||||
List<String> nuLore = new ArrayList<>();
|
||||
nuLore.add(ChatColor.GRAY + "[" + groupName + " encrypted]");
|
||||
List<String> newLore = new ArrayList<>();
|
||||
newLore.add(ChatColor.GRAY + "[" + groupName + " encrypted]");
|
||||
if (bookMetadata.hasLore()) {
|
||||
List<String> oldLore = bookMetadata.getLore();
|
||||
if (oldLore != null) {
|
||||
nuLore.addAll(oldLore);
|
||||
newLore.addAll(oldLore);
|
||||
}
|
||||
}
|
||||
bookMetadata.setLore(nuLore);
|
||||
bookMetadata.setLore(newLore);
|
||||
|
||||
//Save file
|
||||
File file = (useYml) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt");
|
||||
@ -888,7 +753,15 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
return bookMetadata;
|
||||
}
|
||||
|
||||
public ItemStack eLoad(Player player, String key, boolean deleteEncryptedFile) {
|
||||
/**
|
||||
* Loads an encrypted book
|
||||
*
|
||||
* @param player <p>The player trying to load the book</p>
|
||||
* @param key <p>The encryption key/password for decryption</p>
|
||||
* @param deleteEncryptedFile <p>Whether to delete the plaintext file after decryption is finished</p>
|
||||
* @return <p>The loaded book, or null if no book could be loaded</p>
|
||||
*/
|
||||
public ItemStack loadEncryptedBook(Player player, String key, boolean deleteEncryptedFile) {
|
||||
ItemStack heldBook = InventoryHelper.getHeldBook(player, true);
|
||||
BookMeta bookMetadata = (BookMeta) heldBook.getItemMeta();
|
||||
String path = bookFolder + "Encrypted" + SLASH;
|
||||
@ -897,7 +770,8 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
return null;
|
||||
}
|
||||
|
||||
String fileName = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() : bookMetadata.getTitle() + titleAuthorSeparator + bookMetadata.getAuthor();
|
||||
String fileName = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() : bookMetadata.getTitle() +
|
||||
titleAuthorSeparator + bookMetadata.getAuthor();
|
||||
fileName = "[" + key + "]" + fileName;
|
||||
fileName = cleanString(fileName);
|
||||
fileName = fixName(fileName, false);
|
||||
@ -955,18 +829,6 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
return FileHelper.listFiles(sender, file, silent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes null and empty items from a list
|
||||
*
|
||||
* @param list <p>The list to clean</p>
|
||||
* @return <p>A clean list containing all relevant values</p>
|
||||
*/
|
||||
protected List<String> cleanList(List<String> list) {
|
||||
List<String> resultList = new ArrayList<>(list);
|
||||
resultList.removeIf((item) -> item == null || item.trim().isEmpty());
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a book
|
||||
*
|
||||
@ -1016,7 +878,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
//Format the last page just in case
|
||||
BookFormatter.formatLastPage(encryptedPages);
|
||||
//Remove empty pages
|
||||
List<String> newPages = cleanList(encryptedPages);
|
||||
List<String> newPages = InputCleaningHelper.cleanList(encryptedPages);
|
||||
|
||||
ItemStack encryptedBook = createEncryptedBook(book, newPages, player, newMetadata);
|
||||
|
||||
@ -1060,9 +922,9 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
BookMeta newMetadata = book;
|
||||
boolean wasSaved;
|
||||
if (groupName.trim().isEmpty()) {
|
||||
wasSaved = eSave(player, book, integerKey);
|
||||
wasSaved = saveEncryptedBook(player, book, integerKey);
|
||||
} else {
|
||||
newMetadata = groupESave(player, book, groupName);
|
||||
newMetadata = saveEncryptedBookForGroup(player, book, groupName);
|
||||
wasSaved = newMetadata != null;
|
||||
}
|
||||
if (wasSaved) {
|
||||
@ -1092,67 +954,6 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
sender.sendMessage(errorColor + message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given book
|
||||
*
|
||||
* @param sender <p>The sender of the command to delete the book</p>
|
||||
* @param fileName <p>The file name of the book</p>
|
||||
* @param isPublic <p>Whether the book to delete is public or not</p>
|
||||
*/
|
||||
public void deleteBook(CommandSender sender, String fileName, Boolean isPublic) {
|
||||
//If the file name is an index of the load list, load the book
|
||||
try {
|
||||
int loadListIndex = Integer.parseInt(fileName);
|
||||
String senderName = sender.getName();
|
||||
if (loadList.containsKey(senderName) && loadListIndex <= loadList.get(senderName).size()) {
|
||||
fileName = loadList.get(senderName).get(loadListIndex - 1);
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
//Get the file to be deleted
|
||||
File file;
|
||||
if (isPublic) {
|
||||
file = FileHelper.getBookFile(bookFolder + fileName);
|
||||
} else {
|
||||
file = FileHelper.getBookFile(bookFolder + cleanString(sender.getName()) + SLASH + fileName);
|
||||
}
|
||||
|
||||
//Send message if no such file could be found
|
||||
if (file == null) {
|
||||
sendErrorMessage(sender, "Incorrect file name!");
|
||||
return;
|
||||
}
|
||||
|
||||
//Try to delete the file
|
||||
try {
|
||||
if (file.delete()) {
|
||||
sendSuccessMessage(sender, "\"" + fileName + "\" deleted successfully");
|
||||
} else {
|
||||
sendErrorMessage(sender, "Deletion failed without an exception!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sendErrorMessage(sender, "Deletion failed!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-signs the player's currently held book
|
||||
*
|
||||
* @param player <p>The player holding the book</p>
|
||||
* @param mainHand <p>Whether the player is holding the book in its main hand or its off hand</p>
|
||||
*/
|
||||
public void unSignHeldBook(Player player, boolean mainHand) {
|
||||
//Get the old book
|
||||
BookMeta oldBook = InventoryHelper.getHeldBookMetadata(player, mainHand);
|
||||
|
||||
//UnSign the book
|
||||
ItemStack newBook = new ItemStack(Material.WRITABLE_BOOK);
|
||||
newBook.setItemMeta(oldBook);
|
||||
|
||||
InventoryHelper.replaceHeldItem(player, newBook, mainHand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether books have a price for printing them
|
||||
*
|
||||
@ -1162,93 +963,4 @@ public class BooksWithoutBorders extends JavaPlugin {
|
||||
return (bookPriceType != null && bookPriceQuantity > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the player pay for printing a given number of books
|
||||
*
|
||||
* @param player <p>The player printing the books</p>
|
||||
* @param numCopies <p>The number of copies the player is trying to print</p>
|
||||
* @return <p>True if the player cannot pay for the printing of the books</p>
|
||||
*/
|
||||
public boolean cannotPayForBookPrinting(Player player, int numCopies) {
|
||||
//BookPriceQuantity: How many items are required to pay for each book
|
||||
//BookPriceType: Which item is used to pay for the books. AIR = use economy
|
||||
double cost = bookPriceQuantity * numCopies;
|
||||
int itemCost = (int) cost;
|
||||
|
||||
if (bookPriceType == Material.AIR) {
|
||||
return !payForBookPrintingEconomy(player, cost, numCopies);
|
||||
} else {
|
||||
if (player.getInventory().contains(bookPriceType, itemCost)) {
|
||||
payForBookPrintingItem(player, itemCost);
|
||||
return false;
|
||||
} else {
|
||||
sendErrorMessage(player, itemCost + " " + bookPriceType.toString() +
|
||||
"(s) are required for this command!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes payment for printing a number of books by withdrawing the correct item
|
||||
*
|
||||
* @param player <p>The player which needs to pay</p>
|
||||
* @param itemCost <p>The number of items to pay</p>
|
||||
*/
|
||||
private void payForBookPrintingItem(Player player, int itemCost) {
|
||||
PlayerInventory playerInventory = player.getInventory();
|
||||
|
||||
int clearedAmount = 0;
|
||||
while (clearedAmount < itemCost) {
|
||||
int firstItemIndex = playerInventory.first(bookPriceType);
|
||||
ItemStack firstItem = playerInventory.getItem(firstItemIndex);
|
||||
|
||||
if (Objects.requireNonNull(firstItem).getAmount() <= itemCost - clearedAmount) {
|
||||
clearedAmount += firstItem.getAmount();
|
||||
player.getInventory().clear(firstItemIndex);
|
||||
} else {
|
||||
clearedAmount = itemCost;
|
||||
firstItem.setAmount(firstItem.getAmount() - (clearedAmount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses economy to take payment for printing a number of books
|
||||
*
|
||||
* @param player <p>The player which needs to pay</p>
|
||||
* @param cost <p>The cost of the book printing</p>
|
||||
* @param numCopies <p>The number of books the player is printing</p>
|
||||
* @return <p>True if the player had the money and it has been withdrawn</p>
|
||||
*/
|
||||
private boolean payForBookPrintingEconomy(Player player, double cost, int numCopies) {
|
||||
Economy economy = BooksWithoutBorders.eco;
|
||||
if ((economy.getBalance(player) - cost) >= 0) {
|
||||
economy.withdrawPlayer(player, cost);
|
||||
sendSuccessMessage(player, economy.format(cost) + " withdrawn to create " + numCopies + " book(s)");
|
||||
sendSuccessMessage(player, "New balance: " + economy.format(economy.getBalance(player)));
|
||||
return true;
|
||||
} else {
|
||||
sendErrorMessage(player, economy.format(cost) + " is required for this command!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given player is the author of a given book
|
||||
*
|
||||
* @param player <p>The player to check</p>
|
||||
* @param book <p>The book to check</p>
|
||||
* @return <p>True if the player is the book's author</p>
|
||||
*/
|
||||
public boolean isAuthor(Player player, BookMeta book) {
|
||||
String author = book.getAuthor();
|
||||
if (author != null && cleanString(player.getName()).equalsIgnoreCase(cleanString(author))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
sendErrorMessage(player, "You must be the author of this book to use this command!");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import java.util.Objects;
|
||||
import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
|
||||
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
|
||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
@ -58,7 +59,7 @@ public class BooksWithoutBordersListener implements Listener {
|
||||
fileName = oldBook.getTitle() + BooksWithoutBorders.titleAuthorSeparator + oldBook.getAuthor();
|
||||
}
|
||||
|
||||
String cleanPlayerName = BooksWithoutBorders.bwb.cleanString(player.getName());
|
||||
String cleanPlayerName = InputCleaningHelper.cleanString(player.getName());
|
||||
|
||||
String[] possiblePaths = new String[]{
|
||||
bookFolder + fileName + ".yml",
|
||||
@ -359,7 +360,7 @@ public class BooksWithoutBordersListener implements Listener {
|
||||
|
||||
String fileName = oldBook.getTitle() + BooksWithoutBorders.titleAuthorSeparator + oldBook.getAuthor();
|
||||
|
||||
String encryptionFile = BooksWithoutBorders.bwb.cleanString(groupName) + slash + fileName + ".yml";
|
||||
String encryptionFile = InputCleaningHelper.cleanString(groupName) + slash + fileName + ".yml";
|
||||
|
||||
File file = new File(bookFolder + "Encrypted" + slash + encryptionFile);
|
||||
if (!file.isFile()) {
|
||||
@ -446,7 +447,7 @@ public class BooksWithoutBordersListener implements Listener {
|
||||
String lineText = ChatColor.stripColor(sign.getLine(2));
|
||||
String key = EncryptionHelper.getNumberKeyFromStringKey(lineText);
|
||||
|
||||
ItemStack book = BooksWithoutBorders.bwb.eLoad(player, key, false);
|
||||
ItemStack book = BooksWithoutBorders.bwb.loadEncryptedBook(player, key, false);
|
||||
if (book != null) {
|
||||
player.getInventory().setItem(hand, book);
|
||||
player.sendMessage(ChatColor.GREEN + "Book decrypted!");
|
||||
|
@ -1,12 +1,150 @@
|
||||
package net.knarcraft.bookswithoutborders.command;
|
||||
|
||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.bookPriceQuantity;
|
||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.bookPriceType;
|
||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.commandColor;
|
||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.sendErrorMessage;
|
||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.sendSuccessMessage;
|
||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.successColor;
|
||||
|
||||
/**
|
||||
* Command executor for the books without borders (bwb) command
|
||||
*/
|
||||
public class CommandBooksWithoutBorders implements CommandExecutor {
|
||||
|
||||
private final BooksWithoutBorders booksWithoutBorders;
|
||||
|
||||
public CommandBooksWithoutBorders(BooksWithoutBorders booksWithoutBorders) {
|
||||
this.booksWithoutBorders = booksWithoutBorders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
return false;
|
||||
if (sender instanceof Player) {
|
||||
showPlayerCommands(sender);
|
||||
} else {
|
||||
showConsoleCommands(sender);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows all commands available to the console
|
||||
* @param sender <p>The console which sent the command</p>
|
||||
*/
|
||||
private void showConsoleCommands(CommandSender sender) {
|
||||
sender.sendMessage(commandColor + "Use: /bwb [Command]");
|
||||
sender.sendMessage(commandColor + "[] denote parameters");
|
||||
sender.sendMessage(commandColor + "Commands:");
|
||||
sender.sendMessage(commandColor + "\nReload:" + successColor + " Reloads BwB's config file");
|
||||
sender.sendMessage(commandColor + "givePublic [file name or number] [player name] [true/false]: " + successColor);
|
||||
sendSuccessMessage(sender, "Gives the selected player a book from the public directory");
|
||||
sendSuccessMessage(sender, "If no file is specified, a list of available files is returned");
|
||||
sender.sendMessage(commandColor + "deletePublic [file name or number]: " + successColor + "Deletes the specified");
|
||||
sendSuccessMessage(sender, "file in the public directory");
|
||||
sendSuccessMessage(sender, "If no file is specified, a list of available files is returned");
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows all commands available to the sending player
|
||||
* @param sender <p>The player which sent the command</p>
|
||||
*/
|
||||
private void showPlayerCommands(CommandSender sender) {
|
||||
//Lists all commands
|
||||
sender.sendMessage(commandColor + "Use: /bwb [Command]");
|
||||
sender.sendMessage(commandColor + "[] denote parameters");
|
||||
|
||||
if (booksWithoutBorders.booksHavePrice()) {
|
||||
if (bookPriceType != Material.AIR) {
|
||||
sendErrorMessage(sender, "[" + (int) bookPriceQuantity + " " + bookPriceType.toString() + "(s) are required to create a book]");
|
||||
} else {
|
||||
sendErrorMessage(sender, "[" + BooksWithoutBorders.eco.format(bookPriceQuantity) + " is required to create a book]");
|
||||
}
|
||||
}
|
||||
sender.sendMessage(commandColor + "Commands:");
|
||||
|
||||
if (sender.hasPermission("bookswithoutborders.load")) {
|
||||
sender.sendMessage(commandColor + "\nLoad [file name or number] [# of copies] [true/false]:");
|
||||
sendSuccessMessage(sender, "Creates a book from the specified file and gives it to the player");
|
||||
sendSuccessMessage(sender, "If no file is specified, a list of available files is returned");
|
||||
sendSuccessMessage(sender, "If true is specified the book will be signed, if false it will be");
|
||||
sendSuccessMessage(sender, "unsigned");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.loadPublic")) {
|
||||
sender.sendMessage(commandColor + "loadPublic [file name or number] [# of copies] [true/false]:");
|
||||
sendSuccessMessage(sender, "Same as Load, but views files in the public directory");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.save")) {
|
||||
sender.sendMessage("\n" + commandColor + "Save [true/false]: " + successColor + "Saves the book the player is");
|
||||
sendSuccessMessage(sender, "holding to a text file in a private directory");
|
||||
sendSuccessMessage(sender, "If true is specified, a book of the same name by the same");
|
||||
sendSuccessMessage(sender, "author will be overwritten by the new book");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.savePublic")) {
|
||||
sender.sendMessage(commandColor + "savePublic [true/false]: " + successColor + "Same as Save,");
|
||||
sendSuccessMessage(sender, "but saves files in the public directory");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.give")) {
|
||||
sender.sendMessage("\n" + commandColor + "Give [file name or number] [player name] [# of copies] [true/false]:");
|
||||
sendSuccessMessage(sender, "Gives the selected player a book from your personal directory");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.givePublic")) {
|
||||
sender.sendMessage(commandColor + "givePublic [file name or number] [player name] [# of copies] [true/false]:");
|
||||
sendSuccessMessage(sender, "Same as give, but uses books from the public directory");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.delete")) {
|
||||
sender.sendMessage(commandColor + "\nDelete [file name or number]: " + successColor + "Deletes the specified");
|
||||
sendSuccessMessage(sender, "file in the player's directory");
|
||||
sendSuccessMessage(sender, "If no file is specified, a list of available files is returned");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.admin")) {
|
||||
sender.sendMessage(commandColor + "deletePublic [file name or number]: " + successColor + "Same as Delete,");
|
||||
sendSuccessMessage(sender, "but deletes files in the public directory");
|
||||
sender.sendMessage(commandColor + "\nReload:" + successColor + " Reloads BwB's configuration file");
|
||||
}
|
||||
|
||||
if (sender.hasPermission("bookswithoutborders.unsign")) {
|
||||
sender.sendMessage("\n" + commandColor + "Unsign: " + successColor + "Un-signs the book the player is holding");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.copy")) {
|
||||
sender.sendMessage("\n" + commandColor + "Copy [number of copies]: " + successColor + "Copies the book the player is holding");
|
||||
}
|
||||
|
||||
if (sender.hasPermission("bookswithoutborders.encrypt")) {
|
||||
sender.sendMessage("\n" + commandColor + "Encrypt [key] [style]: " + successColor + "Encrypts the book the player is holding");
|
||||
sender.sendMessage(commandColor + "[key]" + successColor + " is required and can be any phrase or number excluding spaces");
|
||||
sender.sendMessage(commandColor + "[style]" + successColor + " is not required. Possible values are \"DNA\" or \"Magic\"");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.groupEncrypt")) {
|
||||
sender.sendMessage("\n" + commandColor + "groupEncrypt [group name] [key] [style]: " + successColor + "Encrypts book so that only players with the" +
|
||||
"\n bookswithoutborders.decrypt." + commandColor + "[group name]" + successColor + " permission may decrypt the book by holding and left clicking the book");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.decrypt")) {
|
||||
sender.sendMessage("\n" + commandColor + "Decrypt [key]: " + successColor + "Decrypts the book the player is holding");
|
||||
sender.sendMessage(commandColor + "[key]" + successColor + " is required and MUST be IDENTICAL to the key used to encrypt held book");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.setTitle")) {
|
||||
sender.sendMessage("\n" + commandColor + "setTitle [title]: " + successColor + "Sets the title of the book/item the player is holding");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.setAuthor")) {
|
||||
sender.sendMessage("\n" + commandColor + "setAuthor [author]: " + successColor + "Sets the author of the book the player is holding");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.setLore")) {
|
||||
sender.sendMessage("\n" + commandColor + "setLore [lore]: " + successColor + "Sets the lore of the item the player is holding");
|
||||
sendSuccessMessage(sender, "Insert the lore_line_separator character to force a new line\n[\"~\" by default]");
|
||||
}
|
||||
if (sender.hasPermission("bookswithoutborders.setBookPrice")) {
|
||||
sender.sendMessage("\n" + commandColor + "setBookPrice [Item/Eco] [quantity]: " + successColor + "Sets the per-book-price to create a book via commands." +
|
||||
"\nIf [Item], the item in the player's hand in the amount of [quantity] will be the price.\nIf [Eco], a Vault based economy will be used for price." +
|
||||
"\nIf neither [Item/Eco] or [quantity] are specified the current price to create books will be removed.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.bookswithoutborders.command;
|
||||
|
||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -45,7 +46,7 @@ public class CommandCopy implements CommandExecutor {
|
||||
int copies = Integer.parseInt(args[0]);
|
||||
if (copies > 0) {
|
||||
if (BooksWithoutBorders.authorOnlyCopy && !player.hasPermission("bookswithoutborders.bypassAuthorOnlyCopy")) {
|
||||
if (!booksWithoutBorders.isAuthor(player, (BookMeta) Objects.requireNonNull(heldBook.getItemMeta())))
|
||||
if (!isAuthor(player, (BookMeta) Objects.requireNonNull(heldBook.getItemMeta())))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -70,4 +71,22 @@ public class CommandCopy implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given player is the author of a given book
|
||||
*
|
||||
* @param player <p>The player to check</p>
|
||||
* @param book <p>The book to check</p>
|
||||
* @return <p>True if the player is the book's author</p>
|
||||
*/
|
||||
private boolean isAuthor(Player player, BookMeta book) {
|
||||
String author = book.getAuthor();
|
||||
String playerName = InputCleaningHelper.cleanString(player.getName());
|
||||
if (author != null && playerName.equalsIgnoreCase(InputCleaningHelper.cleanString(author))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
BooksWithoutBorders.sendErrorMessage(player, "You must be the author of this book to use this command!");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public class CommandDecrypt implements CommandExecutor {
|
||||
|
||||
if (!key.equalsIgnoreCase("")) {
|
||||
//Decrypt the book
|
||||
ItemStack book = booksWithoutBorders.eLoad(player, key, false);
|
||||
ItemStack book = booksWithoutBorders.loadEncryptedBook(player, key, false);
|
||||
if (book != null) {
|
||||
InventoryHelper.setHeldWrittenBook(player, book);
|
||||
BooksWithoutBorders.sendSuccessMessage(player, "Book auto-decrypted!");
|
||||
@ -91,7 +91,7 @@ public class CommandDecrypt implements CommandExecutor {
|
||||
String key = EncryptionHelper.getNumberKeyFromStringKey(args[0]);
|
||||
|
||||
//Decrypt the book
|
||||
ItemStack book = booksWithoutBorders.eLoad(player, key, true);
|
||||
ItemStack book = booksWithoutBorders.loadEncryptedBook(player, key, true);
|
||||
if (book != null) {
|
||||
InventoryHelper.setHeldWrittenBook(player, book);
|
||||
BooksWithoutBorders.sendSuccessMessage(player, "Book decrypted!");
|
||||
|
@ -1,11 +1,15 @@
|
||||
package net.knarcraft.bookswithoutborders.command;
|
||||
|
||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Command executor for the delete command
|
||||
*/
|
||||
@ -47,7 +51,7 @@ public class CommandDelete implements CommandExecutor {
|
||||
return false;
|
||||
} else {
|
||||
if (!BooksWithoutBorders.loadList.get(sender.getName()).isEmpty()) {
|
||||
booksWithoutBorders.deleteBook(sender, args[0], deletePublic);
|
||||
performBookDeletion(sender, args[0], deletePublic);
|
||||
return true;
|
||||
} else {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "No files available to delete!");
|
||||
@ -59,4 +63,49 @@ public class CommandDelete implements CommandExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given book
|
||||
*
|
||||
* @param sender <p>The sender of the command to delete the book</p>
|
||||
* @param fileName <p>The file name of the book</p>
|
||||
* @param isPublic <p>Whether the book to delete is public or not</p>
|
||||
*/
|
||||
public void performBookDeletion(CommandSender sender, String fileName, Boolean isPublic) {
|
||||
//If the file name is an index of the load list, load the book
|
||||
try {
|
||||
int loadListIndex = Integer.parseInt(fileName);
|
||||
String senderName = sender.getName();
|
||||
if (BooksWithoutBorders.loadList.containsKey(senderName) && loadListIndex <= BooksWithoutBorders.loadList.get(senderName).size()) {
|
||||
fileName = BooksWithoutBorders.loadList.get(senderName).get(loadListIndex - 1);
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
//Get the file to be deleted
|
||||
File file;
|
||||
if (isPublic) {
|
||||
file = FileHelper.getBookFile(BooksWithoutBorders.bookFolder + fileName);
|
||||
} else {
|
||||
file = FileHelper.getBookFile(BooksWithoutBorders.bookFolder +
|
||||
InputCleaningHelper.cleanString(sender.getName()) + BooksWithoutBorders.SLASH + fileName);
|
||||
}
|
||||
|
||||
//Send message if no such file could be found
|
||||
if (file == null) {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "Incorrect file name!");
|
||||
return;
|
||||
}
|
||||
|
||||
//Try to delete the file
|
||||
try {
|
||||
if (file.delete()) {
|
||||
BooksWithoutBorders.sendSuccessMessage(sender, "\"" + fileName + "\" deleted successfully");
|
||||
} else {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "Deletion failed without an exception!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "Deletion failed!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.bookswithoutborders.command;
|
||||
|
||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -68,7 +69,7 @@ public class CommandGive implements CommandExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
String bookToLoad = booksWithoutBorders.cleanString(bookIdentifier);
|
||||
String bookToLoad = InputCleaningHelper.cleanString(bookIdentifier);
|
||||
try {
|
||||
ItemStack newBook = booksWithoutBorders.loadBook(player, bookToLoad, isSigned, "player", Integer.parseInt(copies));
|
||||
if (newBook != null) {
|
||||
|
@ -1,12 +1,87 @@
|
||||
package net.knarcraft.bookswithoutborders.command;
|
||||
|
||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
||||
|
||||
/**
|
||||
* Command executor for the give public command
|
||||
*/
|
||||
public class CommandGivePublic implements CommandExecutor {
|
||||
|
||||
private final BooksWithoutBorders booksWithoutBorders;
|
||||
|
||||
public CommandGivePublic(BooksWithoutBorders booksWithoutBorders) {
|
||||
this.booksWithoutBorders = booksWithoutBorders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
return false;
|
||||
if (sender instanceof Player) {
|
||||
if (!sender.hasPermission("bookswithoutborders.givePublic")) {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, " You don't have permission to use this command!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length == 2 || args.length > 5) {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "Incorrect number of arguments for this command!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.length == 1) {
|
||||
BooksWithoutBorders.loadList.put(sender.getName(), booksWithoutBorders.listFiles(sender, true, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int x = 0; x < args[1].length(); x++) {
|
||||
if (!Character.isDigit(args[1].charAt(x)))
|
||||
break;
|
||||
if (x == args[1].length() - 1)
|
||||
BooksWithoutBorders.loadList.put(sender.getName(), booksWithoutBorders.listFiles(sender, true, true));
|
||||
}
|
||||
|
||||
ItemStack newBook;
|
||||
Player receivingPlayer = booksWithoutBorders.getServer().getPlayer(args[2]);
|
||||
if (receivingPlayer == null) {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "Player not found!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (receivingPlayer.getInventory().firstEmpty() == -1) {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "Receiving player must have space in their inventory to receive books!");
|
||||
return false;
|
||||
}
|
||||
//bwb give [book name] [player] [numCopies] [is signed]
|
||||
try {
|
||||
if (args.length == 5)
|
||||
newBook = booksWithoutBorders.loadBook(sender, cleanString(args[1]), args[4], "public", Integer.parseInt(args[3]));
|
||||
else if (args.length == 4) {
|
||||
if (args[3].equalsIgnoreCase("true") || args[3].equalsIgnoreCase("false"))
|
||||
newBook = booksWithoutBorders.loadBook(sender, cleanString(args[1]), args[3], "public");
|
||||
else
|
||||
newBook = booksWithoutBorders.loadBook(sender, cleanString(args[1]), "true", "public", Integer.parseInt(args[3]));
|
||||
} else
|
||||
newBook = booksWithoutBorders.loadBook(sender, cleanString(args[1]), "true", "public");
|
||||
|
||||
if (newBook != null) {
|
||||
receivingPlayer.getInventory().addItem(newBook);
|
||||
BooksWithoutBorders.sendSuccessMessage(sender, "Book sent!");
|
||||
BooksWithoutBorders.sendSuccessMessage(receivingPlayer, "Book received!");
|
||||
return true;
|
||||
} else {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "Book failed to load!");
|
||||
return false;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "Invalid number of book copies specified!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.bookswithoutborders.command;
|
||||
|
||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -71,7 +72,7 @@ public class CommandLoad implements CommandExecutor {
|
||||
BooksWithoutBorders.loadList.put(player.getName(), booksWithoutBorders.listFiles(player, loadPublic, true));
|
||||
} catch (NumberFormatException ignored) {}
|
||||
|
||||
String bookToLoad = booksWithoutBorders.cleanString(bookIdentifier);
|
||||
String bookToLoad = InputCleaningHelper.cleanString(bookIdentifier);
|
||||
try {
|
||||
//Give the new book if it cannot be loaded
|
||||
ItemStack newBook = booksWithoutBorders.loadBook(player, bookToLoad, isSigned, directory, Integer.parseInt(copies));
|
||||
|
@ -0,0 +1,30 @@
|
||||
package net.knarcraft.bookswithoutborders.command;
|
||||
|
||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* Command executor for the reload command
|
||||
*/
|
||||
public class CommandReload implements CommandExecutor {
|
||||
|
||||
private final BooksWithoutBorders booksWithoutBorders;
|
||||
|
||||
public CommandReload(BooksWithoutBorders booksWithoutBorders) {
|
||||
this.booksWithoutBorders = booksWithoutBorders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (booksWithoutBorders.loadConfig() && booksWithoutBorders.loadExistingPlayers()) {
|
||||
BooksWithoutBorders.sendSuccessMessage(sender, "BooksWithoutBorders configuration reloaded!");
|
||||
} else {
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "Reload Failed!");
|
||||
BooksWithoutBorders.sendErrorMessage(sender, "See console for details");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -3,22 +3,19 @@ package net.knarcraft.bookswithoutborders.command;
|
||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||
import net.knarcraft.bookswithoutborders.state.ItemSlot;
|
||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.BookMeta;
|
||||
|
||||
/**
|
||||
* Command executor for the unsign command
|
||||
*/
|
||||
public class CommandUnSign implements CommandExecutor {
|
||||
|
||||
private final BooksWithoutBorders booksWithoutBorders;
|
||||
|
||||
public CommandUnSign(BooksWithoutBorders booksWithoutBorders) {
|
||||
this.booksWithoutBorders = booksWithoutBorders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
@ -33,7 +30,24 @@ public class CommandUnSign implements CommandExecutor {
|
||||
|
||||
//Find which hand the player is using to hold the book. If holding one in each, throw an error
|
||||
ItemSlot holdingSlot = InventoryHelper.getHeldSlotBook(player, false, false, true, true);
|
||||
booksWithoutBorders.unSignHeldBook(player, holdingSlot == ItemSlot.MAIN_HAND);
|
||||
unSignHeldBook(player, holdingSlot == ItemSlot.MAIN_HAND);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-signs the player's currently held book
|
||||
*
|
||||
* @param player <p>The player holding the book</p>
|
||||
* @param mainHand <p>Whether the player is holding the book in its main hand or its off hand</p>
|
||||
*/
|
||||
public void unSignHeldBook(Player player, boolean mainHand) {
|
||||
//Get the old book
|
||||
BookMeta oldBook = InventoryHelper.getHeldBookMetadata(player, mainHand);
|
||||
|
||||
//UnSign the book
|
||||
ItemStack newBook = new ItemStack(Material.WRITABLE_BOOK);
|
||||
newBook.setItemMeta(oldBook);
|
||||
|
||||
InventoryHelper.replaceHeldItem(player, newBook, mainHand);
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tab completer for the save command
|
||||
*/
|
||||
public class GiveTabCompleter implements TabCompleter {
|
||||
|
||||
final BooksWithoutBorders booksWithoutBorders;
|
||||
|
@ -0,0 +1,55 @@
|
||||
package net.knarcraft.bookswithoutborders.utility;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class InputCleaningHelper {
|
||||
|
||||
/**
|
||||
* Removes null and empty items from a list
|
||||
*
|
||||
* @param list <p>The list to clean</p>
|
||||
* @return <p>A clean list containing all relevant values</p>
|
||||
*/
|
||||
public static List<String> cleanList(List<String> list) {
|
||||
List<String> resultList = new ArrayList<>(list);
|
||||
resultList.removeIf((item) -> item == null || item.trim().isEmpty());
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any special character from a filename
|
||||
*
|
||||
* @param fileName <p>The file name to clean</p>
|
||||
* @return <p>The cleaned file name</p>
|
||||
*/
|
||||
public static String cleanString(String fileName) {
|
||||
fileName = fileName.replace("/", "");
|
||||
fileName = fileName.replace("\\", "");
|
||||
fileName = fileName.replace("*", "");
|
||||
fileName = fileName.replace(":", "");
|
||||
fileName = fileName.replace("|", "");
|
||||
fileName = fileName.replace("<", "");
|
||||
fileName = fileName.replace(">", "");
|
||||
fileName = fileName.replace("?", "");
|
||||
fileName = fileName.replace("\"", "");
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes spaces to underscores or underscores to spaces, depending on context
|
||||
*
|
||||
* @param fileName <p>The file name to fix</p>
|
||||
* @param isLoading <p>Whether loading from a file as opposed to saving to a file</p>
|
||||
* @return <p>The fixed name</p>
|
||||
*/
|
||||
public static String fixName(String fileName, Boolean isLoading) {
|
||||
if (isLoading) {
|
||||
fileName = fileName.replace("_", " ");
|
||||
} else {
|
||||
fileName = fileName.replace(" ", "_");
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
}
|
@ -17,6 +17,10 @@ commands:
|
||||
description: Gives the held book to another player
|
||||
usage: /<command> <file name or number> <playername> [# of copies (num)] [signed (true/false)]
|
||||
permission: bookswithoutborders.give
|
||||
givepublic:
|
||||
description: Gives a public book to a player
|
||||
usage: /<command>
|
||||
permission: bookswithoutborders.givepublic
|
||||
decrypt:
|
||||
description: Decrypts the held book
|
||||
usage: /<command> <key>
|
||||
@ -77,7 +81,16 @@ commands:
|
||||
description: Loads a previously saved book from the public books folder
|
||||
usage: /<command> <file name or number> [copies] [is signed (true/false)]
|
||||
permission: bookswithoutborders.loadpublic
|
||||
reload:
|
||||
description: Reloads configuration from disk
|
||||
usage: /<command>
|
||||
permission: bookswithoutborders.admin
|
||||
permissions:
|
||||
bookswithoutborders.*:
|
||||
description: Grants all permissions
|
||||
default: op
|
||||
children:
|
||||
bookswithoutborders.admin: true
|
||||
bookswithoutborders.admin:
|
||||
description: Grants all permissions
|
||||
default: op
|
||||
|
Loading…
Reference in New Issue
Block a user