Adds a new option to format books when signed
Also cleans up config stuff a bit and moves config-related tasks to its own class Moves book loading code to its own class Adds a default config file to make the config file have comments Adds missing command info about the formatBook command Adds information about required permissions to the command info
This commit is contained in:
parent
7acaa9fc81
commit
d423b1e109
@ -20,22 +20,18 @@ import net.knarcraft.bookswithoutborders.command.CommandSetBookPrice;
|
|||||||
import net.knarcraft.bookswithoutborders.command.CommandSetLore;
|
import net.knarcraft.bookswithoutborders.command.CommandSetLore;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandSetTitle;
|
import net.knarcraft.bookswithoutborders.command.CommandSetTitle;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandUnSign;
|
import net.knarcraft.bookswithoutborders.command.CommandUnSign;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings;
|
||||||
|
import net.knarcraft.bookswithoutborders.listener.BookEventListener;
|
||||||
import net.knarcraft.bookswithoutborders.listener.PlayerEventListener;
|
import net.knarcraft.bookswithoutborders.listener.PlayerEventListener;
|
||||||
import net.knarcraft.bookswithoutborders.listener.SignEventListener;
|
import net.knarcraft.bookswithoutborders.listener.SignEventListener;
|
||||||
import net.knarcraft.bookswithoutborders.state.BookDirectory;
|
|
||||||
import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper;
|
|
||||||
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
import org.bukkit.configuration.Configuration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemFactory;
|
import org.bukkit.inventory.ItemFactory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
@ -45,25 +41,13 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getErrorColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getErrorColor;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getSlash;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSuccessColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getSuccessColor;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
|
||||||
|
|
||||||
public class BooksWithoutBorders extends JavaPlugin {
|
public class BooksWithoutBorders extends JavaPlugin {
|
||||||
|
|
||||||
private static int bookDuplicateLimit;
|
|
||||||
private static String titleAuthorSeparator;
|
|
||||||
private static String loreSeparator;
|
|
||||||
private static List<String> firstBooks;
|
|
||||||
private static String welcomeMessage;
|
|
||||||
private static Material bookPriceType = null;
|
|
||||||
private static double bookPriceQuantity;
|
|
||||||
private static boolean authorOnlyCopy;
|
|
||||||
private static boolean useYml;
|
|
||||||
private static boolean adminDecrypt;
|
|
||||||
|
|
||||||
private static ItemFactory itemFactory;
|
private static ItemFactory itemFactory;
|
||||||
private static Map<String, List<String>> playerBooksList;
|
private static Map<String, List<String>> playerBooksList;
|
||||||
private static List<String> publicBooksList;
|
private static List<String> publicBooksList;
|
||||||
@ -116,11 +100,15 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
FileConfiguration config = this.getConfig();
|
||||||
|
config.options().copyDefaults(true);
|
||||||
|
this.saveDefaultConfig();
|
||||||
|
|
||||||
booksWithoutBorders = this;
|
booksWithoutBorders = this;
|
||||||
consoleSender = this.getServer().getConsoleSender();
|
consoleSender = this.getServer().getConsoleSender();
|
||||||
playerBooksList = new HashMap<>();
|
playerBooksList = new HashMap<>();
|
||||||
firstBooks = new ArrayList<>();
|
|
||||||
BooksWithoutBordersSettings.initialize(this);
|
BooksWithoutBordersSettings.initialize(this);
|
||||||
|
BooksWithoutBordersConfig.loadConfig();
|
||||||
publicBooksList = FileHelper.listFiles(consoleSender, true);
|
publicBooksList = FileHelper.listFiles(consoleSender, true);
|
||||||
|
|
||||||
PluginManager pluginManager = this.getServer().getPluginManager();
|
PluginManager pluginManager = this.getServer().getPluginManager();
|
||||||
@ -128,6 +116,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
if (getSlash() != null && initialize()) {
|
if (getSlash() != null && initialize()) {
|
||||||
pluginManager.registerEvents(new PlayerEventListener(), this);
|
pluginManager.registerEvents(new PlayerEventListener(), this);
|
||||||
pluginManager.registerEvents(new SignEventListener(), this);
|
pluginManager.registerEvents(new SignEventListener(), this);
|
||||||
|
pluginManager.registerEvents(new BookEventListener(), this);
|
||||||
} else {
|
} else {
|
||||||
this.getPluginLoader().disablePlugin(this);
|
this.getPluginLoader().disablePlugin(this);
|
||||||
}
|
}
|
||||||
@ -135,120 +124,6 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
registerCommands();
|
registerCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets whether only the author of a book should be able to copy it
|
|
||||||
*
|
|
||||||
* @return <p>Whether only the book author can copy it</p>
|
|
||||||
*/
|
|
||||||
public static boolean getAuthorOnlyCopy() {
|
|
||||||
return authorOnlyCopy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets whether to use YML, not TXT, for saving books
|
|
||||||
*
|
|
||||||
* @return <p>Whether to use YML for saving books</p>
|
|
||||||
*/
|
|
||||||
public static boolean getUseYml() {
|
|
||||||
return useYml;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets whether admins should be able to decrypt books without a password, and decrypt all group encrypted books
|
|
||||||
*
|
|
||||||
* @return <p>Whether admins can bypass the encryption password</p>
|
|
||||||
*/
|
|
||||||
public static boolean getAdminDecrypt() {
|
|
||||||
return adminDecrypt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the quantity of items/currency necessary for copying books
|
|
||||||
*
|
|
||||||
* @param newQuantity <p>The new quantity necessary for payment</p>
|
|
||||||
*/
|
|
||||||
public static void setBookPriceQuantity(double newQuantity) {
|
|
||||||
bookPriceQuantity = newQuantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the quantity of items/currency necessary for copying books
|
|
||||||
*
|
|
||||||
* @return <p>The quantity necessary for payment</p>
|
|
||||||
*/
|
|
||||||
public static double getBookPriceQuantity() {
|
|
||||||
return bookPriceQuantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the item type used for book pricing
|
|
||||||
*
|
|
||||||
* <p>This item is the one a player has to pay for copying books. AIR is used to denote economy. null is used if
|
|
||||||
* payment is disabled. Otherwise, any item can be used.</p>
|
|
||||||
*
|
|
||||||
* @param newType <p>The new item type to use for book pricing</p>
|
|
||||||
*/
|
|
||||||
public static void setBookPriceType(Material newType) {
|
|
||||||
bookPriceType = newType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the item type used for book pricing
|
|
||||||
*
|
|
||||||
* <p>This item is the one a player has to pay for copying books. AIR is used to denote economy. null is used if
|
|
||||||
* payment is disabled. Otherwise, any item can be used.</p>
|
|
||||||
*
|
|
||||||
* @return <p>The item type used for book pricing</p>
|
|
||||||
*/
|
|
||||||
public static Material getBookPriceType() {
|
|
||||||
return bookPriceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the welcome message to show to new players
|
|
||||||
*
|
|
||||||
* @return <p>The welcome message to show new players</p>
|
|
||||||
*/
|
|
||||||
public static String getWelcomeMessage() {
|
|
||||||
return welcomeMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the limit of duplicates for each book
|
|
||||||
*
|
|
||||||
* @return <p>The book duplicate limit</p>
|
|
||||||
*/
|
|
||||||
public static int getBookDuplicateLimit() {
|
|
||||||
return bookDuplicateLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the separator used to split book title from book author
|
|
||||||
*
|
|
||||||
* @return <p>The separator between title and author</p>
|
|
||||||
*/
|
|
||||||
public static String getTitleAuthorSeparator() {
|
|
||||||
return titleAuthorSeparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the separator used to denote a newline in a lore string
|
|
||||||
*
|
|
||||||
* @return <p>The separator used to denote lore newline</p>
|
|
||||||
*/
|
|
||||||
public static String getLoreSeparator() {
|
|
||||||
return loreSeparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a copy of the list of books to give new players
|
|
||||||
*
|
|
||||||
* @return <p>The books to give new players</p>
|
|
||||||
*/
|
|
||||||
public static List<String> getFirstBooks() {
|
|
||||||
return new ArrayList<>(firstBooks);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an instance of this plugin
|
* Gets an instance of this plugin
|
||||||
*
|
*
|
||||||
@ -316,16 +191,25 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Load config
|
//Load config
|
||||||
if (!loadConfig()) {
|
if (!BooksWithoutBordersConfig.loadConfig()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Save config with loaded values to fix invalid config values
|
//Save config with loaded values to fix invalid config values
|
||||||
saveConfigValues();
|
BooksWithoutBordersConfig.saveConfigValues();
|
||||||
|
|
||||||
return testFileSaving();
|
return testFileSaving();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the server's item factory
|
||||||
|
*
|
||||||
|
* @return <p>The server's item factory</p>
|
||||||
|
*/
|
||||||
|
public static ItemFactory getItemFactory() {
|
||||||
|
return itemFactory;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes sure necessary folders exist
|
* Makes sure necessary folders exist
|
||||||
*
|
*
|
||||||
@ -359,213 +243,6 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves the config
|
|
||||||
*/
|
|
||||||
public void saveConfigValues() {
|
|
||||||
Configuration config = this.getConfig();
|
|
||||||
config.set("Options.Save_Books_in_Yaml_Format", useYml);
|
|
||||||
config.set("Options.Max_Number_of_Duplicates", bookDuplicateLimit);
|
|
||||||
config.set("Options.Title-Author_Separator", titleAuthorSeparator);
|
|
||||||
config.set("Options.Lore_line_separator", loreSeparator);
|
|
||||||
config.set("Options.Books_for_new_players", firstBooks);
|
|
||||||
config.set("Options.Message_for_new_players", welcomeMessage);
|
|
||||||
if (bookPriceType != null) {
|
|
||||||
if (bookPriceType != Material.AIR) {
|
|
||||||
config.set("Options.Price_to_create_book.Item_type", bookPriceType.toString());
|
|
||||||
} else {
|
|
||||||
config.set("Options.Price_to_create_book.Item_type", "Economy");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
config.set("Options.Price_to_create_book.Item_type", "Item type name");
|
|
||||||
}
|
|
||||||
config.set("Options.Price_to_create_book.Required_quantity", bookPriceQuantity);
|
|
||||||
config.set("Options.Admin_Auto_Decrypt", adminDecrypt);
|
|
||||||
config.set("Options.Author_Only_Copy", authorOnlyCopy);
|
|
||||||
|
|
||||||
//Handles old book and quill settings
|
|
||||||
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, "Updating to \"Price_to_create_book\" settings");
|
|
||||||
|
|
||||||
if (config.getBoolean("Options.Require_book_and_quill_to_create_book")) {
|
|
||||||
bookPriceType = Material.WRITABLE_BOOK;
|
|
||||||
bookPriceQuantity = 1;
|
|
||||||
config.set("Options.Price_to_create_book.Item_type", bookPriceType.toString());
|
|
||||||
config.set("Options.Price_to_create_book.Required_quantity", bookPriceQuantity);
|
|
||||||
}
|
|
||||||
|
|
||||||
config.set("Options.Require_book_and_quill_to_create_book", null);
|
|
||||||
}
|
|
||||||
this.saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the config
|
|
||||||
*
|
|
||||||
* @return <p>True if the config was loaded successfully</p>
|
|
||||||
*/
|
|
||||||
public boolean loadConfig() {
|
|
||||||
this.reloadConfig();
|
|
||||||
Configuration config = this.getConfig();
|
|
||||||
try {
|
|
||||||
useYml = config.getBoolean("Options.Save_Books_in_Yaml_Format", true);
|
|
||||||
bookDuplicateLimit = config.getInt("Options.Max_Number_of_Duplicates", 5);
|
|
||||||
titleAuthorSeparator = config.getString("Options.Title-Author_Separator", ",");
|
|
||||||
loreSeparator = config.getString("Options.Lore_line_separator", "~");
|
|
||||||
adminDecrypt = config.getBoolean("Options.Admin_Auto_Decrypt", false);
|
|
||||||
authorOnlyCopy = config.getBoolean("Options.Author_Only_Copy", false);
|
|
||||||
|
|
||||||
//Set books to give new players
|
|
||||||
firstBooks = config.getStringList("Options.Books_for_new_players");
|
|
||||||
if (config.contains("Options.Book_for_new_players")) {
|
|
||||||
firstBooks.add(config.getString("Options.Book_for_new_players"));
|
|
||||||
}
|
|
||||||
|
|
||||||
welcomeMessage = config.getString("Options.Message_for_new_players", " ");
|
|
||||||
|
|
||||||
//Convert string into material
|
|
||||||
String paymentMaterial = config.getString("Options.Price_to_create_book.Item_type", " ");
|
|
||||||
if (paymentMaterial.equalsIgnoreCase("Economy")) {
|
|
||||||
if (EconomyHelper.setupEconomy()) {
|
|
||||||
bookPriceType = Material.AIR;
|
|
||||||
} else {
|
|
||||||
sendErrorMessage(consoleSender, "BooksWithoutBorders failed to hook into Vault! Book price not set!");
|
|
||||||
bookPriceType = null;
|
|
||||||
}
|
|
||||||
} else if (!paymentMaterial.equalsIgnoreCase(" ")) {
|
|
||||||
Material material = Material.matchMaterial(paymentMaterial);
|
|
||||||
if (material != null) {
|
|
||||||
bookPriceType = material;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bookPriceQuantity = config.getDouble("Options.Price_to_create_book.Required_quantity", 0);
|
|
||||||
|
|
||||||
//Make sure titleAuthorSeparator is a valid value
|
|
||||||
titleAuthorSeparator = cleanString(titleAuthorSeparator);
|
|
||||||
if (titleAuthorSeparator.length() != 1) {
|
|
||||||
sendErrorMessage(consoleSender, "Title-Author_Separator is set to an invalid value!");
|
|
||||||
sendErrorMessage(consoleSender, "Reverting to default value of \",\"");
|
|
||||||
titleAuthorSeparator = ",";
|
|
||||||
config.set("Options.Title-Author_Separator", titleAuthorSeparator);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
sendErrorMessage(consoleSender, "Warning! Config.yml failed to load!");
|
|
||||||
sendErrorMessage(consoleSender, "Try Looking for settings that are missing values!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the given book
|
|
||||||
*
|
|
||||||
* @param sender <p>The command sender trying to load the book</p>
|
|
||||||
* @param fileName <p>The index or file name of the book to load</p>
|
|
||||||
* @param isSigned <p>Whether to load the book as signed, and not unsigned</p>
|
|
||||||
* @param directory <p>The directory to save the book in</p>
|
|
||||||
* @return <p>The loaded book</p>
|
|
||||||
*/
|
|
||||||
public ItemStack loadBook(CommandSender sender, String fileName, String isSigned, String directory) {
|
|
||||||
return loadBook(sender, fileName, isSigned, directory, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the given book
|
|
||||||
*
|
|
||||||
* @param sender <p>The command sender trying to load the book</p>
|
|
||||||
* @param fileName <p>The index or file name of the book to load</p>
|
|
||||||
* @param isSigned <p>Whether to load the book as signed, and not unsigned</p>
|
|
||||||
* @param directory <p>The directory to save the book in</p>
|
|
||||||
* @param numCopies <p>The number of copies to load</p>
|
|
||||||
* @return <p>The loaded book</p>
|
|
||||||
*/
|
|
||||||
public ItemStack loadBook(CommandSender sender, String fileName, String isSigned, String directory, int numCopies) {
|
|
||||||
BookDirectory bookDirectory = BookDirectory.getFromString(directory);
|
|
||||||
|
|
||||||
//Find the filename if a book index is given
|
|
||||||
try {
|
|
||||||
int bookIndex = Integer.parseInt(fileName);
|
|
||||||
List<String> availableFiles = getAvailableBooks(sender, bookDirectory == BookDirectory.PUBLIC);
|
|
||||||
if (bookIndex <= availableFiles.size()) {
|
|
||||||
fileName = availableFiles.get(Integer.parseInt(fileName) - 1);
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get the full path of the book to load
|
|
||||||
File file = getFullPath(sender, fileName, bookDirectory, directory);
|
|
||||||
if (file == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Make sure the player can pay for the book
|
|
||||||
if (booksHavePrice() && !sender.hasPermission("bookswithoutborders.bypassBookPrice") &&
|
|
||||||
(bookDirectory == BookDirectory.PUBLIC || bookDirectory == BookDirectory.PLAYER) &&
|
|
||||||
EconomyHelper.cannotPayForBookPrinting((Player) sender, numCopies)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Generate a new empty book
|
|
||||||
ItemStack book;
|
|
||||||
BookMeta bookMetadata = (BookMeta) itemFactory.getItemMeta(Material.WRITTEN_BOOK);
|
|
||||||
if (isSigned.equalsIgnoreCase("true")) {
|
|
||||||
book = new ItemStack(Material.WRITTEN_BOOK);
|
|
||||||
} else {
|
|
||||||
book = new ItemStack(Material.WRITABLE_BOOK);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Load the book from the given file
|
|
||||||
BookToFromTextHelper.bookFromFile(file, bookMetadata);
|
|
||||||
if (bookMetadata == null) {
|
|
||||||
sendErrorMessage(sender, "File was blank!!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Remove "encrypted" from the book lore
|
|
||||||
if (bookDirectory == BookDirectory.ENCRYPTED && bookMetadata.hasLore()) {
|
|
||||||
List<String> oldLore = bookMetadata.getLore();
|
|
||||||
if (oldLore != null) {
|
|
||||||
List<String> newLore = new ArrayList<>(oldLore);
|
|
||||||
newLore.remove(0);
|
|
||||||
bookMetadata.setLore(newLore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set the metadata and amount to the new book
|
|
||||||
book.setItemMeta(bookMetadata);
|
|
||||||
book.setAmount(numCopies);
|
|
||||||
|
|
||||||
return book;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a File pointing to the wanted book
|
|
||||||
*
|
|
||||||
* @param sender <p>The sender to send errors to</p>
|
|
||||||
* @param fileName <p>The name of the book file</p>
|
|
||||||
* @param bookDirectory <p>The book directory the file resides in</p>
|
|
||||||
* @param directory <p>The relative directory given</p>
|
|
||||||
* @return <p>A file or null if it does not exist</p>
|
|
||||||
*/
|
|
||||||
private File getFullPath(CommandSender sender, String fileName, BookDirectory bookDirectory, String directory) {
|
|
||||||
File file = null;
|
|
||||||
if (bookDirectory == BookDirectory.PUBLIC) {
|
|
||||||
file = FileHelper.getBookFile(getBookFolder() + fileName);
|
|
||||||
} else if (bookDirectory == BookDirectory.PLAYER) {
|
|
||||||
file = FileHelper.getBookFile(getBookFolder() + cleanString(sender.getName()) + getSlash() + fileName);
|
|
||||||
} else if (bookDirectory == BookDirectory.ENCRYPTED) {
|
|
||||||
file = FileHelper.getBookFile(getBookFolder() + "Encrypted" + getSlash() + directory + getSlash() + fileName);
|
|
||||||
}
|
|
||||||
if (file == null || !file.isFile()) {
|
|
||||||
sendErrorMessage(sender, "Incorrect file name!");
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a success message to a command sender (player or a console)
|
* Sends a success message to a command sender (player or a console)
|
||||||
*
|
*
|
||||||
@ -586,13 +263,4 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
sender.sendMessage(getErrorColor() + message);
|
sender.sendMessage(getErrorColor() + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether books have a price for printing them
|
|
||||||
*
|
|
||||||
* @return <p>True if players need to pay for printing books</p>
|
|
||||||
*/
|
|
||||||
public boolean booksHavePrice() {
|
|
||||||
return (bookPriceType != null && bookPriceQuantity > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
@ -14,20 +15,19 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.sendErrorMessage;
|
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.sendErrorMessage;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getCommandColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getCommandColor;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSuccessColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getSuccessColor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command executor for the books without borders (bwb) command
|
* Command executor for the books without borders (bwb) command
|
||||||
*/
|
*/
|
||||||
public class CommandBooksWithoutBorders implements TabExecutor {
|
public class CommandBooksWithoutBorders implements TabExecutor {
|
||||||
|
|
||||||
private final BooksWithoutBorders booksWithoutBorders = BooksWithoutBorders.getInstance();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
sender.sendMessage(getCommandColor() + "[] denote optional parameters");
|
sender.sendMessage(getCommandColor() + "[] denote optional parameters");
|
||||||
sender.sendMessage(getCommandColor() + "<> denote required parameters");
|
sender.sendMessage(getCommandColor() + "<> denote required parameters");
|
||||||
|
sender.sendMessage(getCommandColor() + "{} denote required permission");
|
||||||
sender.sendMessage(getCommandColor() + "In some cases, commands with required parameters can be called with no parameters");
|
sender.sendMessage(getCommandColor() + "In some cases, commands with required parameters can be called with no parameters");
|
||||||
if (sender instanceof Player) {
|
if (sender instanceof Player) {
|
||||||
showPlayerCommands(sender);
|
showPlayerCommands(sender);
|
||||||
@ -44,9 +44,9 @@ public class CommandBooksWithoutBorders implements TabExecutor {
|
|||||||
*/
|
*/
|
||||||
private void showConsoleCommands(CommandSender sender) {
|
private void showConsoleCommands(CommandSender sender) {
|
||||||
sender.sendMessage(getCommandColor() + "Commands:");
|
sender.sendMessage(getCommandColor() + "Commands:");
|
||||||
showCommandInfo("reload", sender);
|
|
||||||
showCommandInfo("givePublicBook", sender);
|
|
||||||
showCommandInfo("deletePublicBook", sender);
|
showCommandInfo("deletePublicBook", sender);
|
||||||
|
showCommandInfo("givePublicBook", sender);
|
||||||
|
showCommandInfo("reload", sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,9 +56,9 @@ public class CommandBooksWithoutBorders implements TabExecutor {
|
|||||||
*/
|
*/
|
||||||
private void showPlayerCommands(CommandSender sender) {
|
private void showPlayerCommands(CommandSender sender) {
|
||||||
//Lists all commands
|
//Lists all commands
|
||||||
Material bookPriceType = BooksWithoutBorders.getBookPriceType();
|
Material bookPriceType = BooksWithoutBordersConfig.getBookPriceType();
|
||||||
double bookPriceQuantity = BooksWithoutBorders.getBookPriceQuantity();
|
double bookPriceQuantity = BooksWithoutBordersConfig.getBookPriceQuantity();
|
||||||
if (booksWithoutBorders.booksHavePrice()) {
|
if (BooksWithoutBordersConfig.booksHavePrice()) {
|
||||||
if (bookPriceType != Material.AIR) {
|
if (bookPriceType != Material.AIR) {
|
||||||
sendErrorMessage(sender, "[" + (int) bookPriceQuantity + " " + bookPriceType.toString() +
|
sendErrorMessage(sender, "[" + (int) bookPriceQuantity + " " + bookPriceType.toString() +
|
||||||
"(s) are required to create a book]");
|
"(s) are required to create a book]");
|
||||||
@ -69,24 +69,25 @@ public class CommandBooksWithoutBorders implements TabExecutor {
|
|||||||
}
|
}
|
||||||
sender.sendMessage(getCommandColor() + "Commands:");
|
sender.sendMessage(getCommandColor() + "Commands:");
|
||||||
|
|
||||||
showCommandInfo("loadBook", sender);
|
showCommandInfo("copyBook", sender);
|
||||||
showCommandInfo("loadPublicBook", sender);
|
showCommandInfo("decryptBook", sender);
|
||||||
showCommandInfo("saveBook", sender);
|
|
||||||
showCommandInfo("savePublicBook", sender);
|
|
||||||
showCommandInfo("giveBook", sender);
|
|
||||||
showCommandInfo("givePublicBook", sender);
|
|
||||||
showCommandInfo("deleteBook", sender);
|
showCommandInfo("deleteBook", sender);
|
||||||
showCommandInfo("deletePublicBook", sender);
|
showCommandInfo("deletePublicBook", sender);
|
||||||
showCommandInfo("unsignBook", sender);
|
|
||||||
showCommandInfo("copyBook", sender);
|
|
||||||
showCommandInfo("encryptBook", sender);
|
showCommandInfo("encryptBook", sender);
|
||||||
|
showCommandInfo("formatBook", sender);
|
||||||
|
showCommandInfo("giveBook", sender);
|
||||||
|
showCommandInfo("givePublicBook", sender);
|
||||||
showCommandInfo("groupEncryptBook", sender);
|
showCommandInfo("groupEncryptBook", sender);
|
||||||
showCommandInfo("decryptBook", sender);
|
showCommandInfo("loadBook", sender);
|
||||||
showCommandInfo("setTitle", sender);
|
showCommandInfo("loadPublicBook", sender);
|
||||||
showCommandInfo("setAuthor", sender);
|
|
||||||
showCommandInfo("setLore", sender);
|
|
||||||
showCommandInfo("setBookPrice", sender);
|
|
||||||
showCommandInfo("reload", sender);
|
showCommandInfo("reload", sender);
|
||||||
|
showCommandInfo("saveBook", sender);
|
||||||
|
showCommandInfo("savePublicBook", sender);
|
||||||
|
showCommandInfo("setAuthor", sender);
|
||||||
|
showCommandInfo("setBookPrice", sender);
|
||||||
|
showCommandInfo("setLore", sender);
|
||||||
|
showCommandInfo("setTitle", sender);
|
||||||
|
showCommandInfo("unsignBook", sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,9 +101,12 @@ public class CommandBooksWithoutBorders implements TabExecutor {
|
|||||||
if (pluginCommand != null) {
|
if (pluginCommand != null) {
|
||||||
String permission = pluginCommand.getPermission();
|
String permission = pluginCommand.getPermission();
|
||||||
if (permission == null || sender.hasPermission(permission)) {
|
if (permission == null || sender.hasPermission(permission)) {
|
||||||
sender.sendMessage("\n" + getCommandColor() +
|
String commandInfo = "\n" + getCommandColor() + pluginCommand.getUsage().replace("<command>",
|
||||||
pluginCommand.getUsage().replace("<command>", pluginCommand.getName()) + ": " +
|
pluginCommand.getName()) + ": " + getSuccessColor() + pluginCommand.getDescription();
|
||||||
getSuccessColor() + pluginCommand.getDescription());
|
if (sender.hasPermission("bookswithoutborders.admin")) {
|
||||||
|
commandInfo += getCommandColor() + " {" + permission + "}";
|
||||||
|
}
|
||||||
|
sender.sendMessage(commandInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
@ -22,8 +23,6 @@ import java.util.Objects;
|
|||||||
*/
|
*/
|
||||||
public class CommandCopy implements TabExecutor {
|
public class CommandCopy implements TabExecutor {
|
||||||
|
|
||||||
private final BooksWithoutBorders booksWithoutBorders = BooksWithoutBorders.getInstance();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
if (!(sender instanceof Player player)) {
|
if (!(sender instanceof Player player)) {
|
||||||
@ -46,13 +45,13 @@ public class CommandCopy implements TabExecutor {
|
|||||||
try {
|
try {
|
||||||
int copies = Integer.parseInt(args[0]);
|
int copies = Integer.parseInt(args[0]);
|
||||||
if (copies > 0) {
|
if (copies > 0) {
|
||||||
if (BooksWithoutBorders.getAuthorOnlyCopy() && !player.hasPermission("bookswithoutborders.bypassAuthorOnlyCopy")) {
|
if (BooksWithoutBordersConfig.getAuthorOnlyCopy() && !player.hasPermission("bookswithoutborders.bypassAuthorOnlyCopy")) {
|
||||||
if (!isAuthor(player, (BookMeta) Objects.requireNonNull(heldBook.getItemMeta()))) {
|
if (!isAuthor(player, (BookMeta) Objects.requireNonNull(heldBook.getItemMeta()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (booksWithoutBorders.booksHavePrice() &&
|
if (BooksWithoutBordersConfig.booksHavePrice() &&
|
||||||
!player.hasPermission("bookswithoutborders.bypassBookPrice") &&
|
!player.hasPermission("bookswithoutborders.bypassBookPrice") &&
|
||||||
EconomyHelper.cannotPayForBookPrinting(player, copies)) {
|
EconomyHelper.cannotPayForBookPrinting(player, copies)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
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;
|
||||||
@ -15,8 +16,8 @@ import java.io.File;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getSlash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command executor for the decrypt command
|
* Command executor for the decrypt command
|
||||||
@ -44,11 +45,11 @@ public class CommandDecrypt implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Warning: admin decrypt only allows decrypting files created by the same player. Not sure if intended
|
//Warning: admin decrypt only allows decrypting files created by the same player. Not sure if intended
|
||||||
if (args.length == 0 && BooksWithoutBorders.getAdminDecrypt() && player.hasPermission("bookswithoutborders.admin")) {
|
if (args.length == 0 && BooksWithoutBordersConfig.getAdminDecrypt() && player.hasPermission("bookswithoutborders.admin")) {
|
||||||
String path = getBookFolder() + "Encrypted" + getSlash();
|
String path = getBookFolder() + "Encrypted" + getSlash();
|
||||||
String fileName;
|
String fileName;
|
||||||
if (bookMetadata.hasTitle()) {
|
if (bookMetadata.hasTitle()) {
|
||||||
fileName = bookMetadata.getTitle() + BooksWithoutBorders.getTitleAuthorSeparator() + bookMetadata.getAuthor();
|
fileName = bookMetadata.getTitle() + BooksWithoutBordersConfig.getTitleAuthorSeparator() + bookMetadata.getAuthor();
|
||||||
} else {
|
} else {
|
||||||
fileName = "Untitled," + player.getName();
|
fileName = "Untitled," + player.getName();
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ import java.io.File;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getSlash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command executor for the delete command
|
* Command executor for the delete command
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookFormatter;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
@ -13,9 +13,6 @@ 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;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A command for converting color codes to color formatting
|
* A command for converting color codes to color formatting
|
||||||
@ -35,36 +32,13 @@ public class CommandFormat implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ItemStack heldBook = InventoryHelper.getHeldBook(player, true);
|
ItemStack heldBook = InventoryHelper.getHeldBook(player, true);
|
||||||
BookMeta bookMeta = (BookMeta) heldBook.getItemMeta();
|
heldBook.setItemMeta(BookFormatter.formatPages((BookMeta) heldBook.getItemMeta()));
|
||||||
|
|
||||||
List<String> formattedPages = new ArrayList<>(Objects.requireNonNull(bookMeta).getPageCount());
|
|
||||||
for (String page : bookMeta.getPages()) {
|
|
||||||
formattedPages.add(translateAllColorCodes(page));
|
|
||||||
}
|
|
||||||
bookMeta.setPages(formattedPages);
|
|
||||||
heldBook.setItemMeta(bookMeta);
|
|
||||||
|
|
||||||
BooksWithoutBorders.sendSuccessMessage(sender, "Book formatted!");
|
BooksWithoutBorders.sendSuccessMessage(sender, "Book formatted!");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates all found color codes to formatting in a string
|
|
||||||
*
|
|
||||||
* @param message <p>The string to search for color codes</p>
|
|
||||||
* @return <p>The message with color codes translated</p>
|
|
||||||
*/
|
|
||||||
public static String translateAllColorCodes(String message) {
|
|
||||||
message = ChatColor.translateAlternateColorCodes('&', message);
|
|
||||||
Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})");
|
|
||||||
Matcher matcher = pattern.matcher(message);
|
|
||||||
while (matcher.find()) {
|
|
||||||
message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group()));
|
|
||||||
}
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookLoader;
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
||||||
@ -88,7 +89,7 @@ public class CommandGive implements TabExecutor {
|
|||||||
|
|
||||||
String bookToLoad = InputCleaningHelper.cleanString(bookIdentifier);
|
String bookToLoad = InputCleaningHelper.cleanString(bookIdentifier);
|
||||||
try {
|
try {
|
||||||
ItemStack newBook = booksWithoutBorders.loadBook(sender, bookToLoad, isSigned, folder, Integer.parseInt(copies));
|
ItemStack newBook = BookLoader.loadBook(sender, bookToLoad, isSigned, folder, Integer.parseInt(copies));
|
||||||
if (newBook != null) {
|
if (newBook != null) {
|
||||||
receivingPlayer.getInventory().addItem(newBook);
|
receivingPlayer.getInventory().addItem(newBook);
|
||||||
BooksWithoutBorders.sendSuccessMessage(sender, "Book sent!");
|
BooksWithoutBorders.sendSuccessMessage(sender, "Book sent!");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookLoader;
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
||||||
@ -19,8 +20,6 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class CommandLoad implements TabExecutor {
|
public class CommandLoad implements TabExecutor {
|
||||||
|
|
||||||
private final BooksWithoutBorders booksWithoutBorders = BooksWithoutBorders.getInstance();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
return loadBook(sender, args, "player", false);
|
return loadBook(sender, args, "player", false);
|
||||||
@ -79,7 +78,7 @@ public class CommandLoad implements TabExecutor {
|
|||||||
String bookToLoad = InputCleaningHelper.cleanString(bookIdentifier);
|
String bookToLoad = InputCleaningHelper.cleanString(bookIdentifier);
|
||||||
try {
|
try {
|
||||||
//Give the new book if it can be loaded
|
//Give the new book if it can be loaded
|
||||||
ItemStack newBook = booksWithoutBorders.loadBook(player, bookToLoad, isSigned, directory, Integer.parseInt(copies));
|
ItemStack newBook = BookLoader.loadBook(player, bookToLoad, isSigned, directory, Integer.parseInt(copies));
|
||||||
if (newBook != null) {
|
if (newBook != null) {
|
||||||
player.getInventory().addItem(newBook);
|
player.getInventory().addItem(newBook);
|
||||||
BooksWithoutBorders.sendSuccessMessage(player, "Book created!");
|
BooksWithoutBorders.sendSuccessMessage(player, "Book created!");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
@ -14,11 +15,9 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class CommandReload implements TabExecutor {
|
public class CommandReload implements TabExecutor {
|
||||||
|
|
||||||
private final BooksWithoutBorders booksWithoutBorders = BooksWithoutBorders.getInstance();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
if (booksWithoutBorders.loadConfig()) {
|
if (BooksWithoutBordersConfig.loadConfig()) {
|
||||||
BooksWithoutBorders.sendSuccessMessage(sender, "BooksWithoutBorders configuration reloaded!");
|
BooksWithoutBorders.sendSuccessMessage(sender, "BooksWithoutBorders configuration reloaded!");
|
||||||
} else {
|
} else {
|
||||||
BooksWithoutBorders.sendErrorMessage(sender, "Reload Failed!");
|
BooksWithoutBorders.sendErrorMessage(sender, "Reload Failed!");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.state.ItemSlot;
|
import net.knarcraft.bookswithoutborders.state.ItemSlot;
|
||||||
import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper;
|
import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
||||||
@ -18,11 +19,10 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.getTitleAuthorSeparator;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getCommandColor;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getCommandColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getErrorColor;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getErrorColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getSlash;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
|
||||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName;
|
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName;
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ public class CommandSave implements TabExecutor {
|
|||||||
if (!book.hasTitle()) {
|
if (!book.hasTitle()) {
|
||||||
fileName = "Untitled," + player.getName();
|
fileName = "Untitled," + player.getName();
|
||||||
} else {
|
} else {
|
||||||
fileName = book.getTitle() + getTitleAuthorSeparator() + book.getAuthor();
|
fileName = book.getTitle() + BooksWithoutBordersConfig.getTitleAuthorSeparator() + book.getAuthor();
|
||||||
}
|
}
|
||||||
fileName = cleanString(fileName);
|
fileName = cleanString(fileName);
|
||||||
fileName = fixName(fileName, false);
|
fileName = fixName(fileName, false);
|
||||||
@ -120,7 +120,7 @@ public class CommandSave implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Skip if duplicate limit is reached
|
//Skip if duplicate limit is reached
|
||||||
if (foundDuplicates > BooksWithoutBorders.getBookDuplicateLimit()) {
|
if (foundDuplicates > BooksWithoutBordersConfig.getBookDuplicateLimit()) {
|
||||||
BooksWithoutBorders.sendErrorMessage(player, "Maximum amount of " + fileName + " duplicates reached!");
|
BooksWithoutBorders.sendErrorMessage(player, "Maximum amount of " + fileName + " duplicates reached!");
|
||||||
BooksWithoutBorders.sendErrorMessage(player, "Use " + getCommandColor() + "/savebook true " + getErrorColor() + "to overwrite!");
|
BooksWithoutBorders.sendErrorMessage(player, "Use " + getCommandColor() + "/savebook true " + getErrorColor() + "to overwrite!");
|
||||||
return;
|
return;
|
||||||
@ -133,7 +133,7 @@ public class CommandSave implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (BooksWithoutBorders.getUseYml()) {
|
if (BooksWithoutBordersConfig.getUseYml()) {
|
||||||
BookToFromTextHelper.bookToYml(savePath, fileName, book);
|
BookToFromTextHelper.bookToYml(savePath, fileName, book);
|
||||||
} else {
|
} else {
|
||||||
BookToFromTextHelper.bookToTXT(savePath, fileName, book);
|
BookToFromTextHelper.bookToTXT(savePath, fileName, book);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
import net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
||||||
@ -66,10 +67,10 @@ public class CommandSetBookPrice implements TabExecutor {
|
|||||||
* @param sender <p>The sender of the command</p>
|
* @param sender <p>The sender of the command</p>
|
||||||
*/
|
*/
|
||||||
private void clearItemPrice(CommandSender sender) {
|
private void clearItemPrice(CommandSender sender) {
|
||||||
BooksWithoutBorders.setBookPriceType(null);
|
BooksWithoutBordersConfig.setBookPriceType(null);
|
||||||
BooksWithoutBorders.setBookPriceQuantity(0);
|
BooksWithoutBordersConfig.setBookPriceQuantity(0);
|
||||||
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Item type name");
|
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Item type name");
|
||||||
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", BooksWithoutBorders.getBookPriceQuantity());
|
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", BooksWithoutBordersConfig.getBookPriceQuantity());
|
||||||
booksWithoutBorders.saveConfig();
|
booksWithoutBorders.saveConfig();
|
||||||
|
|
||||||
BooksWithoutBorders.sendSuccessMessage(sender, "Price to create books removed!");
|
BooksWithoutBorders.sendSuccessMessage(sender, "Price to create books removed!");
|
||||||
@ -94,10 +95,10 @@ public class CommandSetBookPrice implements TabExecutor {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BooksWithoutBorders.setBookPriceType(heldItem.getType());
|
BooksWithoutBordersConfig.setBookPriceType(heldItem.getType());
|
||||||
BooksWithoutBorders.setBookPriceQuantity(price);
|
BooksWithoutBordersConfig.setBookPriceQuantity(price);
|
||||||
String newPriceType = BooksWithoutBorders.getBookPriceType().toString();
|
String newPriceType = BooksWithoutBordersConfig.getBookPriceType().toString();
|
||||||
double newPriceQuantity = BooksWithoutBorders.getBookPriceQuantity();
|
double newPriceQuantity = BooksWithoutBordersConfig.getBookPriceQuantity();
|
||||||
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", newPriceType);
|
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", newPriceType);
|
||||||
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", newPriceQuantity);
|
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", newPriceQuantity);
|
||||||
booksWithoutBorders.saveConfig();
|
booksWithoutBorders.saveConfig();
|
||||||
@ -116,9 +117,9 @@ public class CommandSetBookPrice implements TabExecutor {
|
|||||||
*/
|
*/
|
||||||
private boolean setEconomyPrice(CommandSender sender, double price) {
|
private boolean setEconomyPrice(CommandSender sender, double price) {
|
||||||
if (EconomyHelper.setupEconomy()) {
|
if (EconomyHelper.setupEconomy()) {
|
||||||
BooksWithoutBorders.setBookPriceQuantity(price);
|
BooksWithoutBordersConfig.setBookPriceQuantity(price);
|
||||||
BooksWithoutBorders.setBookPriceType(Material.AIR);
|
BooksWithoutBordersConfig.setBookPriceType(Material.AIR);
|
||||||
double newPriceQuantity = BooksWithoutBorders.getBookPriceQuantity();
|
double newPriceQuantity = BooksWithoutBordersConfig.getBookPriceQuantity();
|
||||||
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Economy");
|
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Economy");
|
||||||
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", newPriceQuantity);
|
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", newPriceQuantity);
|
||||||
booksWithoutBorders.saveConfig();
|
booksWithoutBorders.saveConfig();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.command;
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -44,7 +45,7 @@ public class CommandSetLore implements TabExecutor {
|
|||||||
|
|
||||||
//Format lore
|
//Format lore
|
||||||
rawLore = ChatColor.translateAlternateColorCodes('&', rawLore);
|
rawLore = ChatColor.translateAlternateColorCodes('&', rawLore);
|
||||||
String[] loreParts = rawLore.split(BooksWithoutBorders.getLoreSeparator());
|
String[] loreParts = rawLore.split(BooksWithoutBordersConfig.getLoreSeparator());
|
||||||
List<String> newLore = new ArrayList<>(Arrays.asList(loreParts));
|
List<String> newLore = new ArrayList<>(Arrays.asList(loreParts));
|
||||||
|
|
||||||
//Update lore
|
//Update lore
|
||||||
|
@ -0,0 +1,271 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.config;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
|
import org.bukkit.configuration.Configuration;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.sendErrorMessage;
|
||||||
|
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.sendSuccessMessage;
|
||||||
|
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
||||||
|
|
||||||
|
public class BooksWithoutBordersConfig {
|
||||||
|
|
||||||
|
private static int bookDuplicateLimit;
|
||||||
|
private static String titleAuthorSeparator;
|
||||||
|
private static String loreSeparator;
|
||||||
|
private static List<String> firstBooks = new ArrayList<>();
|
||||||
|
private static String welcomeMessage;
|
||||||
|
private static Material bookPriceType = null;
|
||||||
|
private static double bookPriceQuantity;
|
||||||
|
private static boolean authorOnlyCopy;
|
||||||
|
private static boolean useYml;
|
||||||
|
private static boolean adminDecrypt;
|
||||||
|
private static boolean formatBooks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether only the author of a book should be able to copy it
|
||||||
|
*
|
||||||
|
* @return <p>Whether only the book author can copy it</p>
|
||||||
|
*/
|
||||||
|
public static boolean getAuthorOnlyCopy() {
|
||||||
|
return authorOnlyCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether to use YML, not TXT, for saving books
|
||||||
|
*
|
||||||
|
* @return <p>Whether to use YML for saving books</p>
|
||||||
|
*/
|
||||||
|
public static boolean getUseYml() {
|
||||||
|
return useYml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether admins should be able to decrypt books without a password, and decrypt all group encrypted books
|
||||||
|
*
|
||||||
|
* @return <p>Whether admins can bypass the encryption password</p>
|
||||||
|
*/
|
||||||
|
public static boolean getAdminDecrypt() {
|
||||||
|
return adminDecrypt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the quantity of items/currency necessary for copying books
|
||||||
|
*
|
||||||
|
* @param newQuantity <p>The new quantity necessary for payment</p>
|
||||||
|
*/
|
||||||
|
public static void setBookPriceQuantity(double newQuantity) {
|
||||||
|
bookPriceQuantity = newQuantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the quantity of items/currency necessary for copying books
|
||||||
|
*
|
||||||
|
* @return <p>The quantity necessary for payment</p>
|
||||||
|
*/
|
||||||
|
public static double getBookPriceQuantity() {
|
||||||
|
return bookPriceQuantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the item type used for book pricing
|
||||||
|
*
|
||||||
|
* <p>This item is the one a player has to pay for copying books. AIR is used to denote economy. null is used if
|
||||||
|
* payment is disabled. Otherwise, any item can be used.</p>
|
||||||
|
*
|
||||||
|
* @param newType <p>The new item type to use for book pricing</p>
|
||||||
|
*/
|
||||||
|
public static void setBookPriceType(Material newType) {
|
||||||
|
bookPriceType = newType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the item type used for book pricing
|
||||||
|
*
|
||||||
|
* <p>This item is the one a player has to pay for copying books. AIR is used to denote economy. null is used if
|
||||||
|
* payment is disabled. Otherwise, any item can be used.</p>
|
||||||
|
*
|
||||||
|
* @return <p>The item type used for book pricing</p>
|
||||||
|
*/
|
||||||
|
public static Material getBookPriceType() {
|
||||||
|
return bookPriceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the welcome message to show to new players
|
||||||
|
*
|
||||||
|
* @return <p>The welcome message to show new players</p>
|
||||||
|
*/
|
||||||
|
public static String getWelcomeMessage() {
|
||||||
|
return welcomeMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the limit of duplicates for each book
|
||||||
|
*
|
||||||
|
* @return <p>The book duplicate limit</p>
|
||||||
|
*/
|
||||||
|
public static int getBookDuplicateLimit() {
|
||||||
|
return bookDuplicateLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the separator used to split book title from book author
|
||||||
|
*
|
||||||
|
* @return <p>The separator between title and author</p>
|
||||||
|
*/
|
||||||
|
public static String getTitleAuthorSeparator() {
|
||||||
|
return titleAuthorSeparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the separator used to denote a newline in a lore string
|
||||||
|
*
|
||||||
|
* @return <p>The separator used to denote lore newline</p>
|
||||||
|
*/
|
||||||
|
public static String getLoreSeparator() {
|
||||||
|
return loreSeparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether all books should be formatted when they are signed
|
||||||
|
*
|
||||||
|
* @return <p>Whether all books should be formatted</p>
|
||||||
|
*/
|
||||||
|
public static boolean formatBooks() {
|
||||||
|
return formatBooks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a copy of the list of books to give new players
|
||||||
|
*
|
||||||
|
* @return <p>The books to give new players</p>
|
||||||
|
*/
|
||||||
|
public static List<String> getFirstBooks() {
|
||||||
|
return new ArrayList<>(firstBooks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether books have a price for printing them
|
||||||
|
*
|
||||||
|
* @return <p>True if players need to pay for printing books</p>
|
||||||
|
*/
|
||||||
|
public static boolean booksHavePrice() {
|
||||||
|
return (bookPriceType != null && bookPriceQuantity > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the config
|
||||||
|
*/
|
||||||
|
public static void saveConfigValues() {
|
||||||
|
ConsoleCommandSender consoleSender = BooksWithoutBorders.getInstance().getServer().getConsoleSender();
|
||||||
|
Configuration config = BooksWithoutBorders.getInstance().getConfig();
|
||||||
|
config.set(ConfigOption.USE_YAML.getConfigNode(), useYml);
|
||||||
|
config.set(ConfigOption.MAX_DUPLICATES.getConfigNode(), bookDuplicateLimit);
|
||||||
|
config.set(ConfigOption.TITLE_AUTHOR_SEPARATOR.getConfigNode(), titleAuthorSeparator);
|
||||||
|
config.set(ConfigOption.LORE_LINE_SEPARATOR.getConfigNode(), loreSeparator);
|
||||||
|
config.set(ConfigOption.BOOKS_FOR_NEW_PLAYERS.getConfigNode(), firstBooks);
|
||||||
|
config.set(ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getConfigNode(), welcomeMessage);
|
||||||
|
config.set(ConfigOption.FORMAT_AFTER_SIGNING.getConfigNode(), formatBooks);
|
||||||
|
|
||||||
|
String itemTypeNode = ConfigOption.PRICE_ITEM_TYPE.getConfigNode();
|
||||||
|
if (bookPriceType != null) {
|
||||||
|
if (bookPriceType != Material.AIR) {
|
||||||
|
config.set(itemTypeNode, bookPriceType.toString());
|
||||||
|
} else {
|
||||||
|
config.set(itemTypeNode, "Economy");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
config.set(itemTypeNode, "Item type name");
|
||||||
|
}
|
||||||
|
|
||||||
|
config.set(ConfigOption.PRICE_QUANTITY.getConfigNode(), bookPriceQuantity);
|
||||||
|
config.set(ConfigOption.ADMIN_AUTO_DECRYPT.getConfigNode(), adminDecrypt);
|
||||||
|
config.set(ConfigOption.AUTHOR_ONLY_COPY.getConfigNode(), authorOnlyCopy);
|
||||||
|
|
||||||
|
//Handles old book and quill settings
|
||||||
|
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, "Updating to \"Price_to_create_book\" settings");
|
||||||
|
|
||||||
|
if (config.getBoolean("Options.Require_book_and_quill_to_create_book")) {
|
||||||
|
bookPriceType = Material.WRITABLE_BOOK;
|
||||||
|
bookPriceQuantity = 1;
|
||||||
|
config.set("Options.Price_to_create_book.Item_type", bookPriceType.toString());
|
||||||
|
config.set("Options.Price_to_create_book.Required_quantity", bookPriceQuantity);
|
||||||
|
}
|
||||||
|
config.set("Options.Require_book_and_quill_to_create_book", null);
|
||||||
|
}
|
||||||
|
BooksWithoutBorders.getInstance().saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the config
|
||||||
|
*
|
||||||
|
* @return <p>True if the config was loaded successfully</p>
|
||||||
|
*/
|
||||||
|
public static boolean loadConfig() {
|
||||||
|
ConsoleCommandSender consoleSender = BooksWithoutBorders.getInstance().getServer().getConsoleSender();
|
||||||
|
BooksWithoutBorders.getInstance().reloadConfig();
|
||||||
|
Configuration config = BooksWithoutBorders.getInstance().getConfig();
|
||||||
|
try {
|
||||||
|
useYml = config.getBoolean(ConfigOption.USE_YAML.getConfigNode(),
|
||||||
|
(Boolean) ConfigOption.USE_YAML.getDefaultValue());
|
||||||
|
bookDuplicateLimit = config.getInt(ConfigOption.MAX_DUPLICATES.getConfigNode(),
|
||||||
|
(Integer) ConfigOption.MAX_DUPLICATES.getDefaultValue());
|
||||||
|
titleAuthorSeparator = config.getString(ConfigOption.TITLE_AUTHOR_SEPARATOR.getConfigNode(),
|
||||||
|
(String) ConfigOption.TITLE_AUTHOR_SEPARATOR.getDefaultValue());
|
||||||
|
loreSeparator = config.getString(ConfigOption.LORE_LINE_SEPARATOR.getConfigNode(),
|
||||||
|
(String) ConfigOption.LORE_LINE_SEPARATOR.getDefaultValue());
|
||||||
|
adminDecrypt = config.getBoolean(ConfigOption.ADMIN_AUTO_DECRYPT.getConfigNode(),
|
||||||
|
(Boolean) ConfigOption.ADMIN_AUTO_DECRYPT.getDefaultValue());
|
||||||
|
authorOnlyCopy = config.getBoolean(ConfigOption.AUTHOR_ONLY_COPY.getConfigNode(),
|
||||||
|
(Boolean) ConfigOption.AUTHOR_ONLY_COPY.getDefaultValue());
|
||||||
|
firstBooks = config.getStringList(ConfigOption.BOOKS_FOR_NEW_PLAYERS.getConfigNode());
|
||||||
|
welcomeMessage = config.getString(ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getConfigNode(),
|
||||||
|
(String) ConfigOption.MESSAGE_FOR_NEW_PLAYERS.getDefaultValue());
|
||||||
|
formatBooks = config.getBoolean(ConfigOption.FORMAT_AFTER_SIGNING.getConfigNode(),
|
||||||
|
(Boolean) ConfigOption.FORMAT_AFTER_SIGNING.getDefaultValue());
|
||||||
|
|
||||||
|
//Convert string into material
|
||||||
|
String paymentMaterial = config.getString(ConfigOption.PRICE_ITEM_TYPE.getConfigNode(),
|
||||||
|
(String) ConfigOption.PRICE_ITEM_TYPE.getDefaultValue());
|
||||||
|
if (paymentMaterial.equalsIgnoreCase("Economy")) {
|
||||||
|
if (EconomyHelper.setupEconomy()) {
|
||||||
|
bookPriceType = Material.AIR;
|
||||||
|
} else {
|
||||||
|
sendErrorMessage(consoleSender, "BooksWithoutBorders failed to hook into Vault! Book price not set!");
|
||||||
|
bookPriceType = null;
|
||||||
|
}
|
||||||
|
} else if (!paymentMaterial.trim().isEmpty()) {
|
||||||
|
Material material = Material.matchMaterial(paymentMaterial);
|
||||||
|
if (material != null) {
|
||||||
|
bookPriceType = material;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bookPriceQuantity = config.getDouble(ConfigOption.PRICE_QUANTITY.getConfigNode(),
|
||||||
|
(Double) ConfigOption.PRICE_QUANTITY.getDefaultValue());
|
||||||
|
|
||||||
|
//Make sure titleAuthorSeparator is a valid value
|
||||||
|
titleAuthorSeparator = cleanString(titleAuthorSeparator);
|
||||||
|
if (titleAuthorSeparator.length() != 1) {
|
||||||
|
sendErrorMessage(consoleSender, "Title-Author_Separator is set to an invalid value!");
|
||||||
|
sendErrorMessage(consoleSender, "Reverting to default value of \",\"");
|
||||||
|
titleAuthorSeparator = ",";
|
||||||
|
config.set("Options.Title-Author_Separator", titleAuthorSeparator);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
sendErrorMessage(consoleSender, "Warning! Config.yml failed to load!");
|
||||||
|
sendErrorMessage(consoleSender, "Try Looking for settings that are missing values!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package net.knarcraft.bookswithoutborders;
|
package net.knarcraft.bookswithoutborders.config;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
/**
|
/**
|
@ -0,0 +1,95 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A representation of the different available config options
|
||||||
|
*/
|
||||||
|
public enum ConfigOption {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether YAML should be used to store books instead of simple text files
|
||||||
|
*/
|
||||||
|
USE_YAML("Options.Save_Books_in_Yaml_Format", true),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The max duplicates of a book that can be saved
|
||||||
|
*/
|
||||||
|
MAX_DUPLICATES("Options.Max_Number_of_Duplicates", 5),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The separator used to separate book title and book author
|
||||||
|
*/
|
||||||
|
TITLE_AUTHOR_SEPARATOR("Options.Title-Author_Separator", ","),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The separator used to specify a new line in an item's lore
|
||||||
|
*/
|
||||||
|
LORE_LINE_SEPARATOR("Options.Lore_line_separator", "~"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The books given to new players when they first join
|
||||||
|
*/
|
||||||
|
BOOKS_FOR_NEW_PLAYERS("Options.Books_for_new_players", "[]"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message to display to new players when they first join
|
||||||
|
*/
|
||||||
|
MESSAGE_FOR_NEW_PLAYERS("Options.Message_for_new_players", ""),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The item type used to pay for book copying
|
||||||
|
*/
|
||||||
|
PRICE_ITEM_TYPE("Options.Price_to_create_book.Item_type", ""),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount of items used to pay for book copying
|
||||||
|
*/
|
||||||
|
PRICE_QUANTITY("Options.Price_to_create_book.Required_quantity", 0.0),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether admins should be able to decrypt books for all groups
|
||||||
|
*/
|
||||||
|
ADMIN_AUTO_DECRYPT("Options.Admin_Auto_Decrypt", false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether only the book author should be able to copy a book
|
||||||
|
*/
|
||||||
|
AUTHOR_ONLY_COPY("Options.Author_Only_Copy", false),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to automatically format every signed book
|
||||||
|
*/
|
||||||
|
FORMAT_AFTER_SIGNING("Options.Format_Book_After_Signing", false);
|
||||||
|
|
||||||
|
private final String configNode;
|
||||||
|
private final Object defaultValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new config option
|
||||||
|
*
|
||||||
|
* @param configNode <p>The config node in the config file this option represents</p>
|
||||||
|
* @param defaultValue <p>The default value for this config option</p>
|
||||||
|
*/
|
||||||
|
ConfigOption(String configNode, Object defaultValue) {
|
||||||
|
this.configNode = configNode;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the config node used for loading/saving this config value
|
||||||
|
*
|
||||||
|
* @return <p>The config node</p>
|
||||||
|
*/
|
||||||
|
public String getConfigNode() {
|
||||||
|
return this.configNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default value of this config option
|
||||||
|
*
|
||||||
|
* @return <p>The default value of this config option</p>
|
||||||
|
*/
|
||||||
|
public Object getDefaultValue() {
|
||||||
|
return this.defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.listener;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookFormatter;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerEditBookEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A listener for listening to book events
|
||||||
|
*
|
||||||
|
* <p>Mainly used for auto-formatting signed books if enabled</p>
|
||||||
|
*/
|
||||||
|
public class BookEventListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBookSign(PlayerEditBookEvent event) {
|
||||||
|
if (event.isCancelled() || !event.isSigning() || !BooksWithoutBordersConfig.formatBooks()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.setNewBookMeta(BookFormatter.formatPages(event.getNewBookMeta()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
package net.knarcraft.bookswithoutborders.listener;
|
package net.knarcraft.bookswithoutborders.listener;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookLoader;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -16,8 +18,8 @@ import org.bukkit.inventory.meta.ItemMeta;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getSlash;
|
||||||
|
|
||||||
public class PlayerEventListener implements Listener {
|
public class PlayerEventListener implements Listener {
|
||||||
|
|
||||||
@ -58,7 +60,7 @@ public class PlayerEventListener implements Listener {
|
|||||||
boolean sendMessage = true;
|
boolean sendMessage = true;
|
||||||
|
|
||||||
//Gives new players necessary books
|
//Gives new players necessary books
|
||||||
for (String bookName : BooksWithoutBorders.getFirstBooks()) {
|
for (String bookName : BooksWithoutBordersConfig.getFirstBooks()) {
|
||||||
sendMessage = giveBookToNewPlayer(bookName, player, sendMessage);
|
sendMessage = giveBookToNewPlayer(bookName, player, sendMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,13 +90,13 @@ public class PlayerEventListener implements Listener {
|
|||||||
if (!bookName.trim().isEmpty()) {
|
if (!bookName.trim().isEmpty()) {
|
||||||
|
|
||||||
//Give the book to the player if it exists
|
//Give the book to the player if it exists
|
||||||
ItemStack newBook = booksWithoutBorders.loadBook(player, bookName, "true", "public");
|
ItemStack newBook = BookLoader.loadBook(player, bookName, "true", "public");
|
||||||
if (newBook != null) {
|
if (newBook != null) {
|
||||||
player.getInventory().addItem(newBook);
|
player.getInventory().addItem(newBook);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Send the player a welcome message if it exists
|
//Send the player a welcome message if it exists
|
||||||
String welcomeMessage = BooksWithoutBorders.getWelcomeMessage();
|
String welcomeMessage = BooksWithoutBordersConfig.getWelcomeMessage();
|
||||||
if (!welcomeMessage.trim().isEmpty() && newBook != null && sendMessage) {
|
if (!welcomeMessage.trim().isEmpty() && newBook != null && sendMessage) {
|
||||||
sendMessage = false;
|
sendMessage = false;
|
||||||
booksWithoutBorders.getServer().getScheduler().scheduleSyncDelayedTask(booksWithoutBorders,
|
booksWithoutBorders.getServer().getScheduler().scheduleSyncDelayedTask(booksWithoutBorders,
|
||||||
@ -143,7 +145,7 @@ public class PlayerEventListener implements Listener {
|
|||||||
//Unknown author is ignored
|
//Unknown author is ignored
|
||||||
fileName = oldBook.getTitle();
|
fileName = oldBook.getTitle();
|
||||||
} else {
|
} else {
|
||||||
fileName = oldBook.getTitle() + BooksWithoutBorders.getTitleAuthorSeparator() + oldBook.getAuthor();
|
fileName = oldBook.getTitle() + BooksWithoutBordersConfig.getTitleAuthorSeparator() + oldBook.getAuthor();
|
||||||
}
|
}
|
||||||
|
|
||||||
String cleanPlayerName = InputCleaningHelper.cleanString(player.getName());
|
String cleanPlayerName = InputCleaningHelper.cleanString(player.getName());
|
||||||
@ -158,7 +160,7 @@ public class PlayerEventListener implements Listener {
|
|||||||
for (String path : possiblePaths) {
|
for (String path : possiblePaths) {
|
||||||
File file = new File(path);
|
File file = new File(path);
|
||||||
if (file.isFile()) {
|
if (file.isFile()) {
|
||||||
return booksWithoutBorders.loadBook(player, fileName, "true", "player");
|
return BookLoader.loadBook(player, fileName, "true", "player");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package net.knarcraft.bookswithoutborders.listener;
|
package net.knarcraft.bookswithoutborders.listener;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
|
import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookLoader;
|
||||||
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
|
import net.knarcraft.bookswithoutborders.utility.EncryptionHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
import net.knarcraft.bookswithoutborders.utility.FileHelper;
|
||||||
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
import net.knarcraft.bookswithoutborders.utility.InputCleaningHelper;
|
||||||
@ -22,8 +24,8 @@ import org.bukkit.inventory.meta.BookMeta;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getSlash;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.FileHelper.isBookListIndex;
|
import static net.knarcraft.bookswithoutborders.utility.FileHelper.isBookListIndex;
|
||||||
|
|
||||||
public class SignEventListener implements Listener {
|
public class SignEventListener implements Listener {
|
||||||
@ -234,11 +236,11 @@ public class SignEventListener implements Listener {
|
|||||||
|
|
||||||
//Permission check
|
//Permission check
|
||||||
if (!player.hasPermission("bookswithoutborders.decrypt." + groupName) &&
|
if (!player.hasPermission("bookswithoutborders.decrypt." + groupName) &&
|
||||||
!(BooksWithoutBorders.getAdminDecrypt() && player.hasPermission("bookswithoutborders.admin"))) {
|
!(BooksWithoutBordersConfig.getAdminDecrypt() && player.hasPermission("bookswithoutborders.admin"))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String fileName = oldBook.getTitle() + BooksWithoutBorders.getTitleAuthorSeparator() + oldBook.getAuthor();
|
String fileName = oldBook.getTitle() + BooksWithoutBordersConfig.getTitleAuthorSeparator() + oldBook.getAuthor();
|
||||||
|
|
||||||
String encryptionFile = InputCleaningHelper.cleanString(groupName) + slash + fileName + ".yml";
|
String encryptionFile = InputCleaningHelper.cleanString(groupName) + slash + fileName + ".yml";
|
||||||
|
|
||||||
@ -249,7 +251,7 @@ public class SignEventListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newBook = BooksWithoutBorders.getInstance().loadBook(player, fileName, "true", groupName, heldItem.getAmount());
|
newBook = BookLoader.loadBook(player, fileName, "true", groupName, heldItem.getAmount());
|
||||||
|
|
||||||
if (newBook == null) {
|
if (newBook == null) {
|
||||||
return;
|
return;
|
||||||
@ -304,7 +306,7 @@ public class SignEventListener implements Listener {
|
|||||||
fileName += ChatColor.stripColor(thirdLine);
|
fileName += ChatColor.stripColor(thirdLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack newBook = BooksWithoutBorders.getInstance().loadBook(player, fileName, "true", "public");
|
ItemStack newBook = BookLoader.loadBook(player, fileName, "true", "public");
|
||||||
|
|
||||||
if (newBook != null) {
|
if (newBook != null) {
|
||||||
player.getInventory().addItem(newBook);
|
player.getInventory().addItem(newBook);
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
package net.knarcraft.bookswithoutborders.utility;
|
package net.knarcraft.bookswithoutborders.utility;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class for formatting text to fit books
|
* A class for formatting text to fit books
|
||||||
@ -94,4 +101,35 @@ public final class BookFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats every page in the given book meta by converting color and formatting codes
|
||||||
|
*
|
||||||
|
* @param bookMeta <p>The book meta to change</p>
|
||||||
|
* @return <p>The changed book meta</p>
|
||||||
|
*/
|
||||||
|
public static BookMeta formatPages(BookMeta bookMeta) {
|
||||||
|
List<String> formattedPages = new ArrayList<>(Objects.requireNonNull(bookMeta).getPageCount());
|
||||||
|
for (String page : bookMeta.getPages()) {
|
||||||
|
formattedPages.add(BookFormatter.translateAllColorCodes(page));
|
||||||
|
}
|
||||||
|
bookMeta.setPages(formattedPages);
|
||||||
|
return bookMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates all found color codes to formatting in a string
|
||||||
|
*
|
||||||
|
* @param message <p>The string to search for color codes</p>
|
||||||
|
* @return <p>The message with color codes translated</p>
|
||||||
|
*/
|
||||||
|
private static String translateAllColorCodes(String message) {
|
||||||
|
message = ChatColor.translateAlternateColorCodes('&', message);
|
||||||
|
Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})");
|
||||||
|
Matcher matcher = pattern.matcher(message);
|
||||||
|
while (matcher.find()) {
|
||||||
|
message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group()));
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,129 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.utility;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings;
|
||||||
|
import net.knarcraft.bookswithoutborders.state.BookDirectory;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class BookLoader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the given book
|
||||||
|
*
|
||||||
|
* @param sender <p>The command sender trying to load the book</p>
|
||||||
|
* @param fileName <p>The index or file name of the book to load</p>
|
||||||
|
* @param isSigned <p>Whether to load the book as signed, and not unsigned</p>
|
||||||
|
* @param directory <p>The directory to save the book in</p>
|
||||||
|
* @return <p>The loaded book</p>
|
||||||
|
*/
|
||||||
|
public static ItemStack loadBook(CommandSender sender, String fileName, String isSigned, String directory) {
|
||||||
|
return loadBook(sender, fileName, isSigned, directory, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the given book
|
||||||
|
*
|
||||||
|
* @param sender <p>The command sender trying to load the book</p>
|
||||||
|
* @param fileName <p>The index or file name of the book to load</p>
|
||||||
|
* @param isSigned <p>Whether to load the book as signed, and not unsigned</p>
|
||||||
|
* @param directory <p>The directory to save the book in</p>
|
||||||
|
* @param numCopies <p>The number of copies to load</p>
|
||||||
|
* @return <p>The loaded book</p>
|
||||||
|
*/
|
||||||
|
public static ItemStack loadBook(CommandSender sender, String fileName, String isSigned, String directory, int numCopies) {
|
||||||
|
BookDirectory bookDirectory = BookDirectory.getFromString(directory);
|
||||||
|
|
||||||
|
//Find the filename if a book index is given
|
||||||
|
try {
|
||||||
|
int bookIndex = Integer.parseInt(fileName);
|
||||||
|
List<String> availableFiles = BooksWithoutBorders.getAvailableBooks(sender, bookDirectory == BookDirectory.PUBLIC);
|
||||||
|
if (bookIndex <= availableFiles.size()) {
|
||||||
|
fileName = availableFiles.get(Integer.parseInt(fileName) - 1);
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the full path of the book to load
|
||||||
|
File file = getFullPath(sender, fileName, bookDirectory, directory);
|
||||||
|
if (file == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Make sure the player can pay for the book
|
||||||
|
if (BooksWithoutBordersConfig.booksHavePrice() && !sender.hasPermission("bookswithoutborders.bypassBookPrice") &&
|
||||||
|
(bookDirectory == BookDirectory.PUBLIC || bookDirectory == BookDirectory.PLAYER) &&
|
||||||
|
EconomyHelper.cannotPayForBookPrinting((Player) sender, numCopies)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Generate a new empty book
|
||||||
|
ItemStack book;
|
||||||
|
BookMeta bookMetadata = (BookMeta) BooksWithoutBorders.getItemFactory().getItemMeta(Material.WRITTEN_BOOK);
|
||||||
|
if (isSigned.equalsIgnoreCase("true")) {
|
||||||
|
book = new ItemStack(Material.WRITTEN_BOOK);
|
||||||
|
} else {
|
||||||
|
book = new ItemStack(Material.WRITABLE_BOOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Load the book from the given file
|
||||||
|
BookToFromTextHelper.bookFromFile(file, bookMetadata);
|
||||||
|
if (bookMetadata == null) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "File was blank!!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove "encrypted" from the book lore
|
||||||
|
if (bookDirectory == BookDirectory.ENCRYPTED && bookMetadata.hasLore()) {
|
||||||
|
List<String> oldLore = bookMetadata.getLore();
|
||||||
|
if (oldLore != null) {
|
||||||
|
List<String> newLore = new ArrayList<>(oldLore);
|
||||||
|
newLore.remove(0);
|
||||||
|
bookMetadata.setLore(newLore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the metadata and amount to the new book
|
||||||
|
book.setItemMeta(bookMetadata);
|
||||||
|
book.setAmount(numCopies);
|
||||||
|
|
||||||
|
return book;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a File pointing to the wanted book
|
||||||
|
*
|
||||||
|
* @param sender <p>The sender to send errors to</p>
|
||||||
|
* @param fileName <p>The name of the book file</p>
|
||||||
|
* @param bookDirectory <p>The book directory the file resides in</p>
|
||||||
|
* @param directory <p>The relative directory given</p>
|
||||||
|
* @return <p>A file or null if it does not exist</p>
|
||||||
|
*/
|
||||||
|
private static File getFullPath(CommandSender sender, String fileName, BookDirectory bookDirectory, String directory) {
|
||||||
|
File file = null;
|
||||||
|
String slash = BooksWithoutBordersSettings.getSlash();
|
||||||
|
String bookFolder = BooksWithoutBordersSettings.getBookFolder();
|
||||||
|
if (bookDirectory == BookDirectory.PUBLIC) {
|
||||||
|
file = FileHelper.getBookFile(bookFolder + fileName);
|
||||||
|
} else if (bookDirectory == BookDirectory.PLAYER) {
|
||||||
|
file = FileHelper.getBookFile(bookFolder + InputCleaningHelper.cleanString(sender.getName()) + slash + fileName);
|
||||||
|
} else if (bookDirectory == BookDirectory.ENCRYPTED) {
|
||||||
|
file = FileHelper.getBookFile(bookFolder + "Encrypted" + slash + directory + slash + fileName);
|
||||||
|
}
|
||||||
|
if (file == null || !file.isFile()) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "Incorrect file name!");
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package net.knarcraft.bookswithoutborders.utility;
|
package net.knarcraft.bookswithoutborders.utility;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
@ -121,7 +121,7 @@ public final class BookToFromTextHelper {
|
|||||||
private static BookMeta bookFromTXT(String fileName, File file, BookMeta bookMetadata) {
|
private static BookMeta bookFromTXT(String fileName, File file, BookMeta bookMetadata) {
|
||||||
String author;
|
String author;
|
||||||
String title;
|
String title;
|
||||||
String titleAuthorSeparator = BooksWithoutBorders.getTitleAuthorSeparator();
|
String titleAuthorSeparator = BooksWithoutBordersConfig.getTitleAuthorSeparator();
|
||||||
|
|
||||||
//Get title and author from the file name
|
//Get title and author from the file name
|
||||||
if (fileName.contains(titleAuthorSeparator)) {
|
if (fileName.contains(titleAuthorSeparator)) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.utility;
|
package net.knarcraft.bookswithoutborders.utility;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.milkbowl.vault.economy.Economy;
|
import net.milkbowl.vault.economy.Economy;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
@ -67,8 +68,8 @@ public final class EconomyHelper {
|
|||||||
public static boolean cannotPayForBookPrinting(Player player, int numCopies) {
|
public static boolean cannotPayForBookPrinting(Player player, int numCopies) {
|
||||||
//BookPriceQuantity: How many items are required to pay for each book
|
//BookPriceQuantity: How many items are required to pay for each book
|
||||||
//BookPriceType: Which item is used to pay for the books. AIR = use economy
|
//BookPriceType: Which item is used to pay for the books. AIR = use economy
|
||||||
Material bookCurrency = BooksWithoutBorders.getBookPriceType();
|
Material bookCurrency = BooksWithoutBordersConfig.getBookPriceType();
|
||||||
double cost = BooksWithoutBorders.getBookPriceQuantity() * numCopies;
|
double cost = BooksWithoutBordersConfig.getBookPriceQuantity() * numCopies;
|
||||||
int itemCost = (int) cost;
|
int itemCost = (int) cost;
|
||||||
|
|
||||||
if (bookCurrency == Material.AIR) {
|
if (bookCurrency == Material.AIR) {
|
||||||
@ -116,7 +117,7 @@ public final class EconomyHelper {
|
|||||||
|
|
||||||
int clearedAmount = 0;
|
int clearedAmount = 0;
|
||||||
while (clearedAmount < itemCost) {
|
while (clearedAmount < itemCost) {
|
||||||
int firstItemIndex = playerInventory.first(BooksWithoutBorders.getBookPriceType());
|
int firstItemIndex = playerInventory.first(BooksWithoutBordersConfig.getBookPriceType());
|
||||||
ItemStack firstItem = playerInventory.getItem(firstItemIndex);
|
ItemStack firstItem = playerInventory.getItem(firstItemIndex);
|
||||||
|
|
||||||
if (Objects.requireNonNull(firstItem).getAmount() <= itemCost - clearedAmount) {
|
if (Objects.requireNonNull(firstItem).getAmount() <= itemCost - clearedAmount) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.bookswithoutborders.utility;
|
package net.knarcraft.bookswithoutborders.utility;
|
||||||
|
|
||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
import net.knarcraft.bookswithoutborders.encryption.GenenCrypt;
|
import net.knarcraft.bookswithoutborders.encryption.GenenCrypt;
|
||||||
import net.knarcraft.bookswithoutborders.encryption.SubstitutionCipher;
|
import net.knarcraft.bookswithoutborders.encryption.SubstitutionCipher;
|
||||||
import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
|
import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
|
||||||
@ -16,8 +17,8 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getSlash;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName;
|
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixName;
|
||||||
|
|
||||||
@ -199,7 +200,7 @@ public final class EncryptionHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String fileName = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() : bookMetadata.getTitle() +
|
String fileName = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() : bookMetadata.getTitle() +
|
||||||
BooksWithoutBorders.getTitleAuthorSeparator() + bookMetadata.getAuthor();
|
BooksWithoutBordersConfig.getTitleAuthorSeparator() + bookMetadata.getAuthor();
|
||||||
fileName = "[" + key + "]" + fileName;
|
fileName = "[" + key + "]" + fileName;
|
||||||
fileName = cleanString(fileName);
|
fileName = cleanString(fileName);
|
||||||
fileName = fixName(fileName, false);
|
fileName = fixName(fileName, false);
|
||||||
@ -265,7 +266,7 @@ public final class EncryptionHelper {
|
|||||||
}
|
}
|
||||||
//Creates file
|
//Creates file
|
||||||
String fileName = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() :
|
String fileName = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() :
|
||||||
bookMetadata.getTitle() + BooksWithoutBorders.getTitleAuthorSeparator() + bookMetadata.getAuthor();
|
bookMetadata.getTitle() + BooksWithoutBordersConfig.getTitleAuthorSeparator() + bookMetadata.getAuthor();
|
||||||
|
|
||||||
fileName = cleanString(fileName);
|
fileName = cleanString(fileName);
|
||||||
fileName = fixName(fileName, false);
|
fileName = fixName(fileName, false);
|
||||||
@ -281,7 +282,7 @@ public final class EncryptionHelper {
|
|||||||
bookMetadata.setLore(newLore);
|
bookMetadata.setLore(newLore);
|
||||||
|
|
||||||
//Save file
|
//Save file
|
||||||
File file = (BooksWithoutBorders.getUseYml()) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt");
|
File file = (BooksWithoutBordersConfig.getUseYml()) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt");
|
||||||
if (!file.isFile()) {
|
if (!file.isFile()) {
|
||||||
try {
|
try {
|
||||||
BookToFromTextHelper.bookToYml(path, fileName, bookMetadata);
|
BookToFromTextHelper.bookToYml(path, fileName, bookMetadata);
|
||||||
@ -306,14 +307,14 @@ 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 = (!bookMetaData.hasTitle()) ? "Untitled," + player.getName() :
|
String fileName = (!bookMetaData.hasTitle()) ? "Untitled," + player.getName() :
|
||||||
bookMetaData.getTitle() + BooksWithoutBorders.getTitleAuthorSeparator() + bookMetaData.getAuthor();
|
bookMetaData.getTitle() + BooksWithoutBordersConfig.getTitleAuthorSeparator() + bookMetaData.getAuthor();
|
||||||
|
|
||||||
fileName = "[" + key + "]" + fileName;
|
fileName = "[" + key + "]" + fileName;
|
||||||
fileName = cleanString(fileName);
|
fileName = cleanString(fileName);
|
||||||
fileName = fixName(fileName, false);
|
fileName = fixName(fileName, false);
|
||||||
|
|
||||||
//cancels saving if file is already encrypted
|
//cancels saving if file is already encrypted
|
||||||
File file = (BooksWithoutBorders.getUseYml()) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt");
|
File file = (BooksWithoutBordersConfig.getUseYml()) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt");
|
||||||
if (file.isFile()) {
|
if (file.isFile()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,8 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersSettings.getSlash;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
26
src/main/resources/config.yml
Normal file
26
src/main/resources/config.yml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Options:
|
||||||
|
# Whether to use YAML for saved books instead of just storing them as text
|
||||||
|
Save_Books_in_Yaml_Format: true
|
||||||
|
# The maximum number of duplicates of a saved book allowed
|
||||||
|
Max_Number_of_Duplicates: 5
|
||||||
|
# The separator used to separate the book title and the book author
|
||||||
|
Title-Author_Separator: ","
|
||||||
|
# The separator used to denote a new line in the book lore
|
||||||
|
Lore_line_separator: "~"
|
||||||
|
# A list of books given to new players the first time they join the server
|
||||||
|
Books_for_new_players: [ ]
|
||||||
|
# An optional message displayed to new players the first time they join the server
|
||||||
|
Message_for_new_players: ""
|
||||||
|
# Price settings for book copying
|
||||||
|
Price_to_create_book:
|
||||||
|
# The item type used as currency for copying books. Use "Economy" to use money instead of items
|
||||||
|
Item_type: ""
|
||||||
|
# The quantity of currency required to pay for each book produced
|
||||||
|
Required_quantity: 0
|
||||||
|
# Whether any admin can decrypt any book regardless of the group it was encrypted for
|
||||||
|
Admin_Auto_Decrypt: false
|
||||||
|
# Whether to only allow the author of a book to create copies
|
||||||
|
Author_Only_Copy: false
|
||||||
|
# Whether to automatically format every book when it's signed
|
||||||
|
Format_Book_After_Signing: false
|
||||||
|
|
@ -13,6 +13,14 @@ commands:
|
|||||||
description: Lists Books Without Borders's commands and uses.
|
description: Lists Books Without Borders's commands and uses.
|
||||||
aliases: [ bwb ]
|
aliases: [ bwb ]
|
||||||
usage: /<command>
|
usage: /<command>
|
||||||
|
decryptbook:
|
||||||
|
description: Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used to encrypt held book
|
||||||
|
usage: /<command> <key>
|
||||||
|
permission: bookswithoutborders.decrypt
|
||||||
|
formatbook:
|
||||||
|
description: Replaces color/formatting codes in a written book with formatted text
|
||||||
|
usage: /<command>
|
||||||
|
permission: bookswithoutborders.format
|
||||||
givebook:
|
givebook:
|
||||||
description: Gives the selected player a book from your personal directory
|
description: Gives the selected player a book from your personal directory
|
||||||
usage: /<command> <file name or number> <playername> [# of copies (num)] [signed (true/false)]
|
usage: /<command> <file name or number> <playername> [# of copies (num)] [signed (true/false)]
|
||||||
@ -21,10 +29,6 @@ commands:
|
|||||||
description: Same as givebook, but uses books from the public directory
|
description: Same as givebook, but uses books from the public directory
|
||||||
usage: /<command> <file name or number> <playername> [# of copies (num)] [signed (true/false)]
|
usage: /<command> <file name or number> <playername> [# of copies (num)] [signed (true/false)]
|
||||||
permission: bookswithoutborders.givepublic
|
permission: bookswithoutborders.givepublic
|
||||||
decryptbook:
|
|
||||||
description: Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used to encrypt held book
|
|
||||||
usage: /<command> <key>
|
|
||||||
permission: bookswithoutborders.decrypt
|
|
||||||
groupencryptbook:
|
groupencryptbook:
|
||||||
description: Encrypts book so that only players with the bookswithoutborders.decrypt.<group name> permission may decrypt the book by holding and left clicking the book
|
description: Encrypts book so that only players with the bookswithoutborders.decrypt.<group name> permission may decrypt the book by holding and left clicking the book
|
||||||
usage: /<command> <group name> <key> [encryption style]
|
usage: /<command> <group name> <key> [encryption style]
|
||||||
@ -85,10 +89,6 @@ commands:
|
|||||||
description: Reloads BwB's configuration file
|
description: Reloads BwB's configuration file
|
||||||
usage: /<command>
|
usage: /<command>
|
||||||
permission: bookswithoutborders.admin
|
permission: bookswithoutborders.admin
|
||||||
formatbook:
|
|
||||||
description: Replaces color/formatting codes in a book with formatted text
|
|
||||||
usage: /<command>
|
|
||||||
permission: bookswithoutborders.format
|
|
||||||
permissions:
|
permissions:
|
||||||
bookswithoutborders.*:
|
bookswithoutborders.*:
|
||||||
description: Grants all permissions
|
description: Grants all permissions
|
||||||
@ -100,29 +100,33 @@ permissions:
|
|||||||
default: op
|
default: op
|
||||||
children:
|
children:
|
||||||
bookswithoutborders.use: true
|
bookswithoutborders.use: true
|
||||||
bookswithoutborders.unsign: true
|
bookswithoutborders.alterbooks: true
|
||||||
bookswithoutborders.copy: true
|
bookswithoutborders.copy: true
|
||||||
bookswithoutborders.loadpublic: true
|
bookswithoutborders.loadpublic: true
|
||||||
bookswithoutborders.savepublic: true
|
bookswithoutborders.savepublic: true
|
||||||
bookswithoutborders.encrypt: true
|
bookswithoutborders.encrypt: true
|
||||||
bookswithoutborders.decrypt: true
|
bookswithoutborders.decrypt: true
|
||||||
|
bookswithoutborders.groupencrypt: true
|
||||||
bookswithoutborders.signs: true
|
bookswithoutborders.signs: true
|
||||||
bookswithoutborders.give: true
|
bookswithoutborders.give: true
|
||||||
bookswithoutborders.givepublic: true
|
bookswithoutborders.givepublic: true
|
||||||
bookswithoutborders.settitle: true
|
|
||||||
bookswithoutborders.setauthor: true
|
|
||||||
bookswithoutborders.setlore: true
|
|
||||||
bookswithoutborders.bypassauthoronlycopy: true
|
bookswithoutborders.bypassauthoronlycopy: true
|
||||||
bookswithoutborders.bypassbookprice: true
|
bookswithoutborders.bypassbookprice: true
|
||||||
bookswithoutborders.groupencrypt: true
|
|
||||||
bookswithoutborders.setbookprice: true
|
bookswithoutborders.setbookprice: true
|
||||||
bookswithoutborders.format: true
|
|
||||||
bookswithoutborders.use:
|
bookswithoutborders.use:
|
||||||
description: Allows player to use commands and to save/load/delete in their personal directory
|
description: Allows player to use commands and to save/load/delete in their personal directory
|
||||||
children:
|
children:
|
||||||
bookswithoutborders.save: true
|
bookswithoutborders.save: true
|
||||||
bookswithoutborders.load: true
|
bookswithoutborders.load: true
|
||||||
bookswithoutborders.delete: true
|
bookswithoutborders.delete: true
|
||||||
|
bookswithoutborders.alterbooks:
|
||||||
|
description: Allows player to change books' data such as lore/title/author/formatting and unsigning books
|
||||||
|
children:
|
||||||
|
bookswithoutborders.unsign: true
|
||||||
|
bookswithoutborders.settitle: true
|
||||||
|
bookswithoutborders.setauthor: true
|
||||||
|
bookswithoutborders.setlore: true
|
||||||
|
bookswithoutborders.format: 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:
|
||||||
|
Loading…
Reference in New Issue
Block a user