diff --git a/README.md b/README.md index 3f9fc9e5..54cd708f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,44 @@ currency value and money transactions are based on actual items in Minecraft, pe a greater level of immersion, a generally more Minecraft-like feeling, and in the case of a PvP environment, making the currency itself vulnerable to raiding. + +### ⚠ Breaking Changes in Version 3.0.0 + +This version changed the way data are stored, so if you come from an older version of Gringotts, you need to manually update your database. + +- Shutdown your server +- In your plugins folder, open the folder named `Gringotts` +- Make a copy of the file `Gringotts.db` in case something goes wrong during the update. +- Install sqlite3 command-line program, on linux you can do so by entering the following in the terminal `sudo apt install sqlite3` +(for windows refer to [this link](https://www.sqlite.org/cli.html)) +- Open your terminal in Gringotts' directory and enter this command `sqlite3 Gringotts.db` +- In the shell enter the following instructions +``` +CREATE TABLE db_migration ( + id integer not null, + mchecksum integer not null, + mtype varchar(1) not null, + mversion varchar(150) not null, + mcomment varchar(150) not null, + mstatus varchar(10) not null, + run_on timestamp not null, + run_by varchar(30) not null, + run_time integer not null, + constraint pk_db_migration primary key (id) +); +``` +Execute and then enter +`INSERT INTO db_migration VALUES(0,0,'I','0','','SUCCESS',1721777343415,'foo',0);` +and +`INSERT INTO db_migration VALUES(1,-1450547331,'V','1.0','initial','SUCCESS',1721777343415,'foo',1);` + +- If everything went smoothly you should be done, exit sqlite by typing `.exit`, replace gringotts.jar by the new version and start your server. + +> You may get the error `Error: attempt to write a readonly database`, that means that your user doesn't have write permission for the file Gringotts.db. + +> On the first launch you will get lot of `Balance differs for account` errors, they can be ignored. If you get one after that, please open an issue as it may indicate a money duplication glitch. + + ### Get Gringotts - [from Spigot](https://www.spigotmc.org/resources/gringotts.42071/) diff --git a/jitpack.yml b/jitpack.yml index 74c2182a..198265cd 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,7 +1,7 @@ jdk: - - openjdk17 + - openjdk21 before_install: - - sdk install java 17.0.3-open - - sdk use java 17.0.3-open + - sdk install java 21.0.4-open + - sdk use java 21.0.4-open - sdk install maven - mvn -v diff --git a/pom.xml b/pom.xml index c7dfd9ed..a6e0cbfc 100755 --- a/pom.xml +++ b/pom.xml @@ -7,8 +7,8 @@ false - 18 - 18 + 17 + 17 UTF-8 @@ -130,7 +130,7 @@ me.clip placeholderapi - 2.11.2 + 2.11.6 provided diff --git a/src/main/java/org/gestern/gringotts/AccountChest.java b/src/main/java/org/gestern/gringotts/AccountChest.java index 90edcaab..57f39f9a 100755 --- a/src/main/java/org/gestern/gringotts/AccountChest.java +++ b/src/main/java/org/gestern/gringotts/AccountChest.java @@ -1,6 +1,9 @@ package org.gestern.gringotts; -import io.papermc.lib.PaperLib; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.bukkit.ChatColor; import org.bukkit.Location; @@ -13,8 +16,7 @@ import org.bukkit.inventory.InventoryHolder; import org.gestern.gringotts.data.EBeanPendingOperation; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import io.papermc.lib.PaperLib; /** * Represents a storage unit for an account. @@ -31,6 +33,7 @@ public class AccountChest { * Sign marking the chest as an account chest. */ public final Sign sign; + public List containerLocations = new ArrayList<>(); /** * Account this chest belongs to. */ @@ -92,6 +95,23 @@ public Location chestLocation() { return block != null ? block.getLocation() : null; } + public boolean matchesLocation(Location loc) { + if (this.containerLocations.isEmpty()) { + InventoryHolder holder = chest(); + + if (holder.getInventory() instanceof DoubleChestInventory) { + DoubleChestInventory doubleChest = (DoubleChestInventory) holder.getInventory(); + + containerLocations.add(doubleChest.getLeftSide().getLocation()); + containerLocations.add(doubleChest.getRightSide().getLocation()); + } else { + containerLocations.add(holder.getInventory().getLocation()); + } + } + loc = loc.toBlockLocation(); + return containerLocations.contains(loc); + } + /** * Get inventory of this account chest. * @@ -130,7 +150,7 @@ private boolean updateInvalid() { } /** - * Return balance of this chest. + * Returns the balance of this chest. * Equivalent to AccountChest#balance(false) * @return balance of this chest or the cached balance if the chest is unloaded */ @@ -138,6 +158,11 @@ public long balance() { return balance(false); } + /** + * Returns the balance of this chest. + * @param forceUpdate used when cache can't be trusted and you need to check the real balance in the {@link AccountChest} + * @return balance of this chest or the cached balance if the chest is unloaded or if forceUpdate is true + */ public long balance(boolean forceUpdate) { if (!forceUpdate && !isChestLoaded()) return cachedBalance; diff --git a/src/main/java/org/gestern/gringotts/Gringotts.java b/src/main/java/org/gestern/gringotts/Gringotts.java index 676f5b96..72623819 100644 --- a/src/main/java/org/gestern/gringotts/Gringotts.java +++ b/src/main/java/org/gestern/gringotts/Gringotts.java @@ -101,7 +101,7 @@ public Gringotts() { } public String getVersion() { - return getDescription().getVersion(); + return getPluginMeta().getVersion(); } /** diff --git a/src/main/java/org/gestern/gringotts/Util.java b/src/main/java/org/gestern/gringotts/Util.java index 138d4d12..4fcf1c71 100644 --- a/src/main/java/org/gestern/gringotts/Util.java +++ b/src/main/java/org/gestern/gringotts/Util.java @@ -197,7 +197,7 @@ public static boolean isValidContainer(Material material) { } return switch (material) { - case CHEST, TRAPPED_CHEST, DISPENSER, FURNACE, HOPPER, DROPPER, BARREL -> true; + case CHEST, TRAPPED_CHEST, DISPENSER, FURNACE, DROPPER, BARREL -> true; default -> false; }; } @@ -210,7 +210,7 @@ public static boolean isValidContainer(Material material) { */ public static boolean isValidInventory(InventoryType inventory) { return switch (inventory) { - case CHEST, DISPENSER, FURNACE, HOPPER, DROPPER, BARREL -> true; + case CHEST, DISPENSER, FURNACE, DROPPER, BARREL -> true; default -> false; }; } diff --git a/src/main/java/org/gestern/gringotts/accountholder/AccountHolderProvider.java b/src/main/java/org/gestern/gringotts/accountholder/AccountHolderProvider.java index c3856fe4..a35d2497 100644 --- a/src/main/java/org/gestern/gringotts/accountholder/AccountHolderProvider.java +++ b/src/main/java/org/gestern/gringotts/accountholder/AccountHolderProvider.java @@ -1,14 +1,13 @@ package org.gestern.gringotts.accountholder; +import java.util.Set; +import java.util.UUID; + import org.bukkit.OfflinePlayer; -import org.gestern.gringotts.event.VaultCreationEvent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Set; -import java.util.UUID; - /** * Provides AccountHolder objects for a given id. * An AccountHolderProvider has its own internal mapping of ids to account holders. diff --git a/src/main/java/org/gestern/gringotts/api/dependency/Dependency.java b/src/main/java/org/gestern/gringotts/api/dependency/Dependency.java index e5d91ae3..db03ec25 100644 --- a/src/main/java/org/gestern/gringotts/api/dependency/Dependency.java +++ b/src/main/java/org/gestern/gringotts/api/dependency/Dependency.java @@ -29,7 +29,7 @@ default String getName() { */ default String getVersion() { return this.getPlugin() - .getDescription() + .getPluginMeta() .getVersion(); } diff --git a/src/main/java/org/gestern/gringotts/api/impl/GringottsEco.java b/src/main/java/org/gestern/gringotts/api/impl/GringottsEco.java index 938331c2..c2dde334 100644 --- a/src/main/java/org/gestern/gringotts/api/impl/GringottsEco.java +++ b/src/main/java/org/gestern/gringotts/api/impl/GringottsEco.java @@ -131,7 +131,7 @@ public Set getBanks() { */ @Override public Account getAccount(String id) { - String[] parts = id.split(":"); + String[] parts = id.split("-", 2); if (parts.length == 1) { OfflinePlayer player = Util.getOfflinePlayer(id); diff --git a/src/main/java/org/gestern/gringotts/api/impl/VaultConnector.java b/src/main/java/org/gestern/gringotts/api/impl/VaultConnector.java index ae204418..f884e657 100644 --- a/src/main/java/org/gestern/gringotts/api/impl/VaultConnector.java +++ b/src/main/java/org/gestern/gringotts/api/impl/VaultConnector.java @@ -60,13 +60,7 @@ public String currencyNameSingular() { @Override public boolean hasAccount(String accountId) { - OfflinePlayer player = Util.getOfflinePlayer(accountId); - - if (player != null) { - return hasAccount(player); - } - - return eco.account(accountId).exists(); + return eco.getAccount(accountId).exists(); } @Override @@ -75,14 +69,8 @@ public boolean hasAccount(OfflinePlayer offlinePlayer) { } @Override - public double getBalance(String accountId) { - OfflinePlayer player = Util.getOfflinePlayer(accountId); - - if (player != null) { - return getBalance(player); - } - - return eco.account(accountId).balance(); + public double getBalance(String accountId) { // TODO optimize + return eco.getAccount(accountId).balance(); } @Override @@ -92,13 +80,7 @@ public double getBalance(OfflinePlayer offlinePlayer) { @Override public boolean has(String accountId, double amount) { - OfflinePlayer player = Util.getOfflinePlayer(accountId); - - if (player != null) { - return has(player, amount); - } - - return eco.account(accountId).has(amount); + return eco.getAccount(accountId).has(amount); } @Override @@ -108,15 +90,7 @@ public boolean has(OfflinePlayer offlinePlayer, double amount) { @Override public EconomyResponse withdrawPlayer(String accountId, double amount) { - OfflinePlayer player = Util.getOfflinePlayer(accountId); - - if (player != null) { - return withdrawPlayer(player, amount); - } - - Account account = eco.account(accountId); - - return withdrawPlayer(account, amount); + return withdrawPlayer(eco.getAccount(accountId), amount); } @Override @@ -142,7 +116,7 @@ private EconomyResponse withdrawPlayer(Account account, double amount) { @Override public EconomyResponse depositPlayer(String playerName, double amount) { - Account account = eco.account(playerName); + Account account = eco.getAccount(playerName); return depositPlayer(account, amount); } diff --git a/src/main/java/org/gestern/gringotts/currency/DenominationKey.java b/src/main/java/org/gestern/gringotts/currency/DenominationKey.java index 1857452e..3f315a74 100644 --- a/src/main/java/org/gestern/gringotts/currency/DenominationKey.java +++ b/src/main/java/org/gestern/gringotts/currency/DenominationKey.java @@ -1,11 +1,9 @@ package org.gestern.gringotts.currency; +import java.util.Objects; + import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import org.gestern.gringotts.Configuration; - -import java.util.HashMap; -import java.util.Objects; /** * Hashable information to identify a denomination by it's ItemStack. diff --git a/src/main/java/org/gestern/gringotts/data/EBeanDAO.java b/src/main/java/org/gestern/gringotts/data/EBeanDAO.java index 641d4c56..5495bbc4 100644 --- a/src/main/java/org/gestern/gringotts/data/EBeanDAO.java +++ b/src/main/java/org/gestern/gringotts/data/EBeanDAO.java @@ -308,7 +308,7 @@ public boolean renameAccount(String type, String oldName, String newName) { @Override public synchronized List retrieveChests(GringottsAccount account) { if (!allChests.isEmpty()) { - return allChests.stream().filter(ac -> ac.account.owner.equals(account.owner)).collect(Collectors.toList()); + return allChests.stream().filter(ac -> ac.account.owner.getId().equals(account.owner.getId())).collect(Collectors.toList()); } SqlQuery getChests = db.sqlQuery("SELECT ac.world, ac.x, ac.y, ac.z, ac.total_value " + "FROM gringotts_accountchest ac JOIN gringotts_account a ON ac.account = a.id " + diff --git a/src/main/java/org/gestern/gringotts/dependency/DependencyProviderImpl.java b/src/main/java/org/gestern/gringotts/dependency/DependencyProviderImpl.java index 5f93b444..72558063 100644 --- a/src/main/java/org/gestern/gringotts/dependency/DependencyProviderImpl.java +++ b/src/main/java/org/gestern/gringotts/dependency/DependencyProviderImpl.java @@ -1,18 +1,17 @@ package org.gestern.gringotts.dependency; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginDescriptionFile; import org.gestern.gringotts.Gringotts; import org.gestern.gringotts.Util; import org.gestern.gringotts.api.dependency.Dependency; import org.gestern.gringotts.api.dependency.DependencyProvider; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - /** * The type Dependency provider. */ @@ -52,8 +51,7 @@ public Plugin hookPlugin(String name, String classpath, String minVersion) { "Plugin %s hooked.", name )); - PluginDescriptionFile desc = plugin.getDescription(); - String version = desc.getVersion(); + String version = plugin.getPluginMeta().getVersion(); if (!Util.versionAtLeast(version, minVersion)) { this.gringotts.getLogger().warning(String.format( diff --git a/src/main/java/org/gestern/gringotts/event/AccountListener.java b/src/main/java/org/gestern/gringotts/event/AccountListener.java index d1710469..9655a6ef 100755 --- a/src/main/java/org/gestern/gringotts/event/AccountListener.java +++ b/src/main/java/org/gestern/gringotts/event/AccountListener.java @@ -1,17 +1,21 @@ package org.gestern.gringotts.event; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Tag; -import org.bukkit.block.BlockState; -import org.bukkit.block.DoubleChest; import org.bukkit.block.Sign; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockDispenseEvent; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.scheduler.BukkitRunnable; import org.gestern.gringotts.AccountChest; @@ -21,9 +25,7 @@ import com.destroystokyo.paper.event.block.BlockDestroyEvent; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import io.papermc.paper.event.player.PlayerOpenSignEvent; /** * Listens for chest creation, destruction and change events. @@ -92,12 +94,9 @@ public void onSignBreak(BlockDestroyEvent event) { @EventHandler(priority = EventPriority.MONITOR) public void onInventoryClose(InventoryCloseEvent event) { - if (!Util.isValidInventory(event.getInventory().getType())) return; - - InventoryHolder holder = event.getInventory().getHolder(); - if (holder == null) return; + if (event.getInventory().getLocation() == null || !Util.isValidInventory(event.getInventory().getType())) return; - AccountChest chest = getAccountChestFromHolder(holder); + AccountChest chest = getAccountChestFromHolder(event.getInventory()); if (chest == null) return; chest.setCachedBalance(chest.balance(true)); @@ -106,8 +105,8 @@ public void onInventoryClose(InventoryCloseEvent event) { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onInventoryMoveItem(InventoryMoveItemEvent event) { - if (event.getSource().getHolder() != null) { - AccountChest chest = getAccountChestFromHolder(event.getSource().getHolder()); + if (Util.isValidInventory(event.getSource().getType())) { + AccountChest chest = getAccountChestFromHolder(event.getSource()); if (chest != null) { new BukkitRunnable() { @Override @@ -118,8 +117,8 @@ public void run() { }.runTask(Gringotts.instance); } } - if (event.getDestination() != null) { - AccountChest chest = getAccountChestFromHolder(event.getDestination().getHolder()); + if (event.getDestination() != null && Util.isValidInventory(event.getDestination().getType())) { + AccountChest chest = getAccountChestFromHolder(event.getDestination()); if (chest != null) { new BukkitRunnable() { @Override @@ -132,23 +131,44 @@ public void run() { } } + @EventHandler + public void onDispenseEvent(BlockDispenseEvent event) { + if (event.getBlock().getState() instanceof InventoryHolder) { + AccountChest chest = getAccountChestFromHolder(((InventoryHolder) event.getBlock().getState()).getInventory()); + if (chest != null) { + new BukkitRunnable() { + @Override + public void run() { + chest.setCachedBalance(chest.balance(true)); + Gringotts.instance.getDao().updateChestBalance(chest, chest.getCachedBalance()); + } + }.runTask(Gringotts.instance); + } + } + } + + @EventHandler + public void onSignEdit(PlayerOpenSignEvent event) { + for (AccountChest chest : Gringotts.instance.getDao().retrieveChests()) { + if (!chest.isChestLoaded()) continue; // For a sign to be changed, it needs to be loaded + if (event.getSign().getLocation().equals(chest.sign.getLocation())) { + event.setCancelled(true); + return; + } + } + } + /** * Get the AccountChest associated with this {@link InventoryHolder} * @param holder * @return the {@link AccountChest} or null if none was found */ - private AccountChest getAccountChestFromHolder(InventoryHolder holder) { + private AccountChest getAccountChestFromHolder(Inventory holder) { for (AccountChest chest : Gringotts.instance.getDao().retrieveChests()) { if (!chest.isChestLoaded()) continue; // For a chest to be open or interacted with, it needs to be loaded - BlockState chestState = Util.chestBlock(chest.sign).getState(); - - if (chestState.equals(holder)) return chest; - - if (holder instanceof DoubleChest) { - DoubleChest doubleChest = (DoubleChest) holder; - if (doubleChest.getLeftSide().equals(chestState) || doubleChest.getRightSide().equals(chestState)) - return chest; + if (chest.matchesLocation(holder.getLocation())) { + return chest; } } return null; diff --git a/src/main/java/org/gestern/gringotts/pendingoperation/PendingOperationManager.java b/src/main/java/org/gestern/gringotts/pendingoperation/PendingOperationManager.java index 5c46b32e..6ec31108 100644 --- a/src/main/java/org/gestern/gringotts/pendingoperation/PendingOperationManager.java +++ b/src/main/java/org/gestern/gringotts/pendingoperation/PendingOperationManager.java @@ -37,7 +37,6 @@ public void applyOperationsForChunk(Chunk chunk) { ).findAny(); if (accountChest.isEmpty()) continue; - System.out.println("chest found"); if (operation.getAmount() < 0) { accountChest.get().remove(-operation.getAmount());