Adds an option for only allowing un-signing by the author

This commit is contained in:
Kristian Knarvik 2022-08-09 17:21:55 +02:00
parent 0d4d87373c
commit a7c284ade2
11 changed files with 111 additions and 60 deletions

View File

@ -2,8 +2,8 @@ package net.knarcraft.bookswithoutborders.command;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
import net.knarcraft.bookswithoutborders.utility.BookHelper;
import net.knarcraft.bookswithoutborders.utility.EconomyHelper; import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper; import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -41,12 +41,13 @@ public class CommandCopy implements TabExecutor {
} }
ItemStack heldBook = InventoryHelper.getHeldBook(player, true); ItemStack heldBook = InventoryHelper.getHeldBook(player, true);
//TODO: Rewrite this so the resulting book becomes a COPY, or COPY OF COPY
try { try {
int copies = Integer.parseInt(args[0]); int copies = Integer.parseInt(args[0]);
if (copies > 0) { if (copies > 0) {
if (BooksWithoutBordersConfig.getAuthorOnlyCopy() && !player.hasPermission("bookswithoutborders.bypassAuthorOnlyCopy")) { if (BooksWithoutBordersConfig.getAuthorOnlyCopy() && !player.hasPermission("bookswithoutborders.bypassAuthorOnlyCopy")) {
if (!isAuthor(player, (BookMeta) Objects.requireNonNull(heldBook.getItemMeta()))) { if (BookHelper.isNotAuthor(player, (BookMeta) Objects.requireNonNull(heldBook.getItemMeta()))) {
return false; return false;
} }
} }
@ -68,26 +69,9 @@ public class CommandCopy implements TabExecutor {
return false; 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>
*/
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;
}
@Override @Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
@NotNull String[] args) {
int argumentCount = args.length; int argumentCount = args.length;
if (argumentCount == 1) { if (argumentCount == 1) {
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getNumbers(1, 20), args[0]); return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getNumbers(1, 20), args[0]);

View File

@ -2,7 +2,7 @@ package net.knarcraft.bookswithoutborders.command;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
import net.knarcraft.bookswithoutborders.utility.BookFormatter; import net.knarcraft.bookswithoutborders.utility.BookHelper;
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper; import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -59,7 +59,7 @@ public class CommandDecrypt implements TabExecutor {
//Get the "encryption key" from the filename //Get the "encryption key" from the filename
String key = ""; String key = "";
for (String encryptedFile : encryptedFiles) { for (String encryptedFile : encryptedFiles) {
if (encryptedFile.contains(BookFormatter.getBookFile(bookMetadata, player))) { if (encryptedFile.contains(BookHelper.getBookFile(bookMetadata, player))) {
key = encryptedFile.substring(encryptedFile.indexOf("[") + 1, encryptedFile.indexOf("]")); key = encryptedFile.substring(encryptedFile.indexOf("[") + 1, encryptedFile.indexOf("]"));
break; break;
} }

View File

@ -3,7 +3,7 @@ package net.knarcraft.bookswithoutborders.command;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders; import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig; import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
import net.knarcraft.bookswithoutborders.state.ItemSlot; import net.knarcraft.bookswithoutborders.state.ItemSlot;
import net.knarcraft.bookswithoutborders.utility.BookFormatter; import net.knarcraft.bookswithoutborders.utility.BookHelper;
import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper; import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper;
import net.knarcraft.bookswithoutborders.utility.FileHelper; import net.knarcraft.bookswithoutborders.utility.FileHelper;
import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
@ -86,7 +86,7 @@ public class CommandSave implements TabExecutor {
} }
//Generate book filename //Generate book filename
String fileName = BookFormatter.getBookFile(book, player); String fileName = BookHelper.getBookFile(book, player);
//Make sure the used folders exist //Make sure the used folders exist
File file = new File(savePath); File file = new File(savePath);

View File

@ -1,7 +1,9 @@
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.state.ItemSlot; import net.knarcraft.bookswithoutborders.state.ItemSlot;
import net.knarcraft.bookswithoutborders.utility.BookHelper;
import net.knarcraft.bookswithoutborders.utility.InventoryHelper; import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -14,6 +16,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* Command executor for the unsign command * Command executor for the unsign command
@ -48,6 +51,13 @@ public class CommandUnSign implements TabExecutor {
//Get the old book //Get the old book
BookMeta oldBook = InventoryHelper.getHeldBookMetadata(player, mainHand); BookMeta oldBook = InventoryHelper.getHeldBookMetadata(player, mainHand);
//Only allow the owner to un-sign the book
if (BooksWithoutBordersConfig.getAuthorOnlyUnsign() && !player.hasPermission("bookswithoutborders.bypassAuthorOnlyUnsign")) {
if (BookHelper.isNotAuthor(player, Objects.requireNonNull(oldBook))) {
return;
}
}
//UnSign the book //UnSign the book
ItemStack newBook = new ItemStack(Material.WRITABLE_BOOK); ItemStack newBook = new ItemStack(Material.WRITABLE_BOOK);
newBook.setItemMeta(oldBook); newBook.setItemMeta(oldBook);

View File

@ -34,6 +34,7 @@ public class BooksWithoutBordersConfig {
private static Material bookPriceType = null; private static Material bookPriceType = null;
private static double bookPriceQuantity; private static double bookPriceQuantity;
private static boolean authorOnlyCopy; private static boolean authorOnlyCopy;
private static boolean authorOnlyUnsign;
private static boolean useYml; private static boolean useYml;
private static boolean adminDecrypt; private static boolean adminDecrypt;
private static boolean formatBooks; private static boolean formatBooks;
@ -106,6 +107,15 @@ public class BooksWithoutBordersConfig {
return authorOnlyCopy; return authorOnlyCopy;
} }
/**
* Gets whether only the author of a book should be able to unsign it
*
* @return <p>Whether only the book author can unsign it</p>
*/
public static boolean getAuthorOnlyUnsign() {
return authorOnlyUnsign;
}
/** /**
* Gets whether to use YML, not TXT, for saving books * Gets whether to use YML, not TXT, for saving books
* *
@ -257,10 +267,12 @@ public class BooksWithoutBordersConfig {
config.set(ConfigOption.PRICE_QUANTITY.getConfigNode(), bookPriceQuantity); config.set(ConfigOption.PRICE_QUANTITY.getConfigNode(), bookPriceQuantity);
config.set(ConfigOption.ADMIN_AUTO_DECRYPT.getConfigNode(), adminDecrypt); config.set(ConfigOption.ADMIN_AUTO_DECRYPT.getConfigNode(), adminDecrypt);
config.set(ConfigOption.AUTHOR_ONLY_COPY.getConfigNode(), authorOnlyCopy); config.set(ConfigOption.AUTHOR_ONLY_COPY.getConfigNode(), authorOnlyCopy);
config.set(ConfigOption.AUTHOR_ONLY_UNSIGN.getConfigNode(), authorOnlyUnsign);
//Handles old book and quill settings //Handles old book and quill settings
if (config.contains("Options.Require_book_and_quill_to_create_book")) { if (config.contains("Options.Require_book_and_quill_to_create_book")) {
sendSuccessMessage(consoleSender, "[BooksWithoutBorders] Found old config setting \"Require_book_and_quill_to_create_book\""); sendSuccessMessage(consoleSender, "[BooksWithoutBorders] Found old config setting " +
"\"Require_book_and_quill_to_create_book\"");
sendSuccessMessage(consoleSender, "Updating to \"Price_to_create_book\" settings"); sendSuccessMessage(consoleSender, "Updating to \"Price_to_create_book\" settings");
if (config.getBoolean("Options.Require_book_and_quill_to_create_book")) { if (config.getBoolean("Options.Require_book_and_quill_to_create_book")) {
@ -296,6 +308,8 @@ public class BooksWithoutBordersConfig {
(Boolean) ConfigOption.ADMIN_AUTO_DECRYPT.getDefaultValue()); (Boolean) ConfigOption.ADMIN_AUTO_DECRYPT.getDefaultValue());
authorOnlyCopy = config.getBoolean(ConfigOption.AUTHOR_ONLY_COPY.getConfigNode(), authorOnlyCopy = config.getBoolean(ConfigOption.AUTHOR_ONLY_COPY.getConfigNode(),
(Boolean) ConfigOption.AUTHOR_ONLY_COPY.getDefaultValue()); (Boolean) ConfigOption.AUTHOR_ONLY_COPY.getDefaultValue());
authorOnlyUnsign = config.getBoolean(ConfigOption.AUTHOR_ONLY_UNSIGN.getConfigNode(),
(Boolean) ConfigOption.AUTHOR_ONLY_UNSIGN.getDefaultValue());
firstBooks = config.getStringList(ConfigOption.BOOKS_FOR_NEW_PLAYERS.getConfigNode()); firstBooks = config.getStringList(ConfigOption.BOOKS_FOR_NEW_PLAYERS.getConfigNode());
welcomeMessage = config.getString(ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getConfigNode(), welcomeMessage = config.getString(ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getConfigNode(),
(String) ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getDefaultValue()); (String) ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getDefaultValue());

View File

@ -55,6 +55,11 @@ public enum ConfigOption {
*/ */
AUTHOR_ONLY_COPY("Options.Author_Only_Copy", false), AUTHOR_ONLY_COPY("Options.Author_Only_Copy", false),
/**
* Whether only the book author should be able to unsign a book
*/
AUTHOR_ONLY_UNSIGN("Author_Only_Unsign", false),
/** /**
* Whether to automatically format every signed book * Whether to automatically format every signed book
*/ */

View File

@ -1,8 +1,6 @@
package net.knarcraft.bookswithoutborders.utility; package net.knarcraft.bookswithoutborders.utility;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.BookMeta;
import java.util.ArrayList; import java.util.ArrayList;
@ -11,9 +9,6 @@ import java.util.Objects;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName;
/** /**
* A class for formatting text to fit books * A class for formatting text to fit books
*/ */
@ -22,32 +17,6 @@ public final class BookFormatter {
private BookFormatter() { private BookFormatter() {
} }
/**
* Gets the file name of the given book
*
* @param book <p>The book to get the file of</p>
* @param player <p>The player trying to do something with the book</p>
* @return <p>The book file</p>
*/
public static String getBookFile(BookMeta book, Player player) {
String titleAuthorSeparator = BooksWithoutBordersConfig.getTitleAuthorSeparator();
String bookName;
if (!book.hasTitle()) {
bookName = book.getTitle();
} else {
bookName = "Untitled";
}
String authorName;
if (book.hasAuthor()) {
authorName = book.getAuthor();
} else {
authorName = player.getName();
}
return fixName(cleanString(bookName + titleAuthorSeparator + authorName), false);
}
/** /**
* Formats the last page of a set of pages * Formats the last page of a set of pages
* *

View File

@ -0,0 +1,64 @@
package net.knarcraft.bookswithoutborders.utility;
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
import org.bukkit.entity.Player;
import org.bukkit.inventory.meta.BookMeta;
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName;
/**
* Helper class for getting abstract book information
*/
public final class BookHelper {
private BookHelper() {
}
/**
* Gets the file name of the given book
*
* @param book <p>The book to get the file of</p>
* @param player <p>The player trying to do something with the book</p>
* @return <p>The book file</p>
*/
public static String getBookFile(BookMeta book, Player player) {
String titleAuthorSeparator = BooksWithoutBordersConfig.getTitleAuthorSeparator();
String bookName;
if (!book.hasTitle()) {
bookName = book.getTitle();
} else {
bookName = "Untitled";
}
String authorName;
if (book.hasAuthor()) {
authorName = book.getAuthor();
} else {
authorName = player.getName();
}
return fixName(cleanString(bookName + titleAuthorSeparator + authorName), 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 not the book's author</p>
*/
public static boolean isNotAuthor(Player player, BookMeta book) {
String author = book.getAuthor();
String playerName = InputCleaningHelper.cleanString(player.getName());
if (author != null && playerName.equalsIgnoreCase(InputCleaningHelper.cleanString(author))) {
return false;
}
BooksWithoutBorders.sendErrorMessage(player, "You must be the author of this book to use this command!");
return true;
}
}

View File

@ -198,7 +198,7 @@ public final class EncryptionHelper {
return null; return null;
} }
String fileName = "[" + key + "]" + BookFormatter.getBookFile(bookMetadata, player); String fileName = "[" + key + "]" + BookHelper.getBookFile(bookMetadata, player);
fileName = fixName(cleanString(fileName), false); fileName = fixName(cleanString(fileName), false);
File file = new File(path + fileName + ".yml"); File file = new File(path + fileName + ".yml");
@ -261,7 +261,7 @@ public final class EncryptionHelper {
} }
} }
//Generate file name //Generate file name
String fileName = BookFormatter.getBookFile(bookMetadata, player); String fileName = BookHelper.getBookFile(bookMetadata, player);
List<String> newLore = new ArrayList<>(); List<String> newLore = new ArrayList<>();
newLore.add(ChatColor.GRAY + "[" + groupName + " encrypted]"); newLore.add(ChatColor.GRAY + "[" + groupName + " encrypted]");
@ -300,7 +300,7 @@ public final class EncryptionHelper {
private static Boolean saveEncryptedBook(Player player, BookMeta bookMetaData, String key) { private static Boolean saveEncryptedBook(Player player, BookMeta bookMetaData, String key) {
String path = getBookFolder() + "Encrypted" + getSlash(); String path = getBookFolder() + "Encrypted" + getSlash();
String fileName = "[" + key + "]" + BookFormatter.getBookFile(bookMetaData, player); String fileName = "[" + key + "]" + BookHelper.getBookFile(bookMetaData, player);
fileName = fixName(cleanString(fileName), false); fileName = fixName(cleanString(fileName), false);
//cancels saving if file is already encrypted //cancels saving if file is already encrypted

View File

@ -21,6 +21,8 @@ Options:
Admin_Auto_Decrypt: false Admin_Auto_Decrypt: false
# Whether to only allow the author of a book to create copies # Whether to only allow the author of a book to create copies
Author_Only_Copy: false Author_Only_Copy: false
# Whether to only allow the author of a book to unsign it
Author_Only_Unsign: false
# Whether to automatically format every book when it's signed # Whether to automatically format every book when it's signed
Format_Book_After_Signing: false Format_Book_After_Signing: false

View File

@ -111,6 +111,7 @@ permissions:
bookswithoutborders.give: true bookswithoutborders.give: true
bookswithoutborders.givepublic: true bookswithoutborders.givepublic: true
bookswithoutborders.bypassauthoronlycopy: true bookswithoutborders.bypassauthoronlycopy: true
bookswithoutborders.bypassauthoronlyunsign: true
bookswithoutborders.bypassbookprice: true bookswithoutborders.bypassbookprice: true
bookswithoutborders.setbookprice: true bookswithoutborders.setbookprice: true
bookswithoutborders.use: bookswithoutborders.use:
@ -163,6 +164,8 @@ permissions:
description: Allows player to set the lore of the currently held item description: Allows player to set the lore of the currently held item
bookswithoutborders.bypassauthoronlycopy: bookswithoutborders.bypassauthoronlycopy:
description: Allows player to ignore Author_Only_Copy config setting description: Allows player to ignore Author_Only_Copy config setting
bookswithoutborders.bypassauthoronlyunsign:
description: Allows player to ignore Author_Only_Unsign config setting
bookswithoutborders.bypassbookprice: bookswithoutborders.bypassbookprice:
description: Allows player to ignore Price_to_create_book config setting description: Allows player to ignore Price_to_create_book config setting
bookswithoutborders.setbookprice: bookswithoutborders.setbookprice: