diff --git a/src/main/java/com/yourorg/servershop/gui/SellMenu.java b/src/main/java/com/yourorg/servershop/gui/SellMenu.java index 1cceda8..6ee0d52 100644 --- a/src/main/java/com/yourorg/servershop/gui/SellMenu.java +++ b/src/main/java/com/yourorg/servershop/gui/SellMenu.java @@ -8,6 +8,9 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import com.yourorg.servershop.logging.Transaction; + +import java.time.Instant; import java.util.*; public final class SellMenu implements MenuView { @@ -53,6 +56,7 @@ public void refresh(Player p) { private void sellAll(Player p) { double total = 0.0; int stacks = 0; + List txs = new ArrayList<>(); for (int i = 0; i < p.getInventory().getSize(); i++) { ItemStack s = p.getInventory().getItem(i); if (s == null) continue; var m = s.getType(); @@ -62,11 +66,12 @@ private void sellAll(Player p) { double amount = unit * qty; total += amount; stacks++; p.getInventory().setItem(i, null); - plugin.logger().logAsync(new com.yourorg.servershop.logging.Transaction(java.time.Instant.now(), p.getName(), com.yourorg.servershop.logging.Transaction.Type.SELL, m, qty, amount)); - // TODO: consider calling plugin.dynamic().adjustOnSell(m, qty) per TODO list + plugin.dynamic().adjustOnSell(m, qty); + txs.add(new Transaction(Instant.now(), p.getName(), Transaction.Type.SELL, m, qty, amount)); } if (total > 0) plugin.economy().depositPlayer(p, total); p.sendMessage(plugin.prefixed(plugin.getConfig().getString("messages.soldall").replace("%count%", String.valueOf(stacks)).replace("%total%", String.format("%.2f", total)))); + txs.forEach(plugin.logger()::logAsync); refresh(p); } diff --git a/src/main/java/com/yourorg/servershop/shop/ShopService.java b/src/main/java/com/yourorg/servershop/shop/ShopService.java index 95325a3..9565ced 100644 --- a/src/main/java/com/yourorg/servershop/shop/ShopService.java +++ b/src/main/java/com/yourorg/servershop/shop/ShopService.java @@ -2,12 +2,14 @@ import com.yourorg.servershop.ServerShopPlugin; import com.yourorg.servershop.logging.Transaction; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import java.time.Instant; import java.util.Optional; +import java.util.concurrent.ExecutionException; public final class ShopService { private final ServerShopPlugin plugin; @@ -15,6 +17,18 @@ public final class ShopService { public ShopService(ServerShopPlugin plugin) { this.plugin = plugin; } public Optional buy(Player p, Material mat, int qty) { + if (!Bukkit.isPrimaryThread()) { + try { + return Bukkit.getScheduler().callSyncMethod(plugin, () -> buySync(p, mat, qty)).get(); + } catch (InterruptedException | ExecutionException e) { + Thread.currentThread().interrupt(); + return Optional.of("Internal error"); + } + } + return buySync(p, mat, qty); + } + + private Optional buySync(Player p, Material mat, int qty) { var opt = plugin.catalog().get(mat); if (opt.isEmpty() || !opt.get().canBuy()) return Optional.of(msg("not-for-sale").replace("%material%", mat.name())); String cat = plugin.catalog().categoryOf(mat); @@ -38,6 +52,18 @@ public Optional buy(Player p, Material mat, int qty) { } public Optional sell(Player p, Material mat, int qty) { + if (!Bukkit.isPrimaryThread()) { + try { + return Bukkit.getScheduler().callSyncMethod(plugin, () -> sellSync(p, mat, qty)).get(); + } catch (InterruptedException | ExecutionException e) { + Thread.currentThread().interrupt(); + return Optional.of("Internal error"); + } + } + return sellSync(p, mat, qty); + } + + private Optional sellSync(Player p, Material mat, int qty) { var opt = plugin.catalog().get(mat); if (opt.isEmpty() || !opt.get().canSell()) return Optional.of(msg("not-sellable").replace("%material%", mat.name())); String cat = plugin.catalog().categoryOf(mat);