Merge branch 'refs/heads/dev' into string-formatting
# Conflicts: # src/main/java/net/knarcraft/bookswithoutborders/BooksWithoutBorders.java
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
package net.knarcraft.bookswithoutborders;
|
package net.knarcraft.bookswithoutborders;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.command.CommandAddTitlePage;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandBooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.command.CommandBooksWithoutBorders;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandClear;
|
import net.knarcraft.bookswithoutborders.command.CommandClear;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandCopy;
|
import net.knarcraft.bookswithoutborders.command.CommandCopy;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandDecrypt;
|
import net.knarcraft.bookswithoutborders.command.CommandDecrypt;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandDelete;
|
import net.knarcraft.bookswithoutborders.command.CommandDelete;
|
||||||
|
import net.knarcraft.bookswithoutborders.command.CommandDeletePage;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandDeletePublic;
|
import net.knarcraft.bookswithoutborders.command.CommandDeletePublic;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandEncrypt;
|
import net.knarcraft.bookswithoutborders.command.CommandEncrypt;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandFormat;
|
import net.knarcraft.bookswithoutborders.command.CommandFormat;
|
||||||
@@ -256,6 +258,8 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
registerCommand(BwBCommand.SET_BOOK_GENERATION.toString(), new CommandSetGeneration());
|
registerCommand(BwBCommand.SET_BOOK_GENERATION.toString(), new CommandSetGeneration());
|
||||||
registerCommand(BwBCommand.CLEAR_BOOK.toString(), new CommandClear());
|
registerCommand(BwBCommand.CLEAR_BOOK.toString(), new CommandClear());
|
||||||
registerCommand(BwBCommand.SET_BOOKSHELF_DATA.toString(), new CommandSetBookshelfData());
|
registerCommand(BwBCommand.SET_BOOKSHELF_DATA.toString(), new CommandSetBookshelfData());
|
||||||
|
registerCommand("addBookTitlePage", new CommandAddTitlePage());
|
||||||
|
registerCommand("deleteBookPage", new CommandDeletePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,155 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookFormatter;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabExecutor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A command for adding a title page to a book
|
||||||
|
*/
|
||||||
|
public class CommandAddTitlePage implements TabExecutor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s,
|
||||||
|
@NotNull String[] arguments) {
|
||||||
|
if (!(sender instanceof Player player)) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ItemStack heldBook = InventoryHelper.getHeldBook(player);
|
||||||
|
if (heldBook == null) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "You must be holding a book to perform this command");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index;
|
||||||
|
if (arguments.length < 1) {
|
||||||
|
if (InventoryHelper.notHoldingOneWrittenBookCheck(player, "You must be holding a written book to " +
|
||||||
|
"add an author title page!", "You cannot add an author title page to two books at once!")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
index = Integer.parseInt(arguments[0]) - 1;
|
||||||
|
} catch (NumberFormatException exception) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "Invalid page index given!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String title = null;
|
||||||
|
|
||||||
|
if (arguments.length > 1) {
|
||||||
|
// Get all arguments as a space-separated string
|
||||||
|
StringBuilder builder = new StringBuilder(arguments[1]);
|
||||||
|
for (int i = 2; i < arguments.length; i++) {
|
||||||
|
builder.append(" ").append(arguments[i]);
|
||||||
|
}
|
||||||
|
title = builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
BookMeta bookMeta = (BookMeta) heldBook.getItemMeta();
|
||||||
|
if (bookMeta == null) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "Unable to get metadata for the held book!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
List<String> pages = new ArrayList<>(bookMeta.getPages());
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "The given page index is out of bounds!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (title == null && heldBook.getType() == Material.WRITTEN_BOOK) {
|
||||||
|
String loreSeparator = BooksWithoutBordersConfig.getLoreSeparator();
|
||||||
|
if (index > pages.size()) {
|
||||||
|
pages.add(formatTitle(bookMeta.getTitle() + loreSeparator + "By: " + bookMeta.getAuthor()));
|
||||||
|
} else {
|
||||||
|
pages.add(index, formatTitle(bookMeta.getTitle() + loreSeparator + "By: " + bookMeta.getAuthor()));
|
||||||
|
}
|
||||||
|
} else if (title == null) {
|
||||||
|
if (index > pages.size()) {
|
||||||
|
pages.add("");
|
||||||
|
} else {
|
||||||
|
pages.add(index, "");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (index > pages.size()) {
|
||||||
|
pages.add(formatTitle(title));
|
||||||
|
} else {
|
||||||
|
pages.add(index, formatTitle(title));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bookMeta.setPages(pages);
|
||||||
|
heldBook.setItemMeta(bookMeta);
|
||||||
|
BooksWithoutBorders.sendSuccessMessage(sender, "Title page added!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a book title
|
||||||
|
*
|
||||||
|
* @param input <p>The input to format</p>
|
||||||
|
* @return <p>The formatted input</p>
|
||||||
|
*/
|
||||||
|
private String formatTitle(@NotNull String input) {
|
||||||
|
String loreSeparator = BooksWithoutBordersConfig.getLoreSeparator();
|
||||||
|
if (input.contains(loreSeparator)) {
|
||||||
|
String[] parts = input.split(loreSeparator);
|
||||||
|
StringBuilder output = new StringBuilder("\n");
|
||||||
|
output.append(ChatColor.UNDERLINE).append(ChatColor.BOLD).append(BookFormatter.stripColor(parts[0])).append(ChatColor.RESET);
|
||||||
|
|
||||||
|
for (int i = 1; i < parts.length; i++) {
|
||||||
|
output.append("\n").append("\n").append(ChatColor.ITALIC).append(BookFormatter.stripColor(parts[i])).append(ChatColor.RESET);
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
} else {
|
||||||
|
return ChatColor.UNDERLINE + ChatColor.BOLD.toString() + input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||||
|
@NotNull String[] arguments) {
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
if (!(commandSender instanceof Player player)) {
|
||||||
|
return List.of("1", "2", "3", "4");
|
||||||
|
}
|
||||||
|
ItemStack heldBook = InventoryHelper.getHeldBook(player);
|
||||||
|
if (heldBook != null) {
|
||||||
|
BookMeta bookMeta = (BookMeta) heldBook.getItemMeta();
|
||||||
|
if (bookMeta != null) {
|
||||||
|
List<String> pages = new ArrayList<>();
|
||||||
|
pages.add("1");
|
||||||
|
for (int i = 1; i <= bookMeta.getPages().size(); i++) {
|
||||||
|
pages.add(String.valueOf(i + 1));
|
||||||
|
}
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (arguments.length == 2) {
|
||||||
|
return List.of("Title", "Chapter~Description");
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,91 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabExecutor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A command for deleting a single page from a book
|
||||||
|
*/
|
||||||
|
public class CommandDeletePage implements TabExecutor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] arguments) {
|
||||||
|
if (!(sender instanceof Player player)) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "You must supply a page index");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack heldBook = InventoryHelper.getHeldBook(player);
|
||||||
|
if (heldBook == null) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "You must be holding a book to perform this command");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index;
|
||||||
|
try {
|
||||||
|
index = Integer.parseInt(arguments[0]) - 1;
|
||||||
|
} catch (NumberFormatException exception) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "Invalid page index given!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BookMeta bookMeta = (BookMeta) heldBook.getItemMeta();
|
||||||
|
if (bookMeta == null) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "Unable to get metadata for the held book!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
List<String> pages = new ArrayList<>(bookMeta.getPages());
|
||||||
|
|
||||||
|
if (index < 0 || index >= pages.size()) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "The given page index is out of bounds!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pages.remove(index);
|
||||||
|
|
||||||
|
bookMeta.setPages(pages);
|
||||||
|
heldBook.setItemMeta(bookMeta);
|
||||||
|
BooksWithoutBorders.sendSuccessMessage(sender, "Page deleted!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||||
|
@NotNull String[] arguments) {
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
if (!(commandSender instanceof Player player)) {
|
||||||
|
return List.of("1", "2", "3", "4");
|
||||||
|
}
|
||||||
|
ItemStack heldBook = InventoryHelper.getHeldBook(player);
|
||||||
|
if (heldBook != null) {
|
||||||
|
BookMeta bookMeta = (BookMeta) heldBook.getItemMeta();
|
||||||
|
if (bookMeta != null) {
|
||||||
|
List<String> pages = new ArrayList<>();
|
||||||
|
for (int i = 0; i < bookMeta.getPages().size(); i++) {
|
||||||
|
pages.add(String.valueOf(i + 1));
|
||||||
|
}
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -18,6 +18,25 @@ public final class InventoryHelper {
|
|||||||
private InventoryHelper() {
|
private InventoryHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the book from a player's main hand
|
||||||
|
*
|
||||||
|
* @param player <p>The player holding the book</p>
|
||||||
|
* @return <p>The held book, or null if not holding one book in the main hand</p>
|
||||||
|
*/
|
||||||
|
public static ItemStack getHeldBook(@NotNull Player player) {
|
||||||
|
@NotNull ItemSlot heldSigned = InventoryHelper.getHeldSlotBook(player, true, true,
|
||||||
|
true, true);
|
||||||
|
@NotNull ItemSlot heldUnSigned = InventoryHelper.getHeldSlotBook(player, true, true,
|
||||||
|
true, false);
|
||||||
|
if (heldSigned == ItemSlot.MAIN_HAND || heldUnSigned == ItemSlot.MAIN_HAND) {
|
||||||
|
boolean holdingSigned = heldSigned == ItemSlot.MAIN_HAND;
|
||||||
|
return InventoryHelper.getHeldBook(player, holdingSigned);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the book the holder is playing
|
* Gets the book the holder is playing
|
||||||
*
|
*
|
||||||
|
@@ -101,6 +101,14 @@ commands:
|
|||||||
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
|
||||||
usage: /<command> <delete/name/lore> <text> [more text]
|
usage: /<command> <delete/name/lore> <text> [more text]
|
||||||
permission: bookswithoutborders.editbookshelf
|
permission: bookswithoutborders.editbookshelf
|
||||||
|
addBookTitlePage:
|
||||||
|
description: Adds a blank page, title page or chapter page depending on input and whether the book is signed
|
||||||
|
usage: /<command> [page index] [title~description]
|
||||||
|
permission: bookswithoutborders.addtitlepage
|
||||||
|
deleteBookPage:
|
||||||
|
description: Deletes one page from a book
|
||||||
|
usage: /<command> <page>
|
||||||
|
permission: bookswithoutborders.deletepage
|
||||||
permissions:
|
permissions:
|
||||||
bookswithoutborders.*:
|
bookswithoutborders.*:
|
||||||
description: Grants all permissions
|
description: Grants all permissions
|
||||||
@@ -147,6 +155,8 @@ permissions:
|
|||||||
bookswithoutborders.setlore: true
|
bookswithoutborders.setlore: true
|
||||||
bookswithoutborders.format: true
|
bookswithoutborders.format: true
|
||||||
bookswithoutborders.setgeneration: true
|
bookswithoutborders.setgeneration: true
|
||||||
|
bookswithoutborders.addtitlepage: true
|
||||||
|
bookswithoutborders.deletepage: true
|
||||||
bookswithoutborders.format:
|
bookswithoutborders.format:
|
||||||
description: Allows a player to format a book
|
description: Allows a player to format a book
|
||||||
bookswithoutborders.save:
|
bookswithoutborders.save:
|
||||||
@@ -201,3 +211,7 @@ permissions:
|
|||||||
description: Allows player to left-click a bookshelf to see the contents of the shelf
|
description: Allows player to left-click a bookshelf to see the contents of the shelf
|
||||||
bookswithoutborders.editbookshelf:
|
bookswithoutborders.editbookshelf:
|
||||||
description: Allows player to set name/lore for bookshelves, used for peeking
|
description: Allows player to set name/lore for bookshelves, used for peeking
|
||||||
|
bookswithoutborders.addtitlepage:
|
||||||
|
description: Allows player to add a blank title page to a book
|
||||||
|
bookswithoutborders.deletepage:
|
||||||
|
description: Allows player to delete a page from a book
|
Reference in New Issue
Block a user