Improves encapsulation and removes the custom tracking of existing players

This commit is contained in:
Kristian Knarvik 2021-09-04 01:06:01 +02:00
parent 1d3c50aab1
commit 0ca4b9817e
13 changed files with 133 additions and 140 deletions

View File

@ -17,7 +17,7 @@ Books without Borders has got your back!
* Import books from files as written books or unsigned books
* Text files can be any length, and the import process fits the content to the correct page length
* Books can be saved privately, or to a directory visible server wide
* Encrypt books to secure their contents [[Courtesy of dorrax]](http://dev.bukkit.org/profiles/dorrax/)
* Encrypt books to prevent other players from reading them
* Give, encrypt, or decrypt held books with signs
* Give players books via command blocks
* Unsign or copy held books with a simple command

View File

@ -26,7 +26,6 @@ import net.knarcraft.bookswithoutborders.utility.BookToFromTextHelper;
import net.knarcraft.bookswithoutborders.utility.EconomyHelper;
import net.knarcraft.bookswithoutborders.utility.FileHelper;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
@ -41,12 +40,7 @@ import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -62,33 +56,30 @@ import static net.knarcraft.bookswithoutborders.utility.InputCleaningHelper.clea
public class BooksWithoutBorders extends JavaPlugin {
//Limit for duplicates of a book
public static int bookDuplicateLimit;
private static int bookDuplicateLimit;
//The separating string between the book title and the book author
public static String titleAuthorSeparator;
private static String titleAuthorSeparator;
//Separator to force Lore newline
public static String loreSeparator;
private static String loreSeparator;
//Books to give players on first login
public static List<String> firstBooks;
private static List<String> firstBooks;
//Message to display to new players
public static String welcomeMessage;
//List of players
public static List<String> existingPlayers;
private static String welcomeMessage;
//The material used for payment
public static Material bookPriceType = null;
private static Material bookPriceType = null;
//The number of items/currency to pay for each transaction
public static double bookPriceQuantity;
private static double bookPriceQuantity;
//Whether only the author of a book should be allowed to copy the book
public static boolean authorOnlyCopy;
private static boolean authorOnlyCopy;
//Whether to use YML files instead of TXT files for saving books
public static boolean useYml;
private static boolean useYml;
//Whether admins should be able to decrypt group encrypted books without belonging to its group
public static boolean adminDecrypt;
private static boolean adminDecrypt;
private static ItemFactory itemFactory;
public static Map<String, List<String>> loadList;
private static BooksWithoutBorders booksWithoutBorders;
public static ConsoleCommandSender consoleSender;
private static String existingPlayersFile;
@Override
public void onEnable() {
@ -98,8 +89,6 @@ public class BooksWithoutBorders extends JavaPlugin {
firstBooks = new ArrayList<>();
BooksWithoutBordersSettings.initialize(this);
existingPlayersFile = this.getDataFolder().getAbsolutePath() + getSlash() + "Existing Players.txt";
PluginManager pluginManager = this.getServer().getPluginManager();
if (getSlash() != null && initialize()) {
@ -112,6 +101,78 @@ public class BooksWithoutBorders extends JavaPlugin {
registerCommands();
}
public static boolean getAuthorOnlyCopy() {
return authorOnlyCopy;
}
public static boolean getUseYml() {
return useYml;
}
public static boolean getAdminDecrypt() {
return adminDecrypt;
}
public static void setBookPriceQuantity(double newQuantity) {
bookPriceQuantity = newQuantity;
}
public static double getBookPriceQuantity() {
return bookPriceQuantity;
}
public static void setBookPriceType(Material newType) {
bookPriceType = newType;
}
public static Material getBookPriceType() {
return bookPriceType;
}
/**
* Gets the welcome message to show to new players
* @return <p>The welcome message to show new players</p>
*/
public static String getWelcomeMessage() {
return welcomeMessage;
}
/**
* Gets the limit of duplicates for each book
* @return <p>The book duplicate limit</p>
*/
public static int getBookDuplicateLimit() {
return bookDuplicateLimit;
}
/**
* Gets the separator used to split book title from book author
* @return <p>The separator between title and author</p>
*/
public static String getTitleAuthorSeparator() {
return titleAuthorSeparator;
}
/**
* Gets the separator used to denote a newline in a lore string
* @return <p>The separator used to denote lore newline</p>
*/
public static String getLoreSeparator() {
return loreSeparator;
}
/**
* Gets a copy of the list of books to give new players
* @return <p>The books to give new players</p>
*/
public static List<String> getFirstBooks() {
return new ArrayList<>(firstBooks);
}
/**
* Gets an instance of this plugin
* @return <p>An instance of this plugin</p>
*/
public static BooksWithoutBorders getInstance() {
return booksWithoutBorders;
}
@ -178,11 +239,7 @@ public class BooksWithoutBorders extends JavaPlugin {
//Save config with loaded values to fix invalid config values
saveConfigValues();
if (!testFileSaving()) {
return false;
}
return loadExistingPlayers();
return testFileSaving();
}
/**
@ -311,61 +368,6 @@ public class BooksWithoutBorders extends JavaPlugin {
return true;
}
public boolean loadExistingPlayers() {
File fTest = new File(existingPlayersFile);
existingPlayers = new ArrayList<>();
if (!fTest.exists()) {
try {
if (!fTest.createNewFile()) {
sendErrorMessage(consoleSender, "Could not create Existing Players file! Aborting...");
return false;
}
PrintWriter pw = new PrintWriter(new FileWriter(fTest));
OfflinePlayer[] players = this.getServer().getOfflinePlayers();
for (OfflinePlayer player : players) {
existingPlayers.add(player.getName());
}
for (String player : existingPlayers) {
pw.println(player);
}
pw.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
} else {
try {
BufferedReader br = new BufferedReader(new FileReader(fTest));
String nullCheck = br.readLine();
while (nullCheck != null) {
existingPlayers.add(nullCheck);
nullCheck = br.readLine();
}
br.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
return true;
}
public void addExistingPlayer(String playerName) {
existingPlayers.add(playerName);
try {
PrintWriter pw = new PrintWriter(new FileWriter(existingPlayersFile, true));
pw.println(playerName);
pw.close();
} catch (IOException e) {
sendErrorMessage(consoleSender, "Failed to add " + playerName + " to Existing Players list");
}
}
public ItemStack loadBook(CommandSender sender, String fileName, String isSigned, String dir) {
return loadBook(sender, fileName, isSigned, dir, 1);
}

View File

@ -9,8 +9,6 @@ import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.bookPriceQuantity;
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.bookPriceType;
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.sendErrorMessage;
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getCommandColor;
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getSuccessColor;
@ -54,11 +52,15 @@ public class CommandBooksWithoutBorders implements CommandExecutor {
*/
private void showPlayerCommands(CommandSender sender) {
//Lists all commands
Material bookPriceType = BooksWithoutBorders.getBookPriceType();
double bookPriceQuantity = BooksWithoutBorders.getBookPriceQuantity();
if (booksWithoutBorders.booksHavePrice()) {
if (bookPriceType != Material.AIR) {
sendErrorMessage(sender, "[" + (int) bookPriceQuantity + " " + bookPriceType.toString() + "(s) are required to create a book]");
sendErrorMessage(sender, "[" + (int) bookPriceQuantity + " " + bookPriceType.toString() +
"(s) are required to create a book]");
} else {
sendErrorMessage(sender, "[" + EconomyHelper.getEconomy().format(bookPriceQuantity) + " is required to create a book]");
sendErrorMessage(sender, "[" + EconomyHelper.getEconomy().format(bookPriceQuantity) +
" is required to create a book]");
}
}
sender.sendMessage(getCommandColor() + "Commands:");

View File

@ -41,7 +41,7 @@ public class CommandCopy implements CommandExecutor {
try {
int copies = Integer.parseInt(args[0]);
if (copies > 0) {
if (BooksWithoutBorders.authorOnlyCopy && !player.hasPermission("bookswithoutborders.bypassAuthorOnlyCopy")) {
if (BooksWithoutBorders.getAuthorOnlyCopy() && !player.hasPermission("bookswithoutborders.bypassAuthorOnlyCopy")) {
if (!isAuthor(player, (BookMeta) Objects.requireNonNull(heldBook.getItemMeta())))
return false;
}

View File

@ -41,11 +41,11 @@ public class CommandDecrypt implements CommandExecutor {
}
//Warning: admin decrypt only allows decrypting files created by the same player. Not sure if intended
if (args.length == 0 && BooksWithoutBorders.adminDecrypt && player.hasPermission("bookswithoutborders.admin")) {
if (args.length == 0 && BooksWithoutBorders.getAdminDecrypt() && player.hasPermission("bookswithoutborders.admin")) {
String path = getBookFolder() + "Encrypted" + getSlash();
String fileName;
if (bookMetadata.hasTitle()) {
fileName = bookMetadata.getTitle() + BooksWithoutBorders.titleAuthorSeparator + bookMetadata.getAuthor();
fileName = bookMetadata.getTitle() + BooksWithoutBorders.getTitleAuthorSeparator() + bookMetadata.getAuthor();
} else {
fileName = "Untitled," + player.getName();
}

View File

@ -14,7 +14,7 @@ public class CommandReload implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (booksWithoutBorders.loadConfig() && booksWithoutBorders.loadExistingPlayers()) {
if (booksWithoutBorders.loadConfig()) {
BooksWithoutBorders.sendSuccessMessage(sender, "BooksWithoutBorders configuration reloaded!");
} else {
BooksWithoutBorders.sendErrorMessage(sender, "Reload Failed!");

View File

@ -15,7 +15,7 @@ import org.bukkit.inventory.meta.BookMeta;
import java.io.File;
import java.io.IOException;
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.titleAuthorSeparator;
import static net.knarcraft.bookswithoutborders.BooksWithoutBorders.getTitleAuthorSeparator;
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getBookFolder;
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getCommandColor;
import static net.knarcraft.bookswithoutborders.BooksWithoutBordersSettings.getErrorColor;
@ -86,7 +86,7 @@ public class CommandSave implements CommandExecutor {
if (!book.hasTitle()) {
fileName = "Untitled," + player.getName();
} else {
fileName = book.getTitle() + titleAuthorSeparator + book.getAuthor();
fileName = book.getTitle() + getTitleAuthorSeparator() + book.getAuthor();
}
fileName = cleanString(fileName);
fileName = fixName(fileName, false);
@ -117,7 +117,7 @@ public class CommandSave implements CommandExecutor {
}
//Skip if duplicate limit is reached
if (foundDuplicates > BooksWithoutBorders.bookDuplicateLimit) {
if (foundDuplicates > BooksWithoutBorders.getBookDuplicateLimit()) {
BooksWithoutBorders.sendErrorMessage(player, "Maximum amount of " + fileName + " duplicates reached!");
BooksWithoutBorders.sendErrorMessage(player, "Use " + getCommandColor() + "/bwb Save true " + getErrorColor() + "to overwrite!");
return;
@ -130,7 +130,7 @@ public class CommandSave implements CommandExecutor {
}
try {
if (BooksWithoutBorders.useYml) {
if (BooksWithoutBorders.getUseYml()) {
BookToFromTextHelper.bookToYml(savePath, fileName, book);
} else {
BookToFromTextHelper.bookToTXT(savePath, fileName, book);

View File

@ -61,10 +61,10 @@ public class CommandSetBookPrice implements CommandExecutor {
* @param sender <p>The sender of the command</p>
*/
private void clearItemPrice(CommandSender sender) {
BooksWithoutBorders.bookPriceType = null;
BooksWithoutBorders.bookPriceQuantity = 0;
BooksWithoutBorders.setBookPriceType(null);
BooksWithoutBorders.setBookPriceQuantity(0);
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Item type name");
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", BooksWithoutBorders.bookPriceQuantity);
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", BooksWithoutBorders.getBookPriceQuantity());
booksWithoutBorders.saveConfig();
BooksWithoutBorders.sendSuccessMessage(sender, "Price to create books removed!");
@ -89,16 +89,16 @@ public class CommandSetBookPrice implements CommandExecutor {
return false;
}
BooksWithoutBorders.bookPriceType = heldItem.getType();
BooksWithoutBorders.bookPriceQuantity = price;
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type",
BooksWithoutBorders.bookPriceType.toString());
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity",
BooksWithoutBorders.bookPriceQuantity);
BooksWithoutBorders.setBookPriceType(heldItem.getType());
BooksWithoutBorders.setBookPriceQuantity(price);
String newPriceType = BooksWithoutBorders.getBookPriceType().toString();
double newPriceQuantity = BooksWithoutBorders.getBookPriceQuantity();
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", newPriceType);
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", newPriceQuantity);
booksWithoutBorders.saveConfig();
BooksWithoutBorders.sendSuccessMessage(sender, "Book creation price set to " +
(int) BooksWithoutBorders.bookPriceQuantity + " " + BooksWithoutBorders.bookPriceType.toString() + "(s)!");
BooksWithoutBorders.sendSuccessMessage(sender, "Book creation price set to " + (int) newPriceQuantity +
" " + newPriceType + "(s)!");
return true;
}
@ -111,15 +111,15 @@ public class CommandSetBookPrice implements CommandExecutor {
*/
private boolean setEconomyPrice(CommandSender sender, double price) {
if (EconomyHelper.setupEconomy()) {
BooksWithoutBorders.bookPriceQuantity = price;
BooksWithoutBorders.bookPriceType = Material.AIR;
BooksWithoutBorders.setBookPriceQuantity(price);
BooksWithoutBorders.setBookPriceType(Material.AIR);
double newPriceQuantity = BooksWithoutBorders.getBookPriceQuantity();
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Item_type", "Economy");
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity",
BooksWithoutBorders.bookPriceQuantity);
booksWithoutBorders.getConfig().set("Options.Price_to_create_book.Required_quantity", newPriceQuantity);
booksWithoutBorders.saveConfig();
BooksWithoutBorders.sendSuccessMessage(sender, "Book creation price set to " +
EconomyHelper.getEconomy().format(BooksWithoutBorders.bookPriceQuantity) + "!");
EconomyHelper.getEconomy().format(newPriceQuantity) + "!");
return true;
} else {
BooksWithoutBorders.sendErrorMessage(sender, "BooksWithoutBorders failed to hook into Vault! Book price not set!");

View File

@ -43,7 +43,7 @@ public class CommandSetLore implements CommandExecutor {
//Format lore
rawLore = ChatColor.translateAlternateColorCodes('&', rawLore);
String[] loreParts = rawLore.split(BooksWithoutBorders.loreSeparator);
String[] loreParts = rawLore.split(BooksWithoutBorders.getLoreSeparator());
List<String> newLore = new ArrayList<>(Arrays.asList(loreParts));
//Update lore

View File

@ -57,11 +57,11 @@ public class PlayerEventListener implements Listener {
Player player = event.getPlayer();
//Handle new players
if (!hasPlayedBefore(player.getName())) {
if (!player.hasPlayedBefore()) {
boolean sendMessage = true;
//Gives new players necessary books
for (String bookName : BooksWithoutBorders.firstBooks) {
for (String bookName : BooksWithoutBorders.getFirstBooks()) {
sendMessage = giveBookToNewPlayer(bookName, player, sendMessage);
}
}
@ -103,10 +103,11 @@ public class PlayerEventListener implements Listener {
}
//Send the player a welcome message if it exists
if (!BooksWithoutBorders.welcomeMessage.trim().isEmpty() && newBook != null && sendMessage) {
String welcomeMessage = BooksWithoutBorders.getWelcomeMessage();
if (!welcomeMessage.trim().isEmpty() && newBook != null && sendMessage) {
sendMessage = false;
booksWithoutBorders.getServer().getScheduler().scheduleSyncDelayedTask(booksWithoutBorders,
() -> player.sendMessage(BooksWithoutBorders.welcomeMessage), 40L);
() -> player.sendMessage(welcomeMessage), 40L);
}
}
return sendMessage;
@ -151,7 +152,7 @@ public class PlayerEventListener implements Listener {
//Unknown author is ignored
fileName = oldBook.getTitle();
} else {
fileName = oldBook.getTitle() + BooksWithoutBorders.titleAuthorSeparator + oldBook.getAuthor();
fileName = oldBook.getTitle() + BooksWithoutBorders.getTitleAuthorSeparator() + oldBook.getAuthor();
}
String cleanPlayerName = InputCleaningHelper.cleanString(player.getName());
@ -175,18 +176,4 @@ public class PlayerEventListener implements Listener {
return null;
}
/**
* Checks whether a given player has played on the server before
* @param playerName <p>The player to check</p>
* @return <p>True if the player has played before</p>
*/
private boolean hasPlayedBefore(String playerName) {
if (!BooksWithoutBorders.existingPlayers.contains(playerName)) {
booksWithoutBorders.addExistingPlayer(playerName);
return false;
}
return true;
}
}

View File

@ -237,11 +237,11 @@ public class SignEventListener implements Listener {
//Permission check
if (!player.hasPermission("bookswithoutborders.decrypt." + groupName) &&
!(BooksWithoutBorders.adminDecrypt && player.hasPermission("bookswithoutborders.admin"))) {
!(BooksWithoutBorders.getAdminDecrypt() && player.hasPermission("bookswithoutborders.admin"))) {
return;
}
String fileName = oldBook.getTitle() + BooksWithoutBorders.titleAuthorSeparator + oldBook.getAuthor();
String fileName = oldBook.getTitle() + BooksWithoutBorders.getTitleAuthorSeparator() + oldBook.getAuthor();
String encryptionFile = InputCleaningHelper.cleanString(groupName) + slash + fileName + ".yml";

View File

@ -109,9 +109,11 @@ public final class BookToFromTextHelper {
private static BookMeta bookFromTXT(String fileName, File file, BookMeta bookMetadata) {
String author;
String title;
if (fileName.contains(BooksWithoutBorders.titleAuthorSeparator)) {
author = fileName.substring(fileName.indexOf(BooksWithoutBorders.titleAuthorSeparator) + 1, fileName.length() - 4);
title = fileName.substring(0, fileName.indexOf(BooksWithoutBorders.titleAuthorSeparator));
String titleAuthorSeparator = BooksWithoutBorders.getTitleAuthorSeparator();
if (fileName.contains(titleAuthorSeparator)) {
author = fileName.substring(fileName.indexOf(titleAuthorSeparator) + 1, fileName.length() - 4);
title = fileName.substring(0, fileName.indexOf(titleAuthorSeparator));
} else {
author = "Unknown";
title = fileName.substring(0, fileName.length() - 4);

View File

@ -198,7 +198,7 @@ public final class EncryptionHelper {
}
String fileName = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() : bookMetadata.getTitle() +
BooksWithoutBorders.titleAuthorSeparator + bookMetadata.getAuthor();
BooksWithoutBorders.getTitleAuthorSeparator() + bookMetadata.getAuthor();
fileName = "[" + key + "]" + fileName;
fileName = cleanString(fileName);
fileName = fixName(fileName, false);
@ -263,7 +263,7 @@ public final class EncryptionHelper {
}
//Creates file
String fileName = (!bookMetadata.hasTitle()) ? "Untitled," + player.getName() :
bookMetadata.getTitle() + BooksWithoutBorders.titleAuthorSeparator + bookMetadata.getAuthor();
bookMetadata.getTitle() + BooksWithoutBorders.getTitleAuthorSeparator() + bookMetadata.getAuthor();
fileName = cleanString(fileName);
fileName = fixName(fileName, false);
@ -279,7 +279,7 @@ public final class EncryptionHelper {
bookMetadata.setLore(newLore);
//Save file
File file = (BooksWithoutBorders.useYml) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt");
File file = (BooksWithoutBorders.getUseYml()) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt");
if (!file.isFile()) {
try {
BookToFromTextHelper.bookToYml(path, fileName, bookMetadata);
@ -304,14 +304,14 @@ public final class EncryptionHelper {
private static Boolean saveEncryptedBook(Player player, BookMeta bookMetaData, String key) {
String path = getBookFolder() + "Encrypted" + getSlash();
String fileName = (!bookMetaData.hasTitle()) ? "Untitled," + player.getName() :
bookMetaData.getTitle() + BooksWithoutBorders.titleAuthorSeparator + bookMetaData.getAuthor();
bookMetaData.getTitle() + BooksWithoutBorders.getTitleAuthorSeparator() + bookMetaData.getAuthor();
fileName = "[" + key + "]" + fileName;
fileName = cleanString(fileName);
fileName = fixName(fileName, false);
//cancels saving if file is already encrypted
File file = (BooksWithoutBorders.useYml) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt");
File file = (BooksWithoutBorders.getUseYml()) ? new File(path + fileName + ".yml") : new File(path + fileName + ".txt");
if (file.isFile()) {
return true;
}