Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
af0b0fd12e | |||
a963733734 | |||
7dd201d0d0 | |||
a95d737414 | |||
0ce85af61b | |||
ed54ae84b5 | |||
27d5980fa8 | |||
544f6f69fe | |||
055d7fca60 | |||
8f7cfc591f | |||
2aa25295af | |||
d423b1e109 | |||
7acaa9fc81 | |||
94589faba0 |
75
README.md
75
README.md
@ -25,28 +25,95 @@ Books without Borders has got your back!
|
|||||||
* Configurable option to require certain items or pay via Vault compatible economy to create books via command
|
* Configurable option to require certain items or pay via Vault compatible economy to create books via command
|
||||||
* Add lore to any item with a simple command
|
* Add lore to any item with a simple command
|
||||||
* Supports adding and saving color to title, lore, and book contents
|
* Supports adding and saving color to title, lore, and book contents
|
||||||
|
* Color and formatting codes can be manually turned into formatting using /formatbook
|
||||||
|
* Formatting and color codes can be turned into formatting once any book is signed. This is enabled through a config
|
||||||
|
value
|
||||||
|
|
||||||
#### Group encryption
|
#### Group encryption
|
||||||
|
|
||||||
* Group encryption allows every player with the bookswithoutborders.decrypt.\<group> permission to decrypt the encrypted
|
* Group encryption allows every player with the bookswithoutborders.decrypt.\<group> permission to decrypt the encrypted
|
||||||
book without using a password.
|
book without using a password.
|
||||||
|
|
||||||
|
### Commands:
|
||||||
|
|
||||||
|
An in-game description of available commands is available through the /bwb command.
|
||||||
|
|
||||||
|
* /bookswithoutborders - Displays information about commands (and permissions if the user has bookswithoutborders.admin)
|
||||||
|
* /copybook <# of copies> - Copies the book the player is holding
|
||||||
|
* /decryptbook <key> - Decrypts the book the player is holding. "key" is required and MUST be IDENTICAL to the key used
|
||||||
|
to encrypt the held book
|
||||||
|
* /deletebook <file name or number> - Deletes the specified file in the player's directory
|
||||||
|
* /deletepublicbook <file name or number> - Same as deletebook, but deletes files in the public directory
|
||||||
|
* encryptbook <key> \[encryption style] - Encrypts the book the player is holding. "key" is required and can be any
|
||||||
|
phrase or number excluding spaces. "style" is not required. Possible values are "DNA" or ""
|
||||||
|
* /formatbook - Formats the held written book (converts color and formatting codes to the corresponding formatted text)
|
||||||
|
* /givebook <file name or number> <playername> \[# of copies (num)] \[signed (true/false)] - Gives the selected player a
|
||||||
|
book from your personal directory
|
||||||
|
* /givepublicbook <file name or number> <playername> \[# of copies (num)] \[signed (true/false)] - Same as givebook, but
|
||||||
|
uses books from the public directory
|
||||||
|
* /loadbook <file name or number> \[# of copies] \[signed (true/false)] - Creates a book from the specified file and
|
||||||
|
gives it to the player. If no file is specified, a list of available files is returned. If true is specified, the book
|
||||||
|
will be signed, if false it will be unsigned
|
||||||
|
* /loadpublicbook <file name or number> \[# of copies] \[signed (true/false)] - Same as loadbook, but views files in the
|
||||||
|
public directory
|
||||||
|
* /reload - Reloads BwB's configuration file
|
||||||
|
* /savebook \[overwrite (true/false)] - Saves the book the player is holding to a text file in a private directory. If
|
||||||
|
true is specified, a book of the same name by the same author will be overwritten by the new book
|
||||||
|
* /savepublicbook \[overwrite (true/false)] - Same as savebook, but saves files in the public directory
|
||||||
|
* /setbookauthor <author> - Sets the author of the book the player is holding
|
||||||
|
* /setbookprice <item/eco> <quantity> - Sets the per-book price to create a book via commands. If "Item", the item in
|
||||||
|
the player's hand in the amount of <quantity> will be the price. If "Eco", a Vault based economy will be used for
|
||||||
|
price. If neither <Item/Eco> nor <quantity> are specified, the current price to create books will be removed.
|
||||||
|
* /setlore <new lore> - Sets the lore of the item the player is holding. Insert the lore_line_separator character to
|
||||||
|
force a new line ("~" by default)
|
||||||
|
* /settitle <title> - Sets the title of the book/item the player is holding
|
||||||
|
* /unsignbook - Un-signs the book the player is holding
|
||||||
|
|
||||||
|
### Permissions:
|
||||||
|
|
||||||
|
* bookswithoutborders.* - Grants all permissions
|
||||||
|
* bookswithoutborders.admin - Grants all permissions
|
||||||
|
* bookswithoutborders.use - Allows player to use commands to save/load/delete in their personal directory
|
||||||
|
* bookswithoutborders.alterbooks - Allows player to change books' data such as lore/title/author/formatting and
|
||||||
|
unsigning books
|
||||||
|
* bookswithoutborders.format - Allows a player to format a book
|
||||||
|
* bookswithoutborders.save - Allows a player to save books to their personal directory
|
||||||
|
* bookswithoutborders.load - Allows player to load books from their personal directory
|
||||||
|
* bookswithoutborders.delete - Allows player to delete books from their personal directory
|
||||||
|
* bookswithoutborders.unsign - Allows player to un-sign books
|
||||||
|
* bookswithoutborders.copy - Allows player to copy books
|
||||||
|
* bookswithoutborders.loadpublic - Allows player to load from the public directory
|
||||||
|
* bookswithoutborders.savepublic - Allows player to save to the public directory
|
||||||
|
* bookswithoutborders.encrypt - Allows player to encrypt books
|
||||||
|
* bookswithoutborders.groupencrypt - Allows player to use group-based encryption
|
||||||
|
* bookswithoutborders.decrypt - Allows player to decrypt books
|
||||||
|
* bookswithoutborders.decrypt.agroup - Allows player to decrypt books group-encrypted for group "agroup"
|
||||||
|
* bookswithoutborders.signs - Allows player to create signs that give/encrypt/decrypt books
|
||||||
|
* bookswithoutborders.give - Allows player to give another player one of their privately saved books
|
||||||
|
* bookswithoutborders.givepublic - Allows a player to give another player a book from the public directory
|
||||||
|
* bookswithoutborders.settitle - Allows player to set the title of the currently held book
|
||||||
|
* bookswithoutborders.setauthor - Allows player to set the author of the currently held book
|
||||||
|
* bookswithoutborders.setlore - Allows player to set the lore of the currently held item
|
||||||
|
* bookswithoutborders.bypassauthoronlycopy - Allows player to ignore Author_Only_Copy config setting
|
||||||
|
* bookswithoutborders.bypassbookprice - Allows player to ignore Price_to_create_book config setting
|
||||||
|
* bookswithoutborders-setbookprice - Allows player to set the cost of creating a book
|
||||||
|
|
||||||
### Signs
|
### Signs
|
||||||
|
|
||||||
This plugin supports several custom signs with special functionality. Each plugin sign must have [BwB] on its first
|
This plugin supports several custom signs with special functionality. Each plugin sign must have \[BwB] on its first
|
||||||
line.
|
line.
|
||||||
|
|
||||||
#### Give sign
|
#### Give sign
|
||||||
|
|
||||||
The **_give_** sign must have **[Give]** on its second line. The third and fourth line contains the book to be loaded.
|
The **_give_** sign must have **\[Give]** on its second line. The third and fourth line contains the book to be loaded.
|
||||||
This can either be a numerical id pointing to a publicly saved book, or the full text identifier of the book (book name,
|
This can either be a numerical id pointing to a publicly saved book, or the full text identifier of the book (book name,
|
||||||
author).
|
author).
|
||||||
|
|
||||||
#### Encrypt sign
|
#### Encrypt sign
|
||||||
|
|
||||||
The **_encrypt_** sign must have **[Encrypt]** on its second line. The third line must contain the encryption key The
|
The **_encrypt_** sign must have **\[Encrypt]** on its second line. The third line must contain the encryption key The
|
||||||
fourth line can be empty or contain "dna" for dna-based encryption.
|
fourth line can be empty or contain "dna" for dna-based encryption.
|
||||||
|
|
||||||
#### Decrypt sign
|
#### Decrypt sign
|
||||||
|
|
||||||
The **_decrypt_** sign must have **[Decrypt]** on its second line. The third line must contain the decryption key
|
The **_decrypt_** sign must have **\[Decrypt]** on its second line. The third line must contain the decryption key
|
16
pom.xml
16
pom.xml
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>net.knarcraft</groupId>
|
<groupId>net.knarcraft</groupId>
|
||||||
<artifactId>BooksWithoutBorders</artifactId>
|
<artifactId>BooksWithoutBorders</artifactId>
|
||||||
<version>1.0</version>
|
<version>1.2.3</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<licenses>
|
<licenses>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<description>A continuation of the original Books Without Borders</description>
|
<description>A continuation of the original Books Without Borders</description>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>16</java.version>
|
<java.version>17</java.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
@ -31,8 +31,8 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>${java.version}</source>
|
<source>17</source>
|
||||||
<target>${java.version}</target>
|
<target>17</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
@ -75,7 +75,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot-api</artifactId>
|
<artifactId>spigot-api</artifactId>
|
||||||
<version>1.17.1-R0.1-SNAPSHOT</version>
|
<version>1.19.1-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -84,5 +84,11 @@
|
|||||||
<version>1.7</version>
|
<version>1.7</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains</groupId>
|
||||||
|
<artifactId>annotations</artifactId>
|
||||||
|
<version>23.0.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -6,6 +6,7 @@ import net.knarcraft.bookswithoutborders.command.CommandDecrypt;
|
|||||||
import net.knarcraft.bookswithoutborders.command.CommandDelete;
|
import net.knarcraft.bookswithoutborders.command.CommandDelete;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandDeletePublic;
|
import net.knarcraft.bookswithoutborders.command.CommandDeletePublic;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandEncrypt;
|
import net.knarcraft.bookswithoutborders.command.CommandEncrypt;
|
||||||
|
import net.knarcraft.bookswithoutborders.command.CommandFormat;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandGive;
|
import net.knarcraft.bookswithoutborders.command.CommandGive;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandGivePublic;
|
import net.knarcraft.bookswithoutborders.command.CommandGivePublic;
|
||||||
import net.knarcraft.bookswithoutborders.command.CommandGroupEncrypt;
|
import net.knarcraft.bookswithoutborders.command.CommandGroupEncrypt;
|
||||||
@ -19,22 +20,19 @@ 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.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 net.knarcraft.bookswithoutborders.utility.UpdateChecker;
|
||||||
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.plugin.PluginDescriptionFile;
|
||||||
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;
|
||||||
|
|
||||||
@ -44,25 +42,16 @@ 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.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getErrorColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getErrorColor;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSuccessColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSuccessColor;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main Books Without Borders class
|
||||||
|
*/
|
||||||
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;
|
||||||
@ -115,11 +104,18 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
FileConfiguration config = this.getConfig();
|
||||||
|
config.options().copyDefaults(true);
|
||||||
|
this.saveDefaultConfig();
|
||||||
|
|
||||||
|
//Get plugin info
|
||||||
|
PluginDescriptionFile pluginDescriptionFile = this.getDescription();
|
||||||
|
String pluginVersion = pluginDescriptionFile.getVersion();
|
||||||
|
|
||||||
booksWithoutBorders = this;
|
booksWithoutBorders = this;
|
||||||
consoleSender = this.getServer().getConsoleSender();
|
consoleSender = this.getServer().getConsoleSender();
|
||||||
playerBooksList = new HashMap<>();
|
playerBooksList = new HashMap<>();
|
||||||
firstBooks = new ArrayList<>();
|
BooksWithoutBordersConfig.initialize(this);
|
||||||
BooksWithoutBordersSettings.initialize(this);
|
|
||||||
publicBooksList = FileHelper.listFiles(consoleSender, true);
|
publicBooksList = FileHelper.listFiles(consoleSender, true);
|
||||||
|
|
||||||
PluginManager pluginManager = this.getServer().getPluginManager();
|
PluginManager pluginManager = this.getServer().getPluginManager();
|
||||||
@ -127,125 +123,15 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerCommands();
|
registerCommands();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
UpdateChecker.checkForUpdate(this, "https://api.spigotmc.org/legacy/update.php?resource=96069",
|
||||||
* Gets whether only the author of a book should be able to copy it
|
() -> pluginVersion, null);
|
||||||
*
|
|
||||||
* @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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -280,6 +166,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
registerCommand("loadPublicBook", new CommandLoadPublic());
|
registerCommand("loadPublicBook", new CommandLoadPublic());
|
||||||
registerCommand("booksWithoutBorders", new CommandBooksWithoutBorders());
|
registerCommand("booksWithoutBorders", new CommandBooksWithoutBorders());
|
||||||
registerCommand("reload", new CommandReload());
|
registerCommand("reload", new CommandReload());
|
||||||
|
registerCommand("formatBook", new CommandFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -299,6 +186,7 @@ public class BooksWithoutBorders extends JavaPlugin {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the plugin, loading and fixing the config file
|
* Initializes the plugin, loading and fixing the config file
|
||||||
|
*
|
||||||
* @return <p>True if successful</p>
|
* @return <p>True if successful</p>
|
||||||
*/
|
*/
|
||||||
private boolean initialize() {
|
private boolean initialize() {
|
||||||
@ -313,16 +201,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
|
||||||
*
|
*
|
||||||
@ -356,215 +253,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"));
|
|
||||||
}
|
|
||||||
if (firstBooks.isEmpty()) {
|
|
||||||
firstBooks.add(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
*
|
*
|
||||||
@ -585,13 +273,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,77 +0,0 @@
|
|||||||
package net.knarcraft.bookswithoutborders;
|
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for getting various settings
|
|
||||||
*/
|
|
||||||
public class BooksWithoutBordersSettings {
|
|
||||||
|
|
||||||
//Static settings
|
|
||||||
private static final ChatColor errorColor = ChatColor.RED;
|
|
||||||
private static final ChatColor successColor = ChatColor.GREEN;
|
|
||||||
private static final ChatColor commandColor = ChatColor.YELLOW;
|
|
||||||
private static final String SLASH = System.getProperty("file.separator");
|
|
||||||
private static boolean isInitialized;
|
|
||||||
public static String bookFolder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the books without borders settings class
|
|
||||||
*
|
|
||||||
* @param booksWithoutBorders <p>The books without borders object used for getting required data</p>
|
|
||||||
*/
|
|
||||||
public static void initialize(BooksWithoutBorders booksWithoutBorders) {
|
|
||||||
if (isInitialized) {
|
|
||||||
throw new IllegalArgumentException("Settings class initialized twice. This should not happen!");
|
|
||||||
}
|
|
||||||
isInitialized = true;
|
|
||||||
bookFolder = booksWithoutBorders.getDataFolder().getAbsolutePath() + getSlash() + "Books" + getSlash();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the folder used for storing books
|
|
||||||
*
|
|
||||||
* @return <p>The folder used for storing books</p>
|
|
||||||
*/
|
|
||||||
public static String getBookFolder() {
|
|
||||||
return bookFolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the color to use for error messages
|
|
||||||
*
|
|
||||||
* @return <p>The color to use for error messages</p>
|
|
||||||
*/
|
|
||||||
public static ChatColor getErrorColor() {
|
|
||||||
return errorColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the color to use for success messages
|
|
||||||
*
|
|
||||||
* @return <p>The color to use for success messages</p>
|
|
||||||
*/
|
|
||||||
public static ChatColor getSuccessColor() {
|
|
||||||
return successColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the color used to color commands
|
|
||||||
*
|
|
||||||
* @return <p>The color used to color commands</p>
|
|
||||||
*/
|
|
||||||
public static ChatColor getCommandColor() {
|
|
||||||
return commandColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the correct slash to use for the used OS
|
|
||||||
*
|
|
||||||
* @return <p>The slash to use for file separators</p>
|
|
||||||
*/
|
|
||||||
public static String getSlash() {
|
|
||||||
return SLASH;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -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;
|
||||||
@ -8,25 +9,25 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
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.BooksWithoutBordersConfig.getCommandColor;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSuccessColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.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, Command command, String label, 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);
|
||||||
@ -43,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,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]");
|
||||||
@ -68,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,15 +101,19 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, 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.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;
|
||||||
@ -11,6 +12,7 @@ import org.bukkit.command.TabExecutor;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -21,10 +23,8 @@ 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(CommandSender sender, Command command, String label, 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)) {
|
||||||
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
return false;
|
return false;
|
||||||
@ -45,12 +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;
|
||||||
@ -86,11 +87,12 @@ public class CommandCopy implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
int argumentCount = args.length;
|
int argumentCount = args.length;
|
||||||
if (argumentCount == 1) {
|
if (argumentCount == 1) {
|
||||||
return TabCompletionHelper.getNumbers(1, 20);
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getNumbers(1, 20), args[0]);
|
||||||
}
|
}
|
||||||
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.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;
|
||||||
@ -9,13 +10,14 @@ import org.bukkit.command.TabExecutor;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.File;
|
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.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command executor for the decrypt command
|
* Command executor for the decrypt command
|
||||||
@ -23,7 +25,7 @@ import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getS
|
|||||||
public class CommandDecrypt implements TabExecutor {
|
public class CommandDecrypt implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, 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)) {
|
||||||
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
return false;
|
return false;
|
||||||
@ -43,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();
|
||||||
}
|
}
|
||||||
@ -102,7 +104,7 @@ public class CommandDecrypt implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
int argumentCount = args.length;
|
int argumentCount = args.length;
|
||||||
if (argumentCount == 1) {
|
if (argumentCount == 1) {
|
||||||
List<String> info = new ArrayList<>();
|
List<String> info = new ArrayList<>();
|
||||||
@ -111,4 +113,5 @@ public class CommandDecrypt implements TabExecutor {
|
|||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,19 @@ package net.knarcraft.bookswithoutborders.command;
|
|||||||
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
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 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;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.File;
|
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.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command executor for the delete command
|
* Command executor for the delete command
|
||||||
@ -21,7 +23,7 @@ import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getS
|
|||||||
public class CommandDelete implements TabExecutor {
|
public class CommandDelete implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
if (!(sender instanceof Player)) {
|
if (!(sender instanceof Player)) {
|
||||||
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
return false;
|
return false;
|
||||||
@ -107,12 +109,13 @@ public class CommandDelete implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
return doTabCompletion(sender, args, false);
|
return doTabCompletion(sender, args, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs tab completion
|
* Performs tab completion
|
||||||
|
*
|
||||||
* @param sender <p>The sender of the command</p>
|
* @param sender <p>The sender of the command</p>
|
||||||
* @param args <p>The arguments given</p>
|
* @param args <p>The arguments given</p>
|
||||||
* @param deletePublic <p>Whether to delete a public book</p>
|
* @param deletePublic <p>Whether to delete a public book</p>
|
||||||
@ -121,7 +124,8 @@ public class CommandDelete implements TabExecutor {
|
|||||||
protected List<String> doTabCompletion(CommandSender sender, String[] args, boolean deletePublic) {
|
protected List<String> doTabCompletion(CommandSender sender, String[] args, boolean deletePublic) {
|
||||||
int argumentCount = args.length;
|
int argumentCount = args.length;
|
||||||
if (argumentCount == 1) {
|
if (argumentCount == 1) {
|
||||||
return BooksWithoutBorders.getAvailableBooks(sender, deletePublic);
|
return TabCompletionHelper.filterMatchingContains(BooksWithoutBorders.getAvailableBooks(sender, deletePublic),
|
||||||
|
args[0]);
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.knarcraft.bookswithoutborders.command;
|
|||||||
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;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -12,12 +13,12 @@ import java.util.List;
|
|||||||
public class CommandDeletePublic extends CommandDelete implements TabExecutor {
|
public class CommandDeletePublic extends CommandDelete implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||||
return deleteBook(sender, args, true);
|
return deleteBook(sender, args, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
return doTabCompletion(sender, args, true);
|
return doTabCompletion(sender, args, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,14 @@ import net.knarcraft.bookswithoutborders.state.EncryptionStyle;
|
|||||||
import net.knarcraft.bookswithoutborders.state.ItemSlot;
|
import net.knarcraft.bookswithoutborders.state.ItemSlot;
|
||||||
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 net.knarcraft.bookswithoutborders.utility.TabCompletionHelper;
|
||||||
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;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -21,7 +23,7 @@ import java.util.List;
|
|||||||
public class CommandEncrypt implements TabExecutor {
|
public class CommandEncrypt implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
if (performPreChecks(sender, args, 1, "You must specify a key to encrypt a book!") == null) {
|
if (performPreChecks(sender, args, 1, "You must specify a key to encrypt a book!") == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -96,12 +98,13 @@ public class CommandEncrypt implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
return doTabCompletion(args, false);
|
return doTabCompletion(args, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a list of string for tab completions
|
* Gets a list of string for tab completions
|
||||||
|
*
|
||||||
* @param args <p>The arguments given</p>
|
* @param args <p>The arguments given</p>
|
||||||
* @param groupEncrypt <p>Whether to auto-complete for group encryption</p>
|
* @param groupEncrypt <p>Whether to auto-complete for group encryption</p>
|
||||||
* @return <p>The strings to auto-complete</p>
|
* @return <p>The strings to auto-complete</p>
|
||||||
@ -123,12 +126,13 @@ public class CommandEncrypt implements TabExecutor {
|
|||||||
info.add("<group>");
|
info.add("<group>");
|
||||||
return info;
|
return info;
|
||||||
} else {
|
} else {
|
||||||
return encryptionStyles;
|
return TabCompletionHelper.filterMatchingStartsWith(encryptionStyles, args[1]);
|
||||||
}
|
}
|
||||||
} else if (argumentsCount == 3 && groupEncrypt) {
|
} else if (argumentsCount == 3 && groupEncrypt) {
|
||||||
return encryptionStyles;
|
return TabCompletionHelper.filterMatchingStartsWith(encryptionStyles, args[2]);
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.command;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.BookFormatter;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.InventoryHelper;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabExecutor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A command for converting color codes to color formatting
|
||||||
|
*/
|
||||||
|
public class CommandFormat implements TabExecutor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
|
if (!(sender instanceof Player player)) {
|
||||||
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InventoryHelper.notHoldingOneWrittenBookCheck(player, "You must be holding a written book to format it!",
|
||||||
|
"You cannot format two books at once!")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack heldBook = InventoryHelper.getHeldBook(player, true);
|
||||||
|
heldBook.setItemMeta(BookFormatter.formatPages((BookMeta) heldBook.getItemMeta()));
|
||||||
|
|
||||||
|
BooksWithoutBorders.sendSuccessMessage(sender, "Book formatted!");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
|
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;
|
||||||
@ -10,6 +11,7 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -22,7 +24,7 @@ public class CommandGive implements TabExecutor {
|
|||||||
private final BooksWithoutBorders booksWithoutBorders = BooksWithoutBorders.getInstance();
|
private final BooksWithoutBorders booksWithoutBorders = BooksWithoutBorders.getInstance();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
if (!(sender instanceof Player)) {
|
if (!(sender instanceof Player)) {
|
||||||
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
return false;
|
return false;
|
||||||
@ -87,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!");
|
||||||
@ -104,12 +106,13 @@ public class CommandGive implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
return doTabCompletion(sender, args, false);
|
return doTabCompletion(sender, args, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the actual tab completion
|
* Performs the actual tab completion
|
||||||
|
*
|
||||||
* @param sender <p>The sender of the command</p>
|
* @param sender <p>The sender of the command</p>
|
||||||
* @param args <p>The arguments given</p>
|
* @param args <p>The arguments given</p>
|
||||||
* @param listPublic <p>Whether to list public files or player files</p>
|
* @param listPublic <p>Whether to list public files or player files</p>
|
||||||
@ -129,22 +132,24 @@ public class CommandGive implements TabExecutor {
|
|||||||
|
|
||||||
if (argumentCount == 1) {
|
if (argumentCount == 1) {
|
||||||
//Return list of books
|
//Return list of books
|
||||||
return BooksWithoutBorders.getAvailableBooks(sender, listPublic);
|
return TabCompletionHelper.filterMatchingContains(BooksWithoutBorders.getAvailableBooks(sender, listPublic),
|
||||||
|
args[0]);
|
||||||
} else if (argumentCount == 2) {
|
} else if (argumentCount == 2) {
|
||||||
//Return online players
|
//Return online players
|
||||||
return null;
|
return null;
|
||||||
} else if (argumentCount == 3) {
|
} else if (argumentCount == 3) {
|
||||||
//Number of copies
|
//Number of copies
|
||||||
return TabCompletionHelper.getBooleansAndNumbers(1, 3);
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleansAndNumbers(1, 3), args[2]);
|
||||||
} else if (argumentCount == 4) {
|
} else if (argumentCount == 4) {
|
||||||
//Signed
|
//Signed
|
||||||
try {
|
try {
|
||||||
Integer.parseInt(args[2]);
|
Integer.parseInt(args[2]);
|
||||||
return TabCompletionHelper.getBooleans();
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleans(), args[3]);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.knarcraft.bookswithoutborders.command;
|
|||||||
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;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -12,12 +13,12 @@ import java.util.List;
|
|||||||
public class CommandGivePublic extends CommandGive implements TabExecutor {
|
public class CommandGivePublic extends CommandGive implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||||
return giveBook(sender, args, true, "public");
|
return giveBook(sender, args, true, "public");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
return doTabCompletion(sender, args, true);
|
return doTabCompletion(sender, args, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ import java.util.List;
|
|||||||
public class CommandGroupEncrypt extends CommandEncrypt implements TabExecutor {
|
public class CommandGroupEncrypt extends CommandEncrypt implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||||
BookMeta bookMetadata = performPreChecks(sender, args, 2,
|
BookMeta bookMetadata = performPreChecks(sender, args, 2,
|
||||||
"You must specify a group name and key to encrypt a book!");
|
"You must specify a group name and key to encrypt a book!");
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ public class CommandGroupEncrypt extends CommandEncrypt implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
return doTabCompletion(args, true);
|
return doTabCompletion(args, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
@ -9,6 +10,7 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -18,10 +20,8 @@ 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(CommandSender sender, Command command, String label, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,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!");
|
||||||
@ -94,12 +94,13 @@ public class CommandLoad implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
return doTabCompletion(sender, args, false);
|
return doTabCompletion(sender, args, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the actual tab completion
|
* Performs the actual tab completion
|
||||||
|
*
|
||||||
* @param sender <p>The sender of the command</p>
|
* @param sender <p>The sender of the command</p>
|
||||||
* @param args <p>The arguments given</p>
|
* @param args <p>The arguments given</p>
|
||||||
* @param loadPublic <p>Whether to list public files or player files</p>
|
* @param loadPublic <p>Whether to list public files or player files</p>
|
||||||
@ -109,19 +110,21 @@ public class CommandLoad implements TabExecutor {
|
|||||||
int argumentCount = args.length;
|
int argumentCount = args.length;
|
||||||
if (argumentCount == 1) {
|
if (argumentCount == 1) {
|
||||||
//Return list of books
|
//Return list of books
|
||||||
return BooksWithoutBorders.getAvailableBooks(sender, loadPublic);
|
return TabCompletionHelper.filterMatchingContains(BooksWithoutBorders.getAvailableBooks(sender, loadPublic),
|
||||||
|
args[0]);
|
||||||
} else if (argumentCount == 2) {
|
} else if (argumentCount == 2) {
|
||||||
//Number of copies
|
//Number of copies
|
||||||
return TabCompletionHelper.getBooleansAndNumbers(1, 3);
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleansAndNumbers(1, 3), args[1]);
|
||||||
} else if (argumentCount == 3) {
|
} else if (argumentCount == 3) {
|
||||||
//Signed
|
//Signed
|
||||||
try {
|
try {
|
||||||
Integer.parseInt(args[1]);
|
Integer.parseInt(args[1]);
|
||||||
return TabCompletionHelper.getBooleans();
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getBooleans(), args[2]);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.knarcraft.bookswithoutborders.command;
|
|||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -12,12 +13,12 @@ import java.util.List;
|
|||||||
public class CommandLoadPublic extends CommandLoad implements CommandExecutor {
|
public class CommandLoadPublic extends CommandLoad implements CommandExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||||
return loadBook(sender, args, "public", true);
|
return loadBook(sender, args, "public", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
return doTabCompletion(sender, args, true);
|
return doTabCompletion(sender, args, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
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;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -13,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(CommandSender sender, Command command, String label, 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!");
|
||||||
@ -27,7 +27,8 @@ public class CommandReload implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, 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.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;
|
||||||
@ -11,17 +12,17 @@ import org.bukkit.command.TabExecutor;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
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.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getCommandColor;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getCommandColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getErrorColor;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getErrorColor;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.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;
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixN
|
|||||||
public class CommandSave implements TabExecutor {
|
public class CommandSave implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||||
return saveHeldBook(sender, args, false);
|
return saveHeldBook(sender, args, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ public class CommandSave implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ItemSlot holdingSlot = InventoryHelper.getHeldSlotBook(player, false, false, false, false);
|
ItemSlot holdingSlot = InventoryHelper.getHeldSlotBook(player, false, false, false, false);
|
||||||
if (holdingSlot != ItemSlot.NONE) {
|
if (holdingSlot != null && holdingSlot != ItemSlot.NONE) {
|
||||||
ItemStack holdingItem = InventoryHelper.getHeldItem(player, holdingSlot == ItemSlot.MAIN_HAND);
|
ItemStack holdingItem = InventoryHelper.getHeldItem(player, holdingSlot == ItemSlot.MAIN_HAND);
|
||||||
boolean duplicate = args.length == 1 && Boolean.parseBoolean(args[0]);
|
boolean duplicate = args.length == 1 && Boolean.parseBoolean(args[0]);
|
||||||
saveBook(player, holdingItem, duplicate, savePublic);
|
saveBook(player, holdingItem, duplicate, savePublic);
|
||||||
@ -88,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);
|
||||||
@ -119,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;
|
||||||
@ -132,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);
|
||||||
@ -148,7 +149,8 @@ public class CommandSave implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package net.knarcraft.bookswithoutborders.command;
|
|||||||
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;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command executor for the save public command
|
* Command executor for the save public command
|
||||||
@ -10,7 +11,7 @@ import org.bukkit.command.TabExecutor;
|
|||||||
public class CommandSavePublic extends CommandSave implements TabExecutor {
|
public class CommandSavePublic extends CommandSave implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
return saveHeldBook(sender, args, true);
|
return saveHeldBook(sender, args, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import org.bukkit.command.TabExecutor;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -19,7 +20,7 @@ import java.util.List;
|
|||||||
public class CommandSetAuthor implements TabExecutor {
|
public class CommandSetAuthor implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, 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)) {
|
||||||
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
return false;
|
return false;
|
||||||
@ -49,11 +50,12 @@ public class CommandSetAuthor implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
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.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;
|
||||||
@ -10,6 +11,7 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -20,9 +22,10 @@ import java.util.List;
|
|||||||
public class CommandSetBookPrice implements TabExecutor {
|
public class CommandSetBookPrice implements TabExecutor {
|
||||||
|
|
||||||
private final BooksWithoutBorders booksWithoutBorders = BooksWithoutBorders.getInstance();
|
private final BooksWithoutBorders booksWithoutBorders = BooksWithoutBorders.getInstance();
|
||||||
|
private List<String> paymentTypes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||||
//Clear the current price
|
//Clear the current price
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
clearItemPrice(sender);
|
clearItemPrice(sender);
|
||||||
@ -65,10 +68,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!");
|
||||||
@ -93,10 +96,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();
|
||||||
@ -115,9 +118,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();
|
||||||
@ -132,16 +135,27 @@ public class CommandSetBookPrice implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
|
if (paymentTypes == null) {
|
||||||
|
initializeTabCompleteLists();
|
||||||
|
}
|
||||||
|
|
||||||
int argumentCount = args.length;
|
int argumentCount = args.length;
|
||||||
if (argumentCount == 1) {
|
if (argumentCount == 1) {
|
||||||
List<String> paymentTypes = new ArrayList<>();
|
return TabCompletionHelper.filterMatchingStartsWith(paymentTypes, args[0]);
|
||||||
paymentTypes.add("item");
|
|
||||||
paymentTypes.add("eco");
|
|
||||||
return paymentTypes;
|
|
||||||
} else if (argumentCount == 2) {
|
} else if (argumentCount == 2) {
|
||||||
return TabCompletionHelper.getNumbers(1, 3);
|
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getNumbers(1, 3), args[1]);
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the lists of tab complete values
|
||||||
|
*/
|
||||||
|
private void initializeTabCompleteLists() {
|
||||||
|
paymentTypes = new ArrayList<>();
|
||||||
|
paymentTypes.add("item");
|
||||||
|
paymentTypes.add("eco");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
@ -10,6 +11,7 @@ import org.bukkit.command.TabExecutor;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -21,7 +23,7 @@ import java.util.List;
|
|||||||
public class CommandSetLore implements TabExecutor {
|
public class CommandSetLore implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, 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)) {
|
||||||
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
return false;
|
return false;
|
||||||
@ -43,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
|
||||||
@ -59,10 +61,11 @@ public class CommandSetLore implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||||
//TODO: Figure out if there is a better way to display that an argument is required
|
//TODO: Figure out if there is a better way to display that an argument is required
|
||||||
List<String> options = new ArrayList<>();
|
List<String> options = new ArrayList<>();
|
||||||
options.add("<new lore>");
|
options.add("<new lore>");
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -21,7 +22,7 @@ import java.util.List;
|
|||||||
public class CommandSetTitle implements TabExecutor {
|
public class CommandSetTitle implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, 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)) {
|
||||||
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
return false;
|
return false;
|
||||||
@ -65,9 +66,10 @@ public class CommandSetTitle implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
List<String> options = new ArrayList<>();
|
List<String> options = new ArrayList<>();
|
||||||
options.add("<new title>");
|
options.add("<new title>");
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import org.bukkit.command.TabExecutor;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.BookMeta;
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -20,7 +21,7 @@ import java.util.List;
|
|||||||
public class CommandUnSign implements TabExecutor {
|
public class CommandUnSign implements TabExecutor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, 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)) {
|
||||||
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
BooksWithoutBorders.sendErrorMessage(sender, "This command can only be used by a player!");
|
||||||
return false;
|
return false;
|
||||||
@ -55,7 +56,8 @@ public class CommandUnSign implements TabExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,341 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.config;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A config class that keeps track of all config values
|
||||||
|
*/
|
||||||
|
public class BooksWithoutBordersConfig {
|
||||||
|
|
||||||
|
private static final ChatColor errorColor = ChatColor.RED;
|
||||||
|
private static final ChatColor successColor = ChatColor.GREEN;
|
||||||
|
private static final ChatColor commandColor = ChatColor.YELLOW;
|
||||||
|
private static final String SLASH = System.getProperty("file.separator");
|
||||||
|
private static boolean isInitialized;
|
||||||
|
public static String bookFolder;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the books without borders settings class
|
||||||
|
*
|
||||||
|
* @param booksWithoutBorders <p>The books without borders object used for getting required data</p>
|
||||||
|
*/
|
||||||
|
public static void initialize(BooksWithoutBorders booksWithoutBorders) {
|
||||||
|
if (isInitialized) {
|
||||||
|
throw new IllegalArgumentException("Settings class initialized twice. This should not happen!");
|
||||||
|
}
|
||||||
|
isInitialized = true;
|
||||||
|
bookFolder = booksWithoutBorders.getDataFolder().getAbsolutePath() + getSlash() + "Books" + getSlash();
|
||||||
|
loadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the folder used for storing books
|
||||||
|
*
|
||||||
|
* @return <p>The folder used for storing books</p>
|
||||||
|
*/
|
||||||
|
public static String getBookFolder() {
|
||||||
|
return bookFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the color to use for error messages
|
||||||
|
*
|
||||||
|
* @return <p>The color to use for error messages</p>
|
||||||
|
*/
|
||||||
|
public static ChatColor getErrorColor() {
|
||||||
|
return errorColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the color to use for success messages
|
||||||
|
*
|
||||||
|
* @return <p>The color to use for success messages</p>
|
||||||
|
*/
|
||||||
|
public static ChatColor getSuccessColor() {
|
||||||
|
return successColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the color used to color commands
|
||||||
|
*
|
||||||
|
* @return <p>The color used to color commands</p>
|
||||||
|
*/
|
||||||
|
public static ChatColor getCommandColor() {
|
||||||
|
return commandColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the correct slash to use for the used OS
|
||||||
|
*
|
||||||
|
* @return <p>The slash to use for file separators</p>
|
||||||
|
*/
|
||||||
|
public static String getSlash() {
|
||||||
|
return SLASH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,8 +14,6 @@ public class GenenCrypt {
|
|||||||
|
|
||||||
private final Random ranGen;
|
private final Random ranGen;
|
||||||
private final String[] bases;
|
private final String[] bases;
|
||||||
private final ArrayList<String> originalCodonList;
|
|
||||||
private final ArrayList<String> shuffledCodonList;
|
|
||||||
private final String[] charList;
|
private final String[] charList;
|
||||||
private final HashMap<String, String[]> codonTable;
|
private final HashMap<String, String[]> codonTable;
|
||||||
private final HashMap<String, String> decryptTable;
|
private final HashMap<String, String> decryptTable;
|
||||||
@ -29,7 +27,7 @@ public class GenenCrypt {
|
|||||||
public GenenCrypt(String key) {
|
public GenenCrypt(String key) {
|
||||||
|
|
||||||
// define the initial, unshuffled codon list of 4 base codons
|
// define the initial, unshuffled codon list of 4 base codons
|
||||||
originalCodonList = new ArrayList<>();
|
ArrayList<String> originalCodonList = new ArrayList<>();
|
||||||
bases = new String[]{"A", "T", "G", "C"};
|
bases = new String[]{"A", "T", "G", "C"};
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
@ -50,7 +48,7 @@ public class GenenCrypt {
|
|||||||
ranGen = new java.util.Random(longKey);
|
ranGen = new java.util.Random(longKey);
|
||||||
|
|
||||||
// use the random number generator and the originalCodonList to make a shuffled list
|
// use the random number generator and the originalCodonList to make a shuffled list
|
||||||
shuffledCodonList = new ArrayList<>();
|
ArrayList<String> shuffledCodonList = new ArrayList<>();
|
||||||
while (originalCodonList.size() > 0) {
|
while (originalCodonList.size() > 0) {
|
||||||
int index = ranGen.nextInt(originalCodonList.size());
|
int index = ranGen.nextInt(originalCodonList.size());
|
||||||
shuffledCodonList.add(originalCodonList.get(index));
|
shuffledCodonList.add(originalCodonList.get(index));
|
||||||
@ -90,24 +88,6 @@ public class GenenCrypt {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints the shuffled codon list used for generating the codon table
|
|
||||||
*/
|
|
||||||
public void printShuffledList() {
|
|
||||||
for (String s : shuffledCodonList) {
|
|
||||||
System.out.println(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints the original codon list before it was shuffled
|
|
||||||
*/
|
|
||||||
public void printOriginalList() {
|
|
||||||
for (String s : originalCodonList) {
|
|
||||||
System.out.println(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints the codon table used for encryption and decryption
|
* Prints the codon table used for encryption and decryption
|
||||||
*/
|
*/
|
||||||
@ -181,4 +161,5 @@ public class GenenCrypt {
|
|||||||
}
|
}
|
||||||
return output.toString();
|
return output.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ package net.knarcraft.bookswithoutborders.encryption;
|
|||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple substitution cipher
|
||||||
|
*/
|
||||||
public class SubstitutionCipher {
|
public class SubstitutionCipher {
|
||||||
|
|
||||||
public SubstitutionCipher() {
|
public SubstitutionCipher() {
|
||||||
@ -83,5 +86,6 @@ public class SubstitutionCipher {
|
|||||||
}
|
}
|
||||||
return output.toString();
|
return output.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,9 +18,12 @@ 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.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A listener for listening to player-related events such as joining or holding a book
|
||||||
|
*/
|
||||||
public class PlayerEventListener implements Listener {
|
public class PlayerEventListener implements Listener {
|
||||||
|
|
||||||
private final String slash = getSlash();
|
private final String slash = getSlash();
|
||||||
@ -58,7 +63,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 +93,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 +148,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 +163,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,10 +24,13 @@ 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.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.FileHelper.isBookListIndex;
|
import static net.knarcraft.bookswithoutborders.utility.FileHelper.isBookListIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A listener for relevant sign events such as clicking a decryption sign
|
||||||
|
*/
|
||||||
public class SignEventListener implements Listener {
|
public class SignEventListener implements Listener {
|
||||||
|
|
||||||
private final String slash = getSlash();
|
private final String slash = getSlash();
|
||||||
@ -84,6 +89,9 @@ public class SignEventListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ItemStack heldItem = playerInventory.getItem(hand);
|
ItemStack heldItem = playerInventory.getItem(hand);
|
||||||
|
if (heldItem == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Material heldItemType = heldItem.getType();
|
Material heldItemType = heldItem.getType();
|
||||||
|
|
||||||
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && (Tag.SIGNS.isTagged(clickedBlockType) ||
|
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && (Tag.SIGNS.isTagged(clickedBlockType) ||
|
||||||
@ -234,11 +242,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 +257,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 +312,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);
|
||||||
|
@ -4,8 +4,20 @@ package net.knarcraft.bookswithoutborders.state;
|
|||||||
* This enum represents the different directories books can be saved in
|
* This enum represents the different directories books can be saved in
|
||||||
*/
|
*/
|
||||||
public enum BookDirectory {
|
public enum BookDirectory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The public directory
|
||||||
|
*/
|
||||||
PUBLIC,
|
PUBLIC,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A player directory
|
||||||
|
*/
|
||||||
PLAYER,
|
PLAYER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The encrypted directory
|
||||||
|
*/
|
||||||
ENCRYPTED;
|
ENCRYPTED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,4 +37,5 @@ public enum BookDirectory {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ package net.knarcraft.bookswithoutborders.state;
|
|||||||
* This enum represents the different available encryption styles
|
* This enum represents the different available encryption styles
|
||||||
*/
|
*/
|
||||||
public enum EncryptionStyle {
|
public enum EncryptionStyle {
|
||||||
|
|
||||||
DNA("dna"),
|
DNA("dna"),
|
||||||
SUBSTITUTION("substitution");
|
SUBSTITUTION("substitution");
|
||||||
|
|
||||||
@ -27,4 +28,5 @@ public enum EncryptionStyle {
|
|||||||
}
|
}
|
||||||
return SUBSTITUTION;
|
return SUBSTITUTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
@ -8,7 +15,6 @@ import java.util.List;
|
|||||||
public final class BookFormatter {
|
public final class BookFormatter {
|
||||||
|
|
||||||
private BookFormatter() {
|
private BookFormatter() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,4 +100,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,134 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.utility;
|
||||||
|
|
||||||
|
import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
||||||
|
import net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper class for loading books from files
|
||||||
|
*/
|
||||||
|
public final class BookLoader {
|
||||||
|
|
||||||
|
private 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 = BooksWithoutBordersConfig.getSlash();
|
||||||
|
String bookFolder = BooksWithoutBordersConfig.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;
|
||||||
@ -21,7 +22,6 @@ public final class EconomyHelper {
|
|||||||
private static Economy economy;
|
private static Economy economy;
|
||||||
|
|
||||||
private EconomyHelper() {
|
private EconomyHelper() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,8 +67,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 +116,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.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.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;
|
||||||
|
|
||||||
@ -27,7 +28,6 @@ import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.fixN
|
|||||||
public final class EncryptionHelper {
|
public final class EncryptionHelper {
|
||||||
|
|
||||||
private EncryptionHelper() {
|
private EncryptionHelper() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,7 +199,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 +265,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 +281,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 +306,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;
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,18 @@ import net.knarcraft.bookswithoutborders.BooksWithoutBorders;
|
|||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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.BooksWithoutBordersConfig.getBookFolder;
|
||||||
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSlash;
|
import static net.knarcraft.bookswithoutborders.config.BooksWithoutBordersConfig.getSlash;
|
||||||
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.cleanString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,7 +24,6 @@ import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.clea
|
|||||||
public final class FileHelper {
|
public final class FileHelper {
|
||||||
|
|
||||||
private FileHelper() {
|
private FileHelper() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -123,6 +126,9 @@ public final class FileHelper {
|
|||||||
*/
|
*/
|
||||||
public static void printFiles(CommandSender sender, List<String> fileList) {
|
public static void printFiles(CommandSender sender, List<String> fileList) {
|
||||||
BooksWithoutBorders.sendSuccessMessage(sender, "Available Books:");
|
BooksWithoutBorders.sendSuccessMessage(sender, "Available Books:");
|
||||||
|
if (fileList == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int listSize = fileList.size();
|
int listSize = fileList.size();
|
||||||
for (int fileIndex = 0; fileIndex < listSize; fileIndex++) {
|
for (int fileIndex = 0; fileIndex < listSize; fileIndex++) {
|
||||||
sender.sendMessage(ChatColor.GRAY + "[" + (fileIndex + 1) + "] " + fileList.get(fileIndex));
|
sender.sendMessage(ChatColor.GRAY + "[" + (fileIndex + 1) + "] " + fileList.get(fileIndex));
|
||||||
@ -171,4 +177,15 @@ public final class FileHelper {
|
|||||||
return foundDuplicates;
|
return foundDuplicates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a buffered reader given an input stream
|
||||||
|
*
|
||||||
|
* @param inputStream <p>The input stream to read</p>
|
||||||
|
* @return <p>A buffered reader reading the input stream</p>
|
||||||
|
*/
|
||||||
|
public static BufferedReader getBufferedReaderFromInputStream(InputStream inputStream) {
|
||||||
|
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
|
||||||
|
return new BufferedReader(inputStreamReader);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import java.util.List;
|
|||||||
public final class InputCleaningHelper {
|
public final class InputCleaningHelper {
|
||||||
|
|
||||||
private InputCleaningHelper() {
|
private InputCleaningHelper() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,7 +14,6 @@ import org.bukkit.inventory.meta.BookMeta;
|
|||||||
public final class InventoryHelper {
|
public final class InventoryHelper {
|
||||||
|
|
||||||
private InventoryHelper() {
|
private InventoryHelper() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,7 +96,7 @@ public final class InventoryHelper {
|
|||||||
if (state == BookHoldingState.SIGNED_BOTH_HANDS ||
|
if (state == BookHoldingState.SIGNED_BOTH_HANDS ||
|
||||||
state == BookHoldingState.UNSIGNED_BOTH_HANDS ||
|
state == BookHoldingState.UNSIGNED_BOTH_HANDS ||
|
||||||
state == BookHoldingState.NONE) {
|
state == BookHoldingState.NONE) {
|
||||||
return null;
|
return ItemSlot.NONE;
|
||||||
}
|
}
|
||||||
if (handMatters && typeMatters) {
|
if (handMatters && typeMatters) {
|
||||||
if (mainHand && mainHandItem.getType() == requiredMaterial) {
|
if (mainHand && mainHandItem.getType() == requiredMaterial) {
|
||||||
|
@ -9,7 +9,40 @@ import java.util.List;
|
|||||||
public final class TabCompletionHelper {
|
public final class TabCompletionHelper {
|
||||||
|
|
||||||
private TabCompletionHelper() {
|
private TabCompletionHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds tab complete values that contain the typed text
|
||||||
|
*
|
||||||
|
* @param values <p>The values to filter</p>
|
||||||
|
* @param typedText <p>The text the player has started typing</p>
|
||||||
|
* @return <p>The given string values that contain the player's typed text</p>
|
||||||
|
*/
|
||||||
|
public static List<String> filterMatchingContains(List<String> values, String typedText) {
|
||||||
|
List<String> configValues = new ArrayList<>();
|
||||||
|
for (String value : values) {
|
||||||
|
if (value.toLowerCase().contains(typedText.toLowerCase())) {
|
||||||
|
configValues.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return configValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds tab complete values that match the start of the typed text
|
||||||
|
*
|
||||||
|
* @param values <p>The values to filter</p>
|
||||||
|
* @param typedText <p>The text the player has started typing</p>
|
||||||
|
* @return <p>The given string values that start with the player's typed text</p>
|
||||||
|
*/
|
||||||
|
public static List<String> filterMatchingStartsWith(List<String> values, String typedText) {
|
||||||
|
List<String> configValues = new ArrayList<>();
|
||||||
|
for (String value : values) {
|
||||||
|
if (value.toLowerCase().startsWith(typedText.toLowerCase())) {
|
||||||
|
configValues.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return configValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,92 @@
|
|||||||
|
package net.knarcraft.bookswithoutborders.utility;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.scheduler.BukkitScheduler;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The update checker is responsible for looking for new updates
|
||||||
|
*/
|
||||||
|
public final class UpdateChecker {
|
||||||
|
|
||||||
|
private final static String updateNotice = "A new update is available: %s (You are still on %s)";
|
||||||
|
|
||||||
|
private UpdateChecker() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if there's a new update available, and alerts the user if necessary
|
||||||
|
*/
|
||||||
|
public static void checkForUpdate(Plugin plugin, String apiResourceURL, Supplier<String> getVersionMethod,
|
||||||
|
Consumer<String> setVersionMethod) {
|
||||||
|
BukkitScheduler scheduler = plugin.getServer().getScheduler();
|
||||||
|
scheduler.runTaskAsynchronously(plugin, () -> UpdateChecker.queryAPI(plugin, apiResourceURL, getVersionMethod,
|
||||||
|
setVersionMethod));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries the spigot API to check for a newer version, and informs the user
|
||||||
|
*/
|
||||||
|
private static void queryAPI(Plugin plugin, String APIResourceURL, Supplier<String> getVersionMethod,
|
||||||
|
Consumer<String> setVersionMethod) {
|
||||||
|
try {
|
||||||
|
InputStream inputStream = new URL(APIResourceURL).openStream();
|
||||||
|
BufferedReader reader = FileHelper.getBufferedReaderFromInputStream(inputStream);
|
||||||
|
//There should only be one line of output
|
||||||
|
String newVersion = reader.readLine();
|
||||||
|
reader.close();
|
||||||
|
|
||||||
|
String oldVersion = getVersionMethod.get();
|
||||||
|
//If there is a newer version, notify the user
|
||||||
|
if (isVersionHigher(oldVersion, newVersion)) {
|
||||||
|
plugin.getLogger().log(Level.INFO, getUpdateAvailableString(newVersion, oldVersion));
|
||||||
|
if (setVersionMethod != null) {
|
||||||
|
setVersionMethod.accept(newVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
plugin.getLogger().log(Level.WARNING, "Unable to get newest version.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the string to display to a user to alert about a new update
|
||||||
|
*
|
||||||
|
* @param newVersion <p>The new available plugin version</p>
|
||||||
|
* @param oldVersion <p>The old (current) plugin version</p>
|
||||||
|
* @return <p>The string to display</p>
|
||||||
|
*/
|
||||||
|
public static String getUpdateAvailableString(String newVersion, String oldVersion) {
|
||||||
|
return String.format(updateNotice, newVersion, oldVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decides whether one version number is higher than another
|
||||||
|
*
|
||||||
|
* @param oldVersion <p>The old version to check</p>
|
||||||
|
* @param newVersion <p>The new version to check</p>
|
||||||
|
* @return <p>True if the new version is higher than the old one</p>
|
||||||
|
*/
|
||||||
|
public static boolean isVersionHigher(String oldVersion, String newVersion) {
|
||||||
|
String[] oldVersionParts = oldVersion.split("\\.");
|
||||||
|
String[] newVersionParts = newVersion.split("\\.");
|
||||||
|
int versionLength = Math.max(oldVersionParts.length, newVersionParts.length);
|
||||||
|
for (int i = 0; i < versionLength; i++) {
|
||||||
|
int oldVersionNumber = oldVersionParts.length > i ? Integer.parseInt(oldVersionParts[i]) : 0;
|
||||||
|
int newVersionNumber = newVersionParts.length > i ? Integer.parseInt(newVersionParts[i]) : 0;
|
||||||
|
if (newVersionNumber != oldVersionNumber) {
|
||||||
|
return newVersionNumber > oldVersionNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
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
|
||||||
|
|
@ -1,18 +1,26 @@
|
|||||||
name: BooksWithoutBorders
|
name: BooksWithoutBorders
|
||||||
version: '${project.version}'
|
version: '${project.version}'
|
||||||
main: net.knarcraft.bookswithoutborders.BooksWithoutBorders
|
main: net.knarcraft.bookswithoutborders.BooksWithoutBorders
|
||||||
api-version: 1.17
|
api-version: 1.18
|
||||||
prefix: Books Without Borders
|
prefix: Books Without Borders
|
||||||
authors: [ EpicKnarvik97, AkiraAkiba ]
|
authors: [ EpicKnarvik97, AkiraAkiba ]
|
||||||
description: A continuation of the original Books Without Borders
|
description: A continuation of the original Books Without Borders
|
||||||
softdepend: [ Vault ]
|
softdepend: [ Vault ]
|
||||||
website: ????
|
website: https://www.spigotmc.org/resources/books-without-borders-updated.96069/
|
||||||
dev-url: https://git.knarcraft.net/EpicKnarvik97/Books-Without-Borders
|
dev-url: https://git.knarcraft.net/EpicKnarvik97/Books-Without-Borders
|
||||||
commands:
|
commands:
|
||||||
bookswithoutborders:
|
bookswithoutborders:
|
||||||
description: Lists Books Without Borders's commands and uses.
|
description: Lists Books Without Borders'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]
|
||||||
@ -50,11 +54,11 @@ commands:
|
|||||||
usage: /<command> <key> [encryption style]
|
usage: /<command> <key> [encryption style]
|
||||||
permission: bookswithoutborders.encrypt
|
permission: bookswithoutborders.encrypt
|
||||||
setbookprice:
|
setbookprice:
|
||||||
description: Sets the per-book-price to create a book via commands. If "Item", the item in the player's hand in the amount of [quantity] will be the price. If "Eco", a Vault based economy will be used for price. If neither <Item/Eco> or <quantity> are specified the current price to create books will be removed.
|
description: Sets the per-book-price to create a book via commands. If "Item", the item in the player's hand in the amount of [quantity] will be the price. If "Eco", a Vault based economy will be used for price. If neither <Item/Eco> or <quantity> are specified, the current price to create books will be removed.
|
||||||
usage: /<command> <item/eco> <quantity>
|
usage: /<command> <item/eco> <quantity>
|
||||||
permission: bookswithoutborders.setbookprice
|
permission: bookswithoutborders.setbookprice
|
||||||
setlore:
|
setlore:
|
||||||
description: Sets the lore of the item the player is holding. Insert the lore_line_separator character to force a new line ("~" by default).
|
description: Sets the lore of the item the player is holding. Insert the lore_line_separator character to force a new line ("~" by default)
|
||||||
usage: /<command> <new lore>
|
usage: /<command> <new lore>
|
||||||
permission: bookswithoutborders.setlore
|
permission: bookswithoutborders.setlore
|
||||||
savepublicbook:
|
savepublicbook:
|
||||||
@ -74,7 +78,7 @@ commands:
|
|||||||
usage: /<command> <title>
|
usage: /<command> <title>
|
||||||
permission: bookswithoutborders.settitle
|
permission: bookswithoutborders.settitle
|
||||||
loadbook:
|
loadbook:
|
||||||
description: Creates a book from the specified file and gives it to the player. If no file is specified, a list of available files is returned. If true is specified the book will be signed, if false it will be unsigned
|
description: Creates a book from the specified file and gives it to the player. If no file is specified, a list of available files is returned. If true is specified, the book will be signed, if false it will be unsigned
|
||||||
usage: /<command> <file name or number> [# of copies] [signed (true/false)]
|
usage: /<command> <file name or number> [# of copies] [signed (true/false)]
|
||||||
permission: bookswithoutborders.load
|
permission: bookswithoutborders.load
|
||||||
loadpublicbook:
|
loadpublicbook:
|
||||||
@ -96,28 +100,35 @@ 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.use:
|
bookswithoutborders.use:
|
||||||
description: Allows player to use commands and to save/load/delete in their personal directory
|
description: Allows player to use commands 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:
|
||||||
|
description: Allows a player to format a book
|
||||||
bookswithoutborders.save:
|
bookswithoutborders.save:
|
||||||
description: Allows player to save books to their personal directory
|
description: Allows player to save books to their personal directory
|
||||||
bookswithoutborders.load:
|
bookswithoutborders.load:
|
||||||
@ -129,13 +140,13 @@ permissions:
|
|||||||
bookswithoutborders.copy:
|
bookswithoutborders.copy:
|
||||||
description: Allows player to use copy command
|
description: Allows player to use copy command
|
||||||
bookswithoutborders.loadpublic:
|
bookswithoutborders.loadpublic:
|
||||||
description: Allows player to load in the public directory
|
description: Allows player to load from the public directory
|
||||||
bookswithoutborders.savepublic:
|
bookswithoutborders.savepublic:
|
||||||
description: Allows player to save in the public directory
|
description: Allows player to save to the public directory
|
||||||
bookswithoutborders.encrypt:
|
bookswithoutborders.encrypt:
|
||||||
description: Allows player to encrypt books
|
description: Allows player to encrypt books
|
||||||
bookswithoutborders.groupencrypt:
|
bookswithoutborders.groupencrypt:
|
||||||
description: Allows player to set group based encryption
|
description: Allows player to use group-based encryption
|
||||||
bookswithoutborders.decrypt:
|
bookswithoutborders.decrypt:
|
||||||
description: Allows player to decrypt books
|
description: Allows player to decrypt books
|
||||||
bookswithoutborders.signs:
|
bookswithoutborders.signs:
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package net.knarcraft.bookswithoutborders.encryption;
|
package net.knarcraft.bookswithoutborders.encryption;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static junit.framework.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
|
|
||||||
public class AESTest {
|
public class AESTest {
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ public class AESTest {
|
|||||||
AES aes = new AES(AES.generateIV(), AES.generateIV());
|
AES aes = new AES(AES.generateIV(), AES.generateIV());
|
||||||
|
|
||||||
String encrypted = aes.encryptDecryptText(plainText, password, true);
|
String encrypted = aes.encryptDecryptText(plainText, password, true);
|
||||||
assertFalse(encrypted.equals(plainText));
|
Assert.assertNotSame(encrypted, plainText);
|
||||||
String decrypted = aes.encryptDecryptText(encrypted, password, false);
|
String decrypted = aes.encryptDecryptText(encrypted, password, false);
|
||||||
assertEquals(plainText, decrypted);
|
assertEquals(plainText, decrypted);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user