Prevents WIP books from being lost

This change adds a workaround for writable books used for payment. Only books that don't contain any text can be used for payment, thus preventing any books with important text from being lost.
This commit is contained in:
Kristian Knarvik 2022-11-04 03:37:38 +01:00
parent 6820b71dde
commit 0fdfd81579
2 changed files with 81 additions and 7 deletions

View File

@ -88,7 +88,7 @@
<groupId>org.jetbrains</groupId> <groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId> <artifactId>annotations</artifactId>
<version>23.0.0</version> <version>23.0.0</version>
<scope>compile</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -8,10 +8,13 @@ import org.bukkit.Server;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicesManager; import org.bukkit.plugin.ServicesManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
/** /**
@ -74,17 +77,88 @@ public final class EconomyHelper {
if (bookCurrency == Material.AIR) { if (bookCurrency == Material.AIR) {
return !EconomyHelper.payForBookPrintingEconomy(player, cost, numCopies); return !EconomyHelper.payForBookPrintingEconomy(player, cost, numCopies);
} else { } else {
if (player.getInventory().contains(bookCurrency, itemCost)) { if (bookCurrency == Material.WRITABLE_BOOK) {
payForBookPrintingItem(player, itemCost); //Writable books are treated as a special case to prevent WIP books from being used
return false; return !takeWritableBookPayment(player, itemCost);
} else { } else {
BooksWithoutBorders.sendErrorMessage(player, itemCost + " " + bookCurrency + if (player.getInventory().contains(bookCurrency, itemCost)) {
"(s) are required for this command!"); payForBookPrintingItem(player, itemCost);
return true; return false;
} else {
BooksWithoutBorders.sendErrorMessage(player, itemCost + " " + bookCurrency +
"(s) are required for this command!");
return true;
}
} }
} }
} }
/**
* Takes a writable book payment, ignoring any books containing text
*
* @param player <p>The player to take payment from</p>
* @param itemCost <p>The number of writable books to pay</p>
* @return <p>True if the payment was successful</p>
*/
private static boolean takeWritableBookPayment(Player player, int itemCost) {
List<ItemStack> books = getPlayersEmptyBooks(player);
if (countItems(books) < itemCost) {
BooksWithoutBorders.sendErrorMessage(player, itemCost + " " + Material.WRITABLE_BOOK +
"(s) are required for this command!");
return false;
} else {
int clearedAmount = 0;
for (ItemStack itemStack : books) {
if (itemStack.getAmount() > itemCost) {
itemStack.setAmount(itemStack.getAmount() - itemCost);
break;
} else {
clearedAmount += itemStack.getAmount();
player.getInventory().remove(itemStack);
}
if (clearedAmount >= itemCost) {
break;
}
}
return true;
}
}
/**
* Gets the total number of items contained in the given list of items
*
* @param items <p>The items to count</p>
* @return <p>The total number of items</p>
*/
private static int countItems(List<ItemStack> items) {
int totalItems = 0;
for (ItemStack itemStack : items) {
totalItems += itemStack.getAmount();
}
return totalItems;
}
/**
* Gets all empty books in a player's inventory
*
* @param player <p>The player to get books for</p>
* @return <p>The empty books in the player's inventory</p>
*/
private static List<ItemStack> getPlayersEmptyBooks(Player player) {
List<ItemStack> validBooks = new ArrayList<>();
for (ItemStack itemStack : player.getInventory().getContents()) {
if (itemStack.getType() != Material.WRITABLE_BOOK) {
continue;
}
BookMeta book = (BookMeta) itemStack;
//Only accept empty books
if (!book.hasPages() || (book.getPageCount() == 1 && book.getPage(1).trim().isEmpty())) {
validBooks.add(itemStack);
}
}
return validBooks;
}
/** /**
* Uses economy to take payment for printing a number of books * Uses economy to take payment for printing a number of books
* *