From 49fb85229db13c372e1acce238e02b9c15f70456 Mon Sep 17 00:00:00 2001 From: Len <40720638+destro174@users.noreply.github.com> Date: Sun, 28 Dec 2025 19:58:45 +0100 Subject: [PATCH] Refactor PlayerShops to use Dialogs. --- .../com/alttd/playershops/PlayerShops.java | 7 - .../commands/PlayerShopCommand.java | 13 +- .../conversation/ConversationManager.java | 216 ------------------ .../conversation/ConversationType.java | 10 - .../playershops/dialog/AbstractDialog.java | 83 +++++++ .../playershops/dialog/ListPlayersDialog.java | 90 ++++++++ .../playershops/dialog/ListShopsDialog.java | 161 +++++++++++++ .../playershops/dialog/ManageShopDialog.java | 211 +++++++++++++++++ .../playershops/dialog/SearchShopsDialog.java | 79 +++++++ .../alttd/playershops/dialog/ShopDialog.java | 135 +++++++++++ .../dialog/ShopSettingsDialog.java | 97 ++++++++ .../alttd/playershops/gui/AbstractGui.java | 158 ------------- .../com/alttd/playershops/gui/GuiIcon.java | 83 ------- .../com/alttd/playershops/gui/HomeGui.java | 48 ---- .../alttd/playershops/gui/ListPlayersGui.java | 63 ----- .../alttd/playershops/gui/ListShopsGui.java | 123 ---------- .../playershops/gui/ListTransactionsGui.java | 44 ---- .../playershops/gui/PlayerSettingsGui.java | 59 ----- .../playershops/gui/ShopManagementGui.java | 142 ------------ .../playershops/handler/ShopHandler.java | 24 ++ .../listener/InventoryListener.java | 44 ---- .../listener/TransactionListener.java | 8 +- .../playershops/shop/PlayerSettings.java | 7 +- .../alttd/playershops/shop/PlayerShop.java | 36 ++- .../alttd/playershops/utils/EconomyUtils.java | 33 +++ .../com/alttd/playershops/utils/ShopUtil.java | 21 +- 26 files changed, 978 insertions(+), 1017 deletions(-) delete mode 100644 src/main/java/com/alttd/playershops/conversation/ConversationManager.java delete mode 100644 src/main/java/com/alttd/playershops/conversation/ConversationType.java create mode 100644 src/main/java/com/alttd/playershops/dialog/AbstractDialog.java create mode 100644 src/main/java/com/alttd/playershops/dialog/ListPlayersDialog.java create mode 100644 src/main/java/com/alttd/playershops/dialog/ListShopsDialog.java create mode 100644 src/main/java/com/alttd/playershops/dialog/ManageShopDialog.java create mode 100644 src/main/java/com/alttd/playershops/dialog/SearchShopsDialog.java create mode 100644 src/main/java/com/alttd/playershops/dialog/ShopDialog.java create mode 100644 src/main/java/com/alttd/playershops/dialog/ShopSettingsDialog.java delete mode 100644 src/main/java/com/alttd/playershops/gui/AbstractGui.java delete mode 100644 src/main/java/com/alttd/playershops/gui/GuiIcon.java delete mode 100644 src/main/java/com/alttd/playershops/gui/HomeGui.java delete mode 100644 src/main/java/com/alttd/playershops/gui/ListPlayersGui.java delete mode 100644 src/main/java/com/alttd/playershops/gui/ListShopsGui.java delete mode 100644 src/main/java/com/alttd/playershops/gui/ListTransactionsGui.java delete mode 100644 src/main/java/com/alttd/playershops/gui/PlayerSettingsGui.java delete mode 100644 src/main/java/com/alttd/playershops/gui/ShopManagementGui.java delete mode 100644 src/main/java/com/alttd/playershops/listener/InventoryListener.java diff --git a/src/main/java/com/alttd/playershops/PlayerShops.java b/src/main/java/com/alttd/playershops/PlayerShops.java index 0f732aa..6d89f7c 100644 --- a/src/main/java/com/alttd/playershops/PlayerShops.java +++ b/src/main/java/com/alttd/playershops/PlayerShops.java @@ -4,7 +4,6 @@ import com.alttd.playershops.commands.PlayerShopCommand; import com.alttd.playershops.config.Config; import com.alttd.playershops.config.DatabaseConfig; import com.alttd.playershops.config.MessageConfig; -import com.alttd.playershops.gui.GuiIcon; import com.alttd.playershops.handler.ShopHandler; import com.alttd.playershops.listener.*; import com.alttd.playershops.shop.ShopType; @@ -37,7 +36,6 @@ public class PlayerShops extends JavaPlugin { private ShopListener shopListener; private PlayerListener playerListener; private TransactionListener transactionListener; - private InventoryListener inventoryListener; private GriefPreventionListener griefPreventionListener; @Getter @@ -101,7 +99,6 @@ public class PlayerShops extends JavaPlugin { shopListener = new ShopListener(this); playerListener = new PlayerListener(this); transactionListener = new TransactionListener(this); - inventoryListener = new InventoryListener(this); griefPreventionListener = new GriefPreventionListener(this); // TODO hook into GP } @@ -109,7 +106,6 @@ public class PlayerShops extends JavaPlugin { shopListener.unregister(); playerListener.unregister(); transactionListener.unregister(); - inventoryListener.unregister(); } private void registerCommands() { @@ -129,9 +125,6 @@ public class PlayerShops extends JavaPlugin { for (ShopType shopType : ShopType.values()) { // preload ShopType to get the configs active } - for (GuiIcon guiIcon : GuiIcon.values()) { - // preload to get config values generated - } } } diff --git a/src/main/java/com/alttd/playershops/commands/PlayerShopCommand.java b/src/main/java/com/alttd/playershops/commands/PlayerShopCommand.java index b703647..fa38f92 100644 --- a/src/main/java/com/alttd/playershops/commands/PlayerShopCommand.java +++ b/src/main/java/com/alttd/playershops/commands/PlayerShopCommand.java @@ -3,7 +3,7 @@ package com.alttd.playershops.commands; import com.alttd.playershops.PlayerShops; import com.alttd.playershops.commands.arguments.OfflinePlayerArgument; import com.alttd.playershops.commands.subcommands.CheckStockCommand; -import com.alttd.playershops.gui.HomeGui; +import com.alttd.playershops.dialog.ShopDialog; import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.tree.LiteralCommandNode; @@ -28,14 +28,13 @@ public class PlayerShopCommand { if (!(source.getSource().getSender() instanceof Player player)) return 1; - // TODO -- DIALOG - HomeGui gui = new HomeGui(player.getUniqueId()); - gui.open(); + ShopDialog shopDialog = new ShopDialog(player.getUniqueId()); + shopDialog.open(); return 1; }) .then( Commands.literal("reload") - .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + "reload")) + .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".reload")) .executes(source -> { PlayerShops.getInstance().reloadConfigs(); return 1; @@ -43,7 +42,7 @@ public class PlayerShopCommand { ) .then( Commands.literal("checkstock") - .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + "checkstock") + .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".checkstock") && commandSourceStack.getSender() instanceof Player) .then( Commands.argument("range", IntegerArgumentType.integer(1, 100)) @@ -72,7 +71,7 @@ public class PlayerShopCommand { ) .then( Commands.literal("transfershops") - .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + "transfershops")) + .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".transfershops")) .then( Commands.argument("old", new OfflinePlayerArgument()) .then( diff --git a/src/main/java/com/alttd/playershops/conversation/ConversationManager.java b/src/main/java/com/alttd/playershops/conversation/ConversationManager.java deleted file mode 100644 index dfc7478..0000000 --- a/src/main/java/com/alttd/playershops/conversation/ConversationManager.java +++ /dev/null @@ -1,216 +0,0 @@ -package com.alttd.playershops.conversation; - -import com.alttd.playershops.config.MessageConfig; -import com.alttd.playershops.gui.ShopManagementGui; -import com.alttd.playershops.shop.PlayerShop; -import com.alttd.playershops.shop.ShopType; -import com.alttd.playershops.utils.EconomyUtils; -import com.alttd.playershops.utils.Util; -import com.google.common.base.Joiner; -import net.kyori.adventure.text.Component; -import org.bukkit.conversations.*; -import org.bukkit.entity.Player; -import org.bukkit.plugin.java.JavaPlugin; -import org.jetbrains.annotations.NotNull; - -public class ConversationManager implements ConversationAbandonedListener { - - PlayerShop playerShop; - Player player; - Conversation conversation; - - public ConversationManager(JavaPlugin plugin, Player player, ConversationType conversationType, PlayerShop playerShop) { - if (player.isConversing()) return; - this.player = player; - this.playerShop = playerShop; - ConversationFactory conversationFactory = new ConversationFactory(plugin) - .withModality(true) - .withFirstPrompt(getPrompt(conversationType)) - .addConversationAbandonedListener(this) - .withEscapeSequence("cancel"); - conversation = conversationFactory.buildConversation(player); - conversation.setLocalEchoEnabled(false); // why is this not in the builder - conversation.begin(); - } - - Prompt getPrompt(ConversationType conversationType) { - switch (conversationType) { - case CHANGE_ITEM -> { - return new ChangeItemPrompt(); - } - case CHANGE_AMOUNT -> { - return new ChangeAmountPrompt(); - } - case CHANGE_TYPE -> { - return new ChangeTypePrompt(); - } - case WITHDRAW_BALANCE -> { - return new WithdrawBalancePrompt(); - } - case ADD_BALANCE -> { - return new AddBalancePrompt(); - } - case CHANGE_PRICE -> { - return new ChangePricePrompt(); - } - }; - return null; - } - - private void openGui() { - player.abandonConversation(conversation); - ShopManagementGui shopManagementGui = new ShopManagementGui(player.getUniqueId(), playerShop); - shopManagementGui.open(); - } - - @Override - public void conversationAbandoned(@NotNull ConversationAbandonedEvent abandonedEvent) { -// abandonedEvent.getContext().getForWhom().sendRawMessage("Conversation ended."); - } - - private class ChangeTypePrompt extends FixedSetPrompt { - - public ChangeTypePrompt() { - super("buy", "sell", "none", "random"); - } - - public @NotNull Component getPromptMessage(ConversationContext context) { - return Util.parseMiniMessage("What shoptype would you like to use: " + Joiner.on(", ").join(fixedSet) + " Type cancel to cancel this action."); - } - - @Override - protected Prompt acceptValidatedInput(ConversationContext context, String input) { - ShopType newType = ShopType.fromString(input); - playerShop.setShopType(newType); - openGui(); - return END_OF_CONVERSATION; - } - - } - - private class ChangePricePrompt extends NumericPrompt { - - public @NotNull Component getPromptMessage(ConversationContext context) { - return Util.parseMiniMessage(MessageConfig.CHANGE_PRICE_PROMPT); - } - - @Override - protected boolean isNumberValid(ConversationContext context, Number input) { - return input.doubleValue() >= 0; - } - - @Override - protected String getFailedValidationText(ConversationContext context, Number invalidInput) { - return MessageConfig.CHANGE_PRICE_FAILED_PROMPT; - } - - @Override - protected Prompt acceptValidatedInput(ConversationContext context, Number number) { - playerShop.setPrice(number.doubleValue()); - openGui(); - return END_OF_CONVERSATION; - } - - } - - private class ChangeAmountPrompt extends NumericPrompt { - - public @NotNull Component getPromptMessage(ConversationContext context) { - return Util.parseMiniMessage(MessageConfig.CHANGE_AMOUNT_PROMPT); - } - - @Override - protected boolean isNumberValid(ConversationContext context, Number input) { - return input.intValue() > 0 && input.intValue() <= 64; - } - - @Override - protected String getFailedValidationText(ConversationContext context, Number invalidInput) { - return MessageConfig.CHANGE_AMOUNT_FAILED_PROMPT; - } - - @Override - protected Prompt acceptValidatedInput(ConversationContext context, Number number) { - playerShop.setAmount(number.intValue()); - openGui(); - return END_OF_CONVERSATION; - } - - } - - private class AddBalancePrompt extends NumericPrompt { - - public @NotNull Component getPromptMessage(ConversationContext context) { - return Util.parseMiniMessage(MessageConfig.ADD_BALANCE_PROMPT); - } - - @Override - protected boolean isNumberValid(ConversationContext context, Number input) { - if (input.doubleValue() < 0) - return false; - return EconomyUtils.hasSufficientFunds(player, input.doubleValue()); - } - - @Override - protected String getFailedValidationText(ConversationContext context, Number invalidInput) { - return MessageConfig.ADD_BALANCE_FAILED_PROMPT; - } - - @Override - protected Prompt acceptValidatedInput(ConversationContext context, Number number) { - playerShop.addBalance(number.doubleValue()); - EconomyUtils.removeFunds(player, number.doubleValue()); - openGui(); - return END_OF_CONVERSATION; - } - - } - - private class WithdrawBalancePrompt extends NumericPrompt { - - public @NotNull Component getPromptMessage(ConversationContext context) { - return Util.parseMiniMessage(MessageConfig.WITHDRAW_BALANCE_PROMPT); - } - - @Override - protected boolean isNumberValid(ConversationContext context, Number input) { - if (input.doubleValue() < 0) - return false; - return EconomyUtils.hasSufficientFunds(playerShop, input.doubleValue()); - } - - @Override - protected String getFailedValidationText(ConversationContext context, Number invalidInput) { - return MessageConfig.WITHDRAW_BALANCE_FAILED_PROMPT; - } - - @Override - protected Prompt acceptValidatedInput(ConversationContext context, Number number) { - playerShop.removeBalance(number.doubleValue()); - EconomyUtils.addFunds(player, number.doubleValue()); - openGui(); - return END_OF_CONVERSATION; - } - - } - - private class ChangeItemPrompt extends FixedSetPrompt { - - ChangeItemPrompt() { - super("continue"); - } - - public @NotNull Component getPromptMessage(ConversationContext context) { - return Util.parseMiniMessage(MessageConfig.CHANGE_ITEM_PROMPT); - } - - @Override - protected Prompt acceptValidatedInput(ConversationContext context, String input) { - playerShop.setItemStack(player.getInventory().getItemInMainHand().clone()); - openGui(); - return END_OF_CONVERSATION; - } - - } - -} diff --git a/src/main/java/com/alttd/playershops/conversation/ConversationType.java b/src/main/java/com/alttd/playershops/conversation/ConversationType.java deleted file mode 100644 index 6c6d6cb..0000000 --- a/src/main/java/com/alttd/playershops/conversation/ConversationType.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.alttd.playershops.conversation; - -public enum ConversationType { - CHANGE_ITEM, - CHANGE_AMOUNT, - CHANGE_TYPE, - CHANGE_PRICE, - WITHDRAW_BALANCE, - ADD_BALANCE; -} diff --git a/src/main/java/com/alttd/playershops/dialog/AbstractDialog.java b/src/main/java/com/alttd/playershops/dialog/AbstractDialog.java new file mode 100644 index 0000000..b8d7ff2 --- /dev/null +++ b/src/main/java/com/alttd/playershops/dialog/AbstractDialog.java @@ -0,0 +1,83 @@ +package com.alttd.playershops.dialog; + +import io.papermc.paper.dialog.Dialog; +import io.papermc.paper.registry.data.dialog.ActionButton; +import io.papermc.paper.registry.data.dialog.action.DialogAction; +import io.papermc.paper.registry.data.dialog.body.DialogBody; +import io.papermc.paper.registry.data.dialog.input.DialogInput; +import net.kyori.adventure.text.event.ClickCallback; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public abstract class AbstractDialog { + + Dialog dialog; + protected final int INV_SIZE = 54; + UUID uuid; + AbstractDialog lastDialog; + List actions = new ArrayList<>(); + List inputs = new ArrayList<>(); + List texts = new ArrayList<>(); + ActionButton closeButton; + + AbstractDialog(UUID uuid) { + this.uuid = uuid; + this.lastDialog = null; + closeButton = ActionButton.builder(MiniMessage.miniMessage().deserialize("Go back")).action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + if (!hasLastGui()) { + return; + } + lastDialog.open(); + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ).build(); + } + + abstract Dialog initDialog(); + + public void open() { + if (dialog == null) + return; + + Player player = getPlayer(); + if (player != null) { +// player.closeDialog(); + player.showDialog(dialog); + } + } + + void close() { + Player player = getPlayer(); + if (player != null) { + player.closeInventory(); + } + } + + void initContents() { + } + + Player getPlayer() { + return Bukkit.getPlayer(uuid); + } + + public void setLastGui(AbstractDialog lastDialog) { + this.lastDialog = lastDialog; + } + + public boolean hasLastGui() { + return this.lastDialog != null; + } +} diff --git a/src/main/java/com/alttd/playershops/dialog/ListPlayersDialog.java b/src/main/java/com/alttd/playershops/dialog/ListPlayersDialog.java new file mode 100644 index 0000000..f3aea91 --- /dev/null +++ b/src/main/java/com/alttd/playershops/dialog/ListPlayersDialog.java @@ -0,0 +1,90 @@ +package com.alttd.playershops.dialog; + +import com.alttd.playershops.PlayerShops; +import com.alttd.playershops.config.MessageConfig; +import io.papermc.paper.dialog.Dialog; +import io.papermc.paper.registry.data.dialog.ActionButton; +import io.papermc.paper.registry.data.dialog.DialogBase; +import io.papermc.paper.registry.data.dialog.action.DialogAction; +import io.papermc.paper.registry.data.dialog.type.DialogType; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickCallback; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.object.ObjectContents; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.time.Duration; +import java.util.List; +import java.util.UUID; + +public class ListPlayersDialog extends AbstractDialog { + + private final List owners; + + public ListPlayersDialog(UUID uuid) { + super(uuid); + this.owners = PlayerShops.getInstance().getShopHandler().getShopOwnersForThisServer(); + dialog = initDialog(); + } + + @Override + Dialog initDialog() { + if (getPlayer() == null) { + return null; + } + initContents(); + + return Dialog.create(dialogRegistryBuilderFactory -> + dialogRegistryBuilderFactory.empty() + .type(DialogType.multiAction( + actions, + closeButton, + 3) + ) + .base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_LIST_PLAYERS_TITLE)) + .body(texts) + .inputs(inputs) + .afterAction(DialogBase.DialogAfterAction.CLOSE) + .build() + ) + ); + } + + @Override + void initContents() { + super.initContents(); + + for (UUID shopOwnerUUID : owners) { + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(shopOwnerUUID); + String playerName; + if (!offlinePlayer.hasPlayedBefore()) { + playerName = "Unknown"; + } else { + playerName = offlinePlayer.getName(); + } + + actions.add( + ActionButton.builder( + Component.object(ObjectContents.playerHead(shopOwnerUUID)).append(Component.space().append(Component.text(playerName)))) + .action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + ListShopsDialog listShopsDialog = new ListShopsDialog(uuid, shopOwnerUUID); + listShopsDialog.setLastGui(this); + listShopsDialog.open(); + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ) + .build() + ); + } + } + +} diff --git a/src/main/java/com/alttd/playershops/dialog/ListShopsDialog.java b/src/main/java/com/alttd/playershops/dialog/ListShopsDialog.java new file mode 100644 index 0000000..978f311 --- /dev/null +++ b/src/main/java/com/alttd/playershops/dialog/ListShopsDialog.java @@ -0,0 +1,161 @@ +package com.alttd.playershops.dialog; + +import com.alttd.playershops.PlayerShops; +import com.alttd.playershops.config.MessageConfig; +import com.alttd.playershops.shop.PlayerShop; +import com.alttd.playershops.shop.ShopType; +import com.alttd.playershops.utils.EconomyUtils; +import com.alttd.playershops.utils.ShopUtil; +import io.papermc.paper.dialog.Dialog; +import io.papermc.paper.registry.data.dialog.ActionButton; +import io.papermc.paper.registry.data.dialog.DialogBase; +import io.papermc.paper.registry.data.dialog.action.DialogAction; +import io.papermc.paper.registry.data.dialog.body.DialogBody; +import io.papermc.paper.registry.data.dialog.type.DialogType; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickCallback; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.time.Duration; +import java.util.List; +import java.util.UUID; + +public class ListShopsDialog extends AbstractDialog { + + List shops; + UUID playerToList; + Component title; + TagResolver placeholders; + + public ListShopsDialog(UUID uuid, UUID playerToList) { + super(uuid); + this.playerToList = playerToList; + this.shops = PlayerShops.getInstance().getShopHandler().getShops(this.playerToList); + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(this.playerToList); + + placeholders = TagResolver.resolver( + Placeholder.unparsed("playername", offlinePlayer.hasPlayedBefore() ? offlinePlayer.getName() : "Unknown") + ); + title = MiniMessage.miniMessage().deserialize(MessageConfig.GUI_LIST_SHOPS_TITLE, placeholders); + + dialog = initDialog(); + } + + public ListShopsDialog(UUID uuid, List playerShops) { + super(uuid); + this.shops = playerShops; + + placeholders = TagResolver.resolver( + Placeholder.unparsed("material", "Unknown") + ); + title = MiniMessage.miniMessage().deserialize("Shops per item"); + + dialog = initDialog(); + } + + @Override + Dialog initDialog() { + if (getPlayer() == null) { + return null; + } + + initContents(); + return Dialog.create(dialogRegistryBuilderFactory -> + dialogRegistryBuilderFactory.empty() + .type(DialogType.multiAction( + actions, + closeButton, + 3) + ) + .base(DialogBase.builder(title) + .body(texts) + .inputs(inputs) + .afterAction(DialogBase.DialogAfterAction.CLOSE) + .build() + ) + ); + } + + @Override + void initContents() { + super.initContents(); + + texts.add(DialogBody.plainMessage(MiniMessage.miniMessage().deserialize("This menu will not display shops that are not initialized"))); + + for (PlayerShop shop : shops) { + if (!shop.isInitialized()) { + continue; + } + actions.add( + ActionButton.builder( + ShopUtil.spriteComponent(shop.getItemStack())) + .tooltip(shop.getHoverComponent(getPlayer())) + .action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + if (!ShopUtil.canManageShop(player, shop)) { + return; + } + + ManageShopDialog manageShopDialog = new ManageShopDialog(player.getUniqueId(), shop); + manageShopDialog.setLastGui(this); + manageShopDialog.open(); + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ) + .build() + ); + } + if (uuid != null && uuid.equals(playerToList) && getPlayer().hasPermission("playershops.shop.collectall")) { + actions.add( + ActionButton.builder( + MiniMessage.miniMessage().deserialize("Collect sales")) + .tooltip(MiniMessage.miniMessage().deserialize("Click to collect all balance from your shops.")) + .action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + double d = 0; + int count = 0; + for (PlayerShop playerShop : shops) { + if (!ShopUtil.canManageShop(player, playerShop)) + continue; + + if (playerShop.getType().equals(ShopType.BUY)) + continue; + + double balance = playerShop.getBalance(); + if (balance == 0) + continue; + + playerShop.removeBalance(balance); + EconomyUtils.addFunds(player, balance); + d += balance; + count++; + } + TagResolver placeholders = TagResolver.resolver( + Placeholder.parsed("balance", String.valueOf(d)), + Placeholder.parsed("count", String.valueOf(count)) + ); + player.sendRichMessage(count > 0 ? "You have collected from shops." : "No shops to be collected from.", placeholders); + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .build()) + ) + .build() + ); + } + } +} diff --git a/src/main/java/com/alttd/playershops/dialog/ManageShopDialog.java b/src/main/java/com/alttd/playershops/dialog/ManageShopDialog.java new file mode 100644 index 0000000..6e56473 --- /dev/null +++ b/src/main/java/com/alttd/playershops/dialog/ManageShopDialog.java @@ -0,0 +1,211 @@ +package com.alttd.playershops.dialog; + +import com.alttd.playershops.shop.PlayerShop; +import com.alttd.playershops.shop.ShopType; +import com.alttd.playershops.utils.EconomyUtils; +import com.alttd.playershops.utils.ShopUtil; +import com.alttd.playershops.utils.Util; +import io.papermc.paper.dialog.Dialog; +import io.papermc.paper.registry.data.dialog.ActionButton; +import io.papermc.paper.registry.data.dialog.DialogBase; +import io.papermc.paper.registry.data.dialog.action.DialogAction; +import io.papermc.paper.registry.data.dialog.body.DialogBody; +import io.papermc.paper.registry.data.dialog.input.DialogInput; +import io.papermc.paper.registry.data.dialog.input.SingleOptionDialogInput; +import io.papermc.paper.registry.data.dialog.type.DialogType; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickCallback; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +public class ManageShopDialog extends AbstractDialog { + + PlayerShop shop; + + public ManageShopDialog(UUID uuid, PlayerShop shop) { + super(uuid); + this.shop = shop; + dialog = initDialog(); + } + + @Override + Dialog initDialog() { + if (getPlayer() == null) { + return null; + } + initContents(); + + return Dialog.create(dialogRegistryBuilderFactory -> + dialogRegistryBuilderFactory.empty() + .type(DialogType.multiAction( + actions, + closeButton, + 3) + ) + .base(DialogBase.builder(MiniMessage.miniMessage().deserialize("PlayerShop - ", Placeholder.component("playername", getPlayer().displayName()))) + .body(texts) + .inputs(inputs) + .afterAction(DialogBase.DialogAfterAction.CLOSE) + .build() + ) + ); + } + + @Override + void initContents() { + super.initContents(); + + inputs.add( + DialogInput.singleOption("shoptype", MiniMessage.miniMessage().deserialize("ShopType"), + Arrays.stream(ShopType.values()).map( + shopType -> SingleOptionDialogInput.OptionEntry.create(shopType.name(), MiniMessage.miniMessage().deserialize("" + shopType.name()), shop.getType() == shopType) + ).toList()) + .build() + ); + + inputs.add( + DialogInput.text("balance", MiniMessage.miniMessage().deserialize("Balance")) + .initial(String.valueOf(shop.getBalance())) + .width(300) + .build() + ); + inputs.add( + DialogInput.bool("changeitem", MiniMessage.miniMessage().deserialize("Change item?")) + .initial(false) + .build() + ); + inputs.add( + DialogInput.singleOption("item", MiniMessage.miniMessage().deserialize("Item"), itemEntries()).build() + ); + int maxQty = (shop.isInitialized() ? shop.getItemStack().getMaxStackSize() : 64); + int initialQty = (shop.isInitialized() ? Math.min(shop.getAmount(), maxQty) : 1); + inputs.add( + DialogInput.numberRange("amount", MiniMessage.miniMessage().deserialize("Change amount"), 1f, (float) maxQty) + .step(1f) + .initial((float) initialQty) + .width(300) + .build() + ); + inputs.add( + DialogInput.text("price", MiniMessage.miniMessage().deserialize("Change price")) + .initial(String.valueOf(shop.getPrice())) + .width(300) + .build() + ); + ActionButton saveButton = ActionButton.builder(MiniMessage.miniMessage().deserialize("Confirm")).action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + if (!ShopUtil.canManageShop(player, shop)) { + return; + } + + // Change type + String shopTypeString = view.getText("shoptype"); + ShopType shopType = ShopType.fromString(shopTypeString); + if (shop.getType() != shopType) { + shop.setShopType(shopType); + } + + // Change Balance + String balanceString = view.getText("balance"); + if (balanceString != null && !balanceString.isBlank()) { + Double balance; + try { + balance = EconomyUtils.parseValue(balanceString); + if (balance != null && balance >= 0) { + if (balance != shop.getBalance()) { + double difference = balance - shop.getBalance(); + if (difference >= 0) { + if (EconomyUtils.hasSufficientFunds(player, difference)) { + shop.addBalance(difference); + EconomyUtils.removeFunds(player, difference); + } + } else if (difference <= 0) { + double diff = -1 * difference; + if (EconomyUtils.hasSufficientFunds(shop, diff)) { + shop.removeBalance(diff); + EconomyUtils.addFunds(player, diff); + } + } + } + } + } catch (NumberFormatException ignored) {} + } + + // Change Item + if (Boolean.TRUE.equals(view.getBoolean("changeitem"))) { + String selection = view.getText("item"); + if (selection != null) { + if (selection.equalsIgnoreCase("reset")) { + shop.setItemStack(null); + } + int slot; + try { + slot = Integer.parseInt(selection); + shop.setItemStack(player.getInventory().getItem(slot)); + } catch (NumberFormatException ignored) {} + } + } + + // Change Amount + int amount = view.getFloat("amount").intValue(); + if (amount != shop.getAmount()) { + shop.setAmount(amount); + } + + // Change Price + String priceString = view.getText("price"); + if (priceString != null && !priceString.isBlank()) { + Double price = EconomyUtils.parseValue(priceString); + if (price != null && price >= 0) { + if (price != shop.getPrice()) { + shop.setPrice(price); + } + } + } + + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ).build(); + actions.add(saveButton); + } + + List itemEntries() { + List optionEntries = new ArrayList<>(); + + if (getPlayer() == null) { + return optionEntries; + } + + optionEntries.add( + SingleOptionDialogInput.OptionEntry.create("reset", MiniMessage.miniMessage().deserialize("Reset"), false) + ); + + for (int i = 0; i < getPlayer().getInventory().getSize() ; i++) { + ItemStack item = getPlayer().getInventory().getItem(i); + if (item == null || item.getType() == Material.AIR) continue; + optionEntries.add( + SingleOptionDialogInput.OptionEntry.create(String.valueOf(i), ShopUtil.spriteComponent(item), shop.getItemStack() == item) + ); + } + + return optionEntries; + } + +} diff --git a/src/main/java/com/alttd/playershops/dialog/SearchShopsDialog.java b/src/main/java/com/alttd/playershops/dialog/SearchShopsDialog.java new file mode 100644 index 0000000..7ca72d8 --- /dev/null +++ b/src/main/java/com/alttd/playershops/dialog/SearchShopsDialog.java @@ -0,0 +1,79 @@ +package com.alttd.playershops.dialog; + +import com.alttd.playershops.PlayerShops; +import com.alttd.playershops.config.MessageConfig; +import com.alttd.playershops.shop.PlayerShop; +import com.alttd.playershops.utils.ShopUtil; +import io.papermc.paper.dialog.Dialog; +import io.papermc.paper.registry.data.dialog.ActionButton; +import io.papermc.paper.registry.data.dialog.DialogBase; +import io.papermc.paper.registry.data.dialog.action.DialogAction; +import io.papermc.paper.registry.data.dialog.type.DialogType; +import net.kyori.adventure.text.event.ClickCallback; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.time.Duration; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public class SearchShopsDialog extends AbstractDialog { + + List shops; + + public SearchShopsDialog(UUID uuid) { + super(uuid); +// this.shops = PlayerShops.getInstance().getShopHandler().getShops(playerToList); + + dialog = initDialog(); + } + + @Override + Dialog initDialog() { + if (getPlayer() == null) { + return null; + } + + initContents(); + return Dialog.create(dialogRegistryBuilderFactory -> + dialogRegistryBuilderFactory.empty() + .type(DialogType.multiAction( + actions, + closeButton, + 5) + ) + .base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_LIST_SHOPS_TITLE)) + .body(texts) + .inputs(inputs) + .afterAction(DialogBase.DialogAfterAction.CLOSE) + .build() + ) + ); + } + + @Override + void initContents() { + super.initContents(); + + for (Map.Entry> entry : PlayerShops.getInstance().getShopHandler().shopByMaterial().entrySet()) { + actions.add(ActionButton.builder(ShopUtil.spriteComponent(entry.getKey())) + .action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + ListShopsDialog listShopsDialog = new ListShopsDialog(uuid, entry.getValue()); + listShopsDialog.setLastGui(this); + listShopsDialog.open(); + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ) + .build()); + } + } +} diff --git a/src/main/java/com/alttd/playershops/dialog/ShopDialog.java b/src/main/java/com/alttd/playershops/dialog/ShopDialog.java new file mode 100644 index 0000000..e5e592d --- /dev/null +++ b/src/main/java/com/alttd/playershops/dialog/ShopDialog.java @@ -0,0 +1,135 @@ +package com.alttd.playershops.dialog; + +import com.alttd.playershops.PlayerShops; +import com.alttd.playershops.config.MessageConfig; +import com.alttd.playershops.utils.ShopUtil; +import io.papermc.paper.dialog.Dialog; +import io.papermc.paper.registry.data.dialog.ActionButton; +import io.papermc.paper.registry.data.dialog.DialogBase; +import io.papermc.paper.registry.data.dialog.action.DialogAction; +import io.papermc.paper.registry.data.dialog.type.DialogType; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickCallback; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.object.ObjectContents; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.time.Duration; +import java.util.List; +import java.util.UUID; + +public class ShopDialog extends AbstractDialog { + + public ShopDialog(UUID uuid) { + super(uuid); + dialog = initDialog(); + } + + @Override + Dialog initDialog() { + if (getPlayer() == null) { + return null; + } + initContents(); + + return Dialog.create(dialogRegistryBuilderFactory -> + dialogRegistryBuilderFactory.empty() + .type(DialogType.multiAction( + actions, + closeButton, + 3) + ) + .base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_HOME_TITLE)) + .body(texts) + .inputs(inputs) + .afterAction(DialogBase.DialogAfterAction.CLOSE) + .build() + ) + ); + } + + @Override + void initContents() { + super.initContents(); + + actions.add( + ActionButton.builder( + MiniMessage.miniMessage().deserialize("Your shops")) + .action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + ListShopsDialog abstractDialog = new ListShopsDialog(uuid, uuid); + abstractDialog.setLastGui(this); + abstractDialog.open(); + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ) + .build() + ); + actions.add( + ActionButton.builder( + MiniMessage.miniMessage().deserialize("All shops")) + .action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + ListPlayersDialog abstractDialog = new ListPlayersDialog(uuid); + abstractDialog.setLastGui(this); + abstractDialog.open(); + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ) + .build() + ); + actions.add( + ActionButton.builder( + MiniMessage.miniMessage().deserialize("Shops per item")) + .action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + SearchShopsDialog abstractDialog = new SearchShopsDialog(uuid); + abstractDialog.setLastGui(this); + abstractDialog.open(); + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ) + .build() + ); + actions.add( + ActionButton.builder( + MiniMessage.miniMessage().deserialize("Settings")) + .action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + ShopSettingsDialog abstractDialog = new ShopSettingsDialog(uuid); + abstractDialog.setLastGui(this); + abstractDialog.open(); + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ) + .build() + ); + } + +} diff --git a/src/main/java/com/alttd/playershops/dialog/ShopSettingsDialog.java b/src/main/java/com/alttd/playershops/dialog/ShopSettingsDialog.java new file mode 100644 index 0000000..1063556 --- /dev/null +++ b/src/main/java/com/alttd/playershops/dialog/ShopSettingsDialog.java @@ -0,0 +1,97 @@ +package com.alttd.playershops.dialog; + +import com.alttd.playershops.PlayerShops; +import com.alttd.playershops.config.MessageConfig; +import com.alttd.playershops.shop.PlayerSettings; +import io.papermc.paper.dialog.Dialog; +import io.papermc.paper.registry.data.dialog.ActionButton; +import io.papermc.paper.registry.data.dialog.DialogBase; +import io.papermc.paper.registry.data.dialog.action.DialogAction; +import io.papermc.paper.registry.data.dialog.input.DialogInput; +import io.papermc.paper.registry.data.dialog.type.DialogType; +import it.unimi.dsi.fastutil.objects.Object2BooleanMap; +import net.kyori.adventure.text.event.ClickCallback; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.entity.Player; + +import java.time.Duration; +import java.util.UUID; + +public class ShopSettingsDialog extends AbstractDialog { + + PlayerSettings playerSettings; + public ShopSettingsDialog(UUID uuid) { + super(uuid); + playerSettings = PlayerShops.getInstance().getShopHandler().getPlayerSettings(uuid); + dialog = initDialog(); + } + + @Override + Dialog initDialog() { + if (getPlayer() == null) { + return null; + } + initContents(); + + return Dialog.create(dialogRegistryBuilderFactory -> + dialogRegistryBuilderFactory.empty() + .type(DialogType.multiAction( + actions, + closeButton, + 1) + ) + .base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_PLAYER_SETTINGS_TITLE)) + .body(texts) + .inputs(inputs) + .afterAction(DialogBase.DialogAfterAction.CLOSE) + .build() + ) + ); + } + + @Override + void initContents() { + super.initContents(); + + for(Object2BooleanMap.Entry entry : playerSettings.optionsMap.object2BooleanEntrySet()) { + String setting = entry.getKey().name(); + System.out.println(setting); + inputs.add( + DialogInput.bool(setting, MiniMessage.miniMessage().deserialize("" + entry.getKey().toString() + "")) + .initial(playerSettings.getOption(entry.getKey())) + .build() + ); + } + actions.add( + ActionButton.builder(MiniMessage.miniMessage().deserialize("Confirm")).action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + +// if (Boolean.TRUE.equals(view.getBoolean("changeitem"))) { +// +// } + + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ).build() + ); + actions.add( + ActionButton.builder(MiniMessage.miniMessage().deserialize("Set shop default values")).action( + DialogAction.customClick((view, audience) -> { + if (!(audience instanceof Player player)) { + return; + } + + }, ClickCallback.Options.builder() + .lifetime(Duration.ofMinutes(5)) + .uses(-1) + .build()) + ).build() + ); + } + +} diff --git a/src/main/java/com/alttd/playershops/gui/AbstractGui.java b/src/main/java/com/alttd/playershops/gui/AbstractGui.java deleted file mode 100644 index 57b2842..0000000 --- a/src/main/java/com/alttd/playershops/gui/AbstractGui.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.alttd.playershops.gui; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.UUID; - -public abstract class AbstractGui implements InventoryHolder { - - Inventory inventory; - protected final int INV_SIZE = 54; - int currentSlot; - UUID uuid; - int pageIndex; - AbstractGui lastGui; - - - AbstractGui(UUID uuid) { - this.uuid = uuid; - this.currentSlot = 0; - this.lastGui = null; - } - - public void open() { - Player player = getPlayer(); - if (player != null) { - player.openInventory(inventory); - } - } - - boolean close() { - Player player = getPlayer(); - if (player != null) { - player.closeInventory(); - return true; - } - return false; - } - - void scrollPageNext() { - ItemStack nextPageIcon = inventory.getItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot()); - if (nextPageIcon != null && nextPageIcon.equals(getNextPageIcon())) { - inventory.setItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot(), getPrevPageIcon()); - ++pageIndex; - initInvContents(); - } - } - - void scrollPagePrev() { - ItemStack prevPageIcon = inventory.getItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot()); - if (prevPageIcon != null && prevPageIcon.equals(getPrevPageIcon())) { - inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), getNextPageIcon()); - --pageIndex; - if (pageIndex == 0) { - inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), null); - } - initInvContents(); - } - } - - protected boolean addItem(int slot, ItemStack icon) { - currentSlot = slot; - return addItem(icon); - } - - protected boolean addItem(ItemStack icon) { - if (currentSlot == inventory.getSize() - 9) - return false; - - inventory.setItem(currentSlot, icon); - currentSlot++; - - return true; - } - - void initInvContents() { - clearInvBody(); - currentSlot = 0; - } - - protected void clearInvBody() { - for (int i = 0; i < inventory.getSize() - 9; ++i) { -// inventory.setItem(i, null); - inventory.setItem(i, getDivider()); - } - } - - void makeMenuBar() { - for (int i = inventory.getSize() - 9; i < inventory.getSize(); ++i) { - inventory.setItem(i, getDivider()); - } - } - - Player getPlayer() { - return Bukkit.getPlayer(uuid); - } - - @NotNull - @Override - public Inventory getInventory() { - return inventory; - } - - ItemStack getPrevPageIcon() { - return GuiIcon.MENUBAR_PREV_PAGE.getItemStack(); - } - - ItemStack getNextPageIcon() { - return GuiIcon.MENUBAR_NEXT_PAGE.getItemStack(); - } - - ItemStack getExitIcon() { - return null; - } - - ItemStack getDivider() { - return GuiIcon.DIVIDER.getItemStack(); - } - - public void onClick(int slot, ItemStack item) { - // TODO a better way to do this. - // check all menu actions here - if (slot == GuiIcon.MENUBAR_BACK.getSlot() && GuiIcon.MENUBAR_BACK.getItemStack().equals(item)) { - if (hasLastGui()) - lastGui.open(); - } else if (slot == GuiIcon.MENUBAR_EXIT.getSlot() && GuiIcon.MENUBAR_EXIT.getItemStack().equals(item)) { - getPlayer().closeInventory(); - } else if (slot == GuiIcon.MENUBAR_SEARCH.getSlot() && GuiIcon.MENUBAR_SEARCH.getItemStack().equals(item)) { - // TODO - } else if (slot == GuiIcon.MENUBAR_PREV_PAGE.getSlot() && GuiIcon.MENUBAR_PREV_PAGE.getItemStack().equals(item)) { - scrollPagePrev(); - } else if (slot == GuiIcon.MENUBAR_NEXT_PAGE.getSlot() && GuiIcon.MENUBAR_NEXT_PAGE.getItemStack().equals(item)) { - scrollPageNext(); - } - } - - public void setLastGui(AbstractGui lastGui) { - this.lastGui = lastGui; - inventory.setItem(GuiIcon.MENUBAR_BACK.getSlot(), GuiIcon.MENUBAR_BACK.getItemStack()); - } - - public boolean hasLastGui() { - return lastGui != null; - } - - void addPrevPageItem() { - inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), GuiIcon.MENUBAR_PREV_PAGE.getItemStack()); - } - - void addNextPageItem() { - inventory.setItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot(), GuiIcon.MENUBAR_NEXT_PAGE.getItemStack()); - } - -} diff --git a/src/main/java/com/alttd/playershops/gui/GuiIcon.java b/src/main/java/com/alttd/playershops/gui/GuiIcon.java deleted file mode 100644 index a185faa..0000000 --- a/src/main/java/com/alttd/playershops/gui/GuiIcon.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.alttd.playershops.gui; - -import com.alttd.playershops.config.GuiIconConfig; -import com.alttd.playershops.utils.Util; -import lombok.Getter; -import net.kyori.adventure.text.Component; -import org.bukkit.Material; -import org.bukkit.inventory.ItemFlag; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.ArrayList; -import java.util.List; - -public enum GuiIcon { - DIVIDER, - MENUBAR_BACK, - MENUBAR_EXIT, - MENUBAR_SEARCH, - MENUBAR_PREV_PAGE, - MENUBAR_NEXT_PAGE, - - MANAGE_SHOP, - MANAGE_SHOP_BALANCE_ADD, - MANAGE_SHOP_BALANCE_REMOVE, - MANAGE_SHOP_SALES, - MANAGE_SHOP_ITEM, - MANAGE_SHOP_TYPE, - MANAGE_SHOP_AMOUNT, - MANAGE_SHOP_PRICE, - MANAGE_SHOP_COLLECT_SALES, - MANAGE_SHOP_COLLECT_SALE, - - HOME_LIST_OWN_SHOPS, - HOME_LIST_PLAYERS, - HOME_SETTINGS, - LIST_SHOP, - LIST_PLAYER, - LIST_PLAYER_ADMIN, - EMPTY_SHOP, - - SETTING_ON, - SETTING_OFF; - - @Getter - private final int slot; - @Getter - private final ItemStack itemStack; - - GuiIcon() { - GuiIconConfig config = new GuiIconConfig(this.toString()); - this.slot = config.slot; - this.itemStack = createItem(config.material, config.displayName, config.lore); - } - - private ItemStack createItem(String materialString, String displayName, List itemlore) { - Material material = Material.getMaterial(materialString); - if (material == null) - return null; - - ItemStack item = new ItemStack(material); - ItemMeta itemMeta = item.getItemMeta(); - itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); - itemMeta.displayName(format(displayName)); - List lore = new ArrayList<>(); - for (String line : itemlore) { - lore.add(format(line)); - } - itemMeta.lore(lore); - item.setItemMeta(itemMeta); - - return item; - } - - private Component format(String s) { - return Util.parseMiniMessage(s); - } - - @Override - public String toString() { - return name().toLowerCase(); - } -} diff --git a/src/main/java/com/alttd/playershops/gui/HomeGui.java b/src/main/java/com/alttd/playershops/gui/HomeGui.java deleted file mode 100644 index 93e0704..0000000 --- a/src/main/java/com/alttd/playershops/gui/HomeGui.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.alttd.playershops.gui; - -import com.alttd.playershops.config.MessageConfig; -import com.alttd.playershops.utils.Util; -import org.bukkit.Bukkit; -import org.bukkit.inventory.ItemStack; - -import java.util.UUID; - -public class HomeGui extends AbstractGui { - - public HomeGui(UUID uuid) { - super(uuid); - this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_HOME_TITLE)); - makeMenuBar(); - initInvContents(); - } - - @Override - void initInvContents() { - super.initInvContents(); - inventory.setItem(GuiIcon.HOME_LIST_OWN_SHOPS.getSlot(), GuiIcon.HOME_LIST_OWN_SHOPS.getItemStack()); - inventory.setItem(GuiIcon.HOME_LIST_PLAYERS.getSlot(), GuiIcon.HOME_LIST_PLAYERS.getItemStack()); - inventory.setItem(GuiIcon.HOME_SETTINGS.getSlot(), GuiIcon.HOME_SETTINGS.getItemStack()); - } - - @Override - public void onClick(int slot, ItemStack item) { - super.onClick(slot, item); - - if (slot >= 45) - return; - - if (slot == GuiIcon.HOME_LIST_OWN_SHOPS.getSlot() && GuiIcon.HOME_LIST_OWN_SHOPS.getItemStack().equals(item)) { - ListShopsGui listShopsGui = new ListShopsGui(uuid, uuid); - listShopsGui.setLastGui(this); - listShopsGui.open(); - } else if (slot == GuiIcon.HOME_LIST_PLAYERS.getSlot() && GuiIcon.HOME_LIST_PLAYERS.getItemStack().equals(item)) { - ListPlayersGui listPlayersGui = new ListPlayersGui(uuid); - listPlayersGui.setLastGui(this); - listPlayersGui.open(); - }/* else if (slot == GuiIcon.HOME_SETTINGS.getSlot() && GuiIcon.HOME_SETTINGS.getItemStack().equals(item)) { - PlayerSettingsGui playerSettingsGui = new PlayerSettingsGui(uuid); - playerSettingsGui.setLastGui(this); - playerSettingsGui.open(); - }*/ - } -} diff --git a/src/main/java/com/alttd/playershops/gui/ListPlayersGui.java b/src/main/java/com/alttd/playershops/gui/ListPlayersGui.java deleted file mode 100644 index bf04578..0000000 --- a/src/main/java/com/alttd/playershops/gui/ListPlayersGui.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.alttd.playershops.gui; - -import com.alttd.playershops.PlayerShops; -import com.alttd.playershops.config.MessageConfig; -import com.alttd.playershops.utils.ShopUtil; -import com.alttd.playershops.utils.Util; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; - -import java.util.List; -import java.util.UUID; - -public class ListPlayersGui extends AbstractGui { - - private final List owners; - public ListPlayersGui(UUID uuid) { - super(uuid); - this.owners = PlayerShops.getInstance().getShopHandler().getShopOwnersForThisServer(); - this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_LIST_PLAYERS_TITLE)); - makeMenuBar(); - initInvContents(); - } - - @Override - void initInvContents() { - super.initInvContents(); - - int startIndex = pageIndex * 45; - ItemStack item; - for (int i = startIndex; i < owners.size(); i++) { - item = ShopUtil.getPlayerHead(owners.get(i)); - - if (!addItem(item)) { - addNextPageItem(); - break; - } - } - if (pageIndex > 0) { - addPrevPageItem(); - } - } - - @Override - public void onClick(int slot, ItemStack item) { - super.onClick(slot, item); - - if (slot >= 45) - return; - - if (item.getType() != Material.PLAYER_HEAD) - return; - - int index = pageIndex * 45 + slot; - if (index >= owners.size()) - return; - UUID playerToList = owners.get(index); - - ListShopsGui listShopGUI = new ListShopsGui(uuid, playerToList); - listShopGUI.setLastGui(this); - listShopGUI.open(); - } -} diff --git a/src/main/java/com/alttd/playershops/gui/ListShopsGui.java b/src/main/java/com/alttd/playershops/gui/ListShopsGui.java deleted file mode 100644 index f8f1a03..0000000 --- a/src/main/java/com/alttd/playershops/gui/ListShopsGui.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.alttd.playershops.gui; - -import com.alttd.playershops.PlayerShops; -import com.alttd.playershops.config.MessageConfig; -import com.alttd.playershops.shop.PlayerShop; -import com.alttd.playershops.shop.ShopType; -import com.alttd.playershops.utils.EconomyUtils; -import com.alttd.playershops.utils.ShopUtil; -import com.alttd.playershops.utils.Util; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.List; -import java.util.UUID; - -public class ListShopsGui extends AbstractGui { - - List shops; - UUID playerToList; - - public ListShopsGui(UUID uuid, UUID playerToList) { - super(uuid); - this.playerToList = playerToList; - this.shops = PlayerShops.getInstance().getShopHandler().getShops(playerToList); - OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerToList); - - TagResolver placeholders = TagResolver.resolver( - Placeholder.unparsed("playername", offlinePlayer.hasPlayedBefore() ? offlinePlayer.getName() : "error") - ); - this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_LIST_SHOPS_TITLE, placeholders)); - makeMenuBar(); - initInvContents(); - } - - @Override - void makeMenuBar() { - super.makeMenuBar(); - if (!uuid.equals(playerToList) && getPlayer().hasPermission("playershops.shop.collectall")) - return; - - inventory.setItem(GuiIcon.MANAGE_SHOP_COLLECT_SALES.getSlot(), GuiIcon.MANAGE_SHOP_COLLECT_SALES.getItemStack()); - } - - @Override - void initInvContents() { - super.initInvContents(); - - // Todo add option to sort shops? - - int startIndex = pageIndex * 45; - for (int i = startIndex; i < shops.size(); i++) { - PlayerShop shop = shops.get(i); - ItemStack item = shop.getItemStack(); - if (!shop.isInitialized() || item == null) - item = GuiIcon.EMPTY_SHOP.getItemStack(); - - if (!addItem(item)) { - addNextPageItem(); - break; - } - } - if (pageIndex > 0) { - addPrevPageItem(); - } - - } - - @Override - public void onClick(int slot, ItemStack item) { - super.onClick(slot, item); - - if (slot == GuiIcon.MANAGE_SHOP_COLLECT_SALES.getSlot() && GuiIcon.MANAGE_SHOP_COLLECT_SALES.getItemStack().equals(item)) { - Player player = getPlayer(); - double d = 0; - int count = 0; - for (PlayerShop playerShop : shops) { - if (!ShopUtil.canManageShop(player, playerShop)) - continue; - if (playerShop.getType().equals(ShopType.BUY)) - continue; - - double balance = playerShop.getBalance(); - if (balance == 0) - continue; - playerShop.removeBalance(balance); - EconomyUtils.addFunds(player, balance); - d += balance; - count++; - } - TagResolver placeholders = TagResolver.resolver( - Placeholder.parsed("balance", String.valueOf(d)), - Placeholder.parsed("count", String.valueOf(count)) - ); - player.sendRichMessage(count > 0 ? "You have collected from shops." : "No shops to be collected from.", placeholders); - return; - } - - if (slot >= 45) - return; - - Player player = getPlayer(); - if (player == null) - return; - - int index = pageIndex * 45 + slot; - if (index >= shops.size()) - return; - - PlayerShop playerShop = shops.get(index); - if (playerShop == null) return; - - if (!ShopUtil.canManageShop(player, playerShop)) - return; - - ShopManagementGui shopManagementGui = new ShopManagementGui(player.getUniqueId(), playerShop); - shopManagementGui.setLastGui(this); - shopManagementGui.open(); - } -} diff --git a/src/main/java/com/alttd/playershops/gui/ListTransactionsGui.java b/src/main/java/com/alttd/playershops/gui/ListTransactionsGui.java deleted file mode 100644 index 3a83261..0000000 --- a/src/main/java/com/alttd/playershops/gui/ListTransactionsGui.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.alttd.playershops.gui; - -import com.alttd.playershops.config.MessageConfig; -import com.alttd.playershops.shop.PlayerShop; -import com.alttd.playershops.shop.ShopTransaction; -import com.alttd.playershops.utils.ShopUtil; -import com.alttd.playershops.utils.Util; -import org.bukkit.Bukkit; -import org.bukkit.inventory.ItemStack; - -import java.util.List; -import java.util.UUID; - -public class ListTransactionsGui extends AbstractGui { - - private final List transactions; - public ListTransactionsGui(UUID uuid, PlayerShop shop) { - super(uuid); - this.transactions = shop.getTransactions(); - this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_LIST_TRANSACTIONS_TITLE)); - makeMenuBar(); - initInvContents(); - } - - @Override - void initInvContents() { - super.initInvContents(); - - int startIndex = pageIndex * 45; - ItemStack item; - for (int i = startIndex; i < transactions.size(); i++) { - item = ShopUtil.getShopTransactionItem(transactions.get(i)); - - if (!addItem(item)) { - addNextPageItem(); - break; - } - } - if (pageIndex > 0) { - addPrevPageItem(); - } - } - -} diff --git a/src/main/java/com/alttd/playershops/gui/PlayerSettingsGui.java b/src/main/java/com/alttd/playershops/gui/PlayerSettingsGui.java deleted file mode 100644 index 616ecd7..0000000 --- a/src/main/java/com/alttd/playershops/gui/PlayerSettingsGui.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.alttd.playershops.gui; - -import com.alttd.playershops.PlayerShops; -import com.alttd.playershops.config.MessageConfig; -import com.alttd.playershops.shop.PlayerSettings; -import com.alttd.playershops.utils.Util; -import it.unimi.dsi.fastutil.objects.Object2BooleanMap; -import net.kyori.adventure.text.TextReplacementConfig; -import org.bukkit.Bukkit; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.UUID; - -public class PlayerSettingsGui extends AbstractGui { - - public PlayerSettingsGui(UUID uuid) { - super(uuid); - this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_PLAYER_SETTINGS_TITLE)); - makeMenuBar(); - initInvContents(); - } - - @Override - void initInvContents() { - super.initInvContents(); - int startIndex = pageIndex * 45; - ItemStack item; - - for(Object2BooleanMap.Entry entry : PlayerShops.getInstance().getShopHandler().getPlayerSettings(uuid).optionsMap.object2BooleanEntrySet()) { - item = entry.getBooleanValue() ? GuiIcon.SETTING_ON.getItemStack() : GuiIcon.SETTING_OFF.getItemStack(); - ItemMeta itemMeta = item.getItemMeta(); - if (itemMeta.hasDisplayName()) { - itemMeta.displayName( - itemMeta.displayName().replaceText( - TextReplacementConfig.builder() - .match("") - .replacement(entry.getKey().toString().toLowerCase().replace("_", " ")).build())); - } - item.setItemMeta(itemMeta); - - if (!addItem(item)) { - addNextPageItem(); - break; - } - } - if (pageIndex > 0) { - addPrevPageItem(); - } - } - - @Override - public void onClick(int slot, ItemStack item) { - super.onClick(slot, item); - - if (slot >= 45) - return; - } -} diff --git a/src/main/java/com/alttd/playershops/gui/ShopManagementGui.java b/src/main/java/com/alttd/playershops/gui/ShopManagementGui.java deleted file mode 100644 index 5f6b9ba..0000000 --- a/src/main/java/com/alttd/playershops/gui/ShopManagementGui.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.alttd.playershops.gui; - -import com.alttd.playershops.PlayerShops; -import com.alttd.playershops.config.MessageConfig; -import com.alttd.playershops.conversation.ConversationManager; -import com.alttd.playershops.conversation.ConversationType; -import com.alttd.playershops.shop.PlayerShop; -import com.alttd.playershops.shop.ShopType; -import com.alttd.playershops.utils.EconomyUtils; -import com.alttd.playershops.utils.ShopUtil; -import com.alttd.playershops.utils.Util; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -public class ShopManagementGui extends AbstractGui { - - PlayerShop shop; - - public ShopManagementGui(UUID uuid, PlayerShop shop) { - super(uuid); - this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_MANAGE_TITLE)); - this.shop = shop; - makeMenuBar(); - initInvContents(); - } - - @Override - void initInvContents() { - super.initInvContents(); - - ItemStack shopIcon = GuiIcon.MANAGE_SHOP.getItemStack(); - ItemMeta meta = shopIcon.getItemMeta(); - List lore = new ArrayList<>(); - TagResolver placeholders = TagResolver.resolver( - Placeholder.unparsed("balance", shop.getBalance() + ""), - Placeholder.unparsed("price", shop.getPrice() + ""), - Placeholder.unparsed("amount", shop.getAmount() + ""), - Placeholder.unparsed("shoptype", shop.getType().toString()), - Placeholder.component("itemname", ShopUtil.itemNameComponent(shop.getItemStack())) - ); - lore.add(Util.parseMiniMessage("Balance: ", placeholders)); - lore.add(Util.parseMiniMessage("item: ", placeholders)); - lore.add(Util.parseMiniMessage("amount: ", placeholders)); - lore.add(Util.parseMiniMessage("Type: ", placeholders)); - lore.add(Util.parseMiniMessage("Price: ", placeholders)); - - meta.lore(lore); - shopIcon.setItemMeta(meta); - - inventory.setItem(GuiIcon.MANAGE_SHOP.getSlot(), shopIcon); - inventory.setItem(GuiIcon.MANAGE_SHOP_BALANCE_ADD.getSlot(), GuiIcon.MANAGE_SHOP_BALANCE_ADD.getItemStack()); - inventory.setItem(GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getSlot(), GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getItemStack()); - inventory.setItem(GuiIcon.MANAGE_SHOP_COLLECT_SALE.getSlot(), GuiIcon.MANAGE_SHOP_COLLECT_SALE.getItemStack()); - inventory.setItem(GuiIcon.MANAGE_SHOP_SALES.getSlot(), GuiIcon.MANAGE_SHOP_SALES.getItemStack()); - inventory.setItem(GuiIcon.MANAGE_SHOP_ITEM.getSlot(), GuiIcon.MANAGE_SHOP_ITEM.getItemStack()); - inventory.setItem(GuiIcon.MANAGE_SHOP_TYPE.getSlot(), GuiIcon.MANAGE_SHOP_TYPE.getItemStack()); - inventory.setItem(GuiIcon.MANAGE_SHOP_AMOUNT.getSlot(), GuiIcon.MANAGE_SHOP_AMOUNT.getItemStack()); - inventory.setItem(GuiIcon.MANAGE_SHOP_PRICE.getSlot(), GuiIcon.MANAGE_SHOP_PRICE.getItemStack()); - } - - @Override - void makeMenuBar() { - super.makeMenuBar(); - } - - @Override - public void onClick(int slot, ItemStack item) { - super.onClick(slot, item); - - if (slot == GuiIcon.MANAGE_SHOP_COLLECT_SALE.getSlot() && GuiIcon.MANAGE_SHOP_COLLECT_SALE.getItemStack().equals(item)) { - Player player = getPlayer(); - double d = 0; - int count = 0; - if (!ShopUtil.canManageShop(player, this.shop)) - return; - if (this.shop.getType().equals(ShopType.BUY)) - return; - - double balance = this.shop.getBalance(); - if (balance == 0) - return; - - this.shop.removeBalance(balance); - EconomyUtils.addFunds(player, balance); - d += balance; - count++; - TagResolver placeholders = TagResolver.resolver( - Placeholder.parsed("balance", String.valueOf(d)), - Placeholder.parsed("count", String.valueOf(count)) - ); - player.sendRichMessage("You have collected from shops.", placeholders); - return; - } - - if (slot >= 45) - return; - - if (slot == GuiIcon.MANAGE_SHOP.getSlot() && GuiIcon.MANAGE_SHOP.getItemStack().equals(item)) { - - } else if (slot == GuiIcon.MANAGE_SHOP_BALANCE_ADD.getSlot() && GuiIcon.MANAGE_SHOP_BALANCE_ADD.getItemStack().equals(item)) { - if (EconomyUtils.getFunds(getPlayer()) > 0) { - openChangePrompt(ConversationType.ADD_BALANCE); - } else { - getPlayer().sendRichMessage("You do not have money to add to this shop"); - } - } else if (slot == GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getSlot() && GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getItemStack().equals(item)) { - if (shop.getBalance() > 0) { - openChangePrompt(ConversationType.WITHDRAW_BALANCE); - } else { - getPlayer().sendRichMessage("You can't withdraw money from this shop"); - } - } else if (slot == GuiIcon.MANAGE_SHOP_SALES.getSlot() && GuiIcon.MANAGE_SHOP_SALES.getItemStack().equals(item)) { - ListTransactionsGui listTransactionsGui = new ListTransactionsGui(uuid, shop); - listTransactionsGui.setLastGui(this); - listTransactionsGui.open(); - } else if (slot == GuiIcon.MANAGE_SHOP_ITEM.getSlot() && GuiIcon.MANAGE_SHOP_ITEM.getItemStack().equals(item)) { - openChangePrompt(ConversationType.CHANGE_ITEM); - } else if (slot == GuiIcon.MANAGE_SHOP_TYPE.getSlot() && GuiIcon.MANAGE_SHOP_TYPE.getItemStack().equals(item)) { - openChangePrompt(ConversationType.CHANGE_TYPE); - } else if (slot == GuiIcon.MANAGE_SHOP_AMOUNT.getSlot() && GuiIcon.MANAGE_SHOP_AMOUNT.getItemStack().equals(item)) { - openChangePrompt(ConversationType.CHANGE_AMOUNT); - } else if (slot == GuiIcon.MANAGE_SHOP_PRICE.getSlot() && GuiIcon.MANAGE_SHOP_PRICE.getItemStack().equals(item)) { - openChangePrompt(ConversationType.CHANGE_PRICE); - } - } - - private void openChangePrompt(ConversationType conversationType) { - Player player = getPlayer(); - player.closeInventory(); - new ConversationManager(PlayerShops.getInstance(), player, conversationType, shop); - } - -} diff --git a/src/main/java/com/alttd/playershops/handler/ShopHandler.java b/src/main/java/com/alttd/playershops/handler/ShopHandler.java index 0954a70..fed4a1e 100644 --- a/src/main/java/com/alttd/playershops/handler/ShopHandler.java +++ b/src/main/java/com/alttd/playershops/handler/ShopHandler.java @@ -6,11 +6,13 @@ import com.alttd.playershops.shop.PlayerSettings; import com.alttd.playershops.shop.PlayerShop; import com.alttd.playershops.storage.database.DatabaseHelper; import com.alttd.playershops.utils.Logger; +import com.alttd.playershops.utils.Pair; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -201,4 +203,26 @@ public class ShopHandler { } sender.sendRichMessage(playerShops.size() + " from " + oldOwner.getName() + " have been transferred to " + newOwner.getName() + "."); } + + /** + * On demand calculation of shops per material + * + * @return TreeMap containing a list of PlayerShops per material. + */ + public TreeMap> shopByMaterial() { + // TODO -- make this a cache. update cache on change, do not calc dynamicly + TreeMap> shopByMaterialTreeSet = new TreeMap<>(); + + for (PlayerShop shop : getShops()) { + if (!shop.isInitialized()) { + continue; + } + + Material material = shop.getItemStack().getType(); + List shopList = shopByMaterialTreeSet.computeIfAbsent(material, v -> new ArrayList<>()); + shopList.add(shop); + } + + return shopByMaterialTreeSet; + } } diff --git a/src/main/java/com/alttd/playershops/listener/InventoryListener.java b/src/main/java/com/alttd/playershops/listener/InventoryListener.java deleted file mode 100644 index 848504f..0000000 --- a/src/main/java/com/alttd/playershops/listener/InventoryListener.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.alttd.playershops.listener; - -import com.alttd.playershops.PlayerShops; -import com.alttd.playershops.gui.AbstractGui; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.ItemStack; - -public class InventoryListener extends EventListener { - - private final PlayerShops plugin; - public InventoryListener(PlayerShops plugin) { - this.plugin = plugin; - this.register(this.plugin); - } - - @EventHandler - public void onInventoryClickEvent(InventoryClickEvent event) { - if (!(event.getWhoClicked() instanceof Player player)) - return; - - if (!(event.getView().getTopInventory().getHolder() instanceof AbstractGui gui)) - return; - - if ((event.getView().getBottomInventory().equals(event.getClickedInventory()))) - return; - - if (event.getClick() == ClickType.NUMBER_KEY) { - event.setCancelled(true); - return; - } - - ItemStack clicked = event.getCurrentItem(); - if (!(clicked != null && clicked.getType() != Material.AIR)) - return; - - event.setCancelled(true); - gui.onClick(event.getRawSlot(), clicked); - } - -} diff --git a/src/main/java/com/alttd/playershops/listener/TransactionListener.java b/src/main/java/com/alttd/playershops/listener/TransactionListener.java index 6a8f984..e19669a 100644 --- a/src/main/java/com/alttd/playershops/listener/TransactionListener.java +++ b/src/main/java/com/alttd/playershops/listener/TransactionListener.java @@ -2,7 +2,7 @@ package com.alttd.playershops.listener; import com.alttd.playershops.PlayerShops; import com.alttd.playershops.config.MessageConfig; -import com.alttd.playershops.gui.ShopManagementGui; +import com.alttd.playershops.dialog.ManageShopDialog; import com.alttd.playershops.handler.ShopHandler; import com.alttd.playershops.hook.WorldGuardHook; import com.alttd.playershops.shop.PlayerShop; @@ -92,8 +92,10 @@ public class TransactionListener extends EventListener { event.setCancelled(true); return; } - ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop); - gui.open(); +// ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop); +// gui.open(); + ManageShopDialog manageShopDialog = new ManageShopDialog(player.getUniqueId(), playerShop); + manageShopDialog.open(); event.setCancelled(true); return; } diff --git a/src/main/java/com/alttd/playershops/shop/PlayerSettings.java b/src/main/java/com/alttd/playershops/shop/PlayerSettings.java index 898f37b..2d15576 100644 --- a/src/main/java/com/alttd/playershops/shop/PlayerSettings.java +++ b/src/main/java/com/alttd/playershops/shop/PlayerSettings.java @@ -12,7 +12,12 @@ import java.util.UUID; public class PlayerSettings { public enum Option { SALE_OWNER_NOTIFICATIONS, SALE_USER_NOTIFICATIONS, - STOCK_NOTIFICATIONS, DISCORD_STOCK_NOTIFICATIONS + STOCK_NOTIFICATIONS, DISCORD_STOCK_NOTIFICATIONS; + + @Override + public String toString() { + return this.name().toLowerCase().replace("_", " "); + } } private final UUID uuid; diff --git a/src/main/java/com/alttd/playershops/shop/PlayerShop.java b/src/main/java/com/alttd/playershops/shop/PlayerShop.java index dc965d0..b717fa1 100644 --- a/src/main/java/com/alttd/playershops/shop/PlayerShop.java +++ b/src/main/java/com/alttd/playershops/shop/PlayerShop.java @@ -3,19 +3,25 @@ package com.alttd.playershops.shop; import com.alttd.playershops.PlayerShops; import com.alttd.playershops.events.*; import com.alttd.playershops.utils.*; +import com.alttd.playershops.utils.sprite.MaterialSprites; import lombok.Getter; import lombok.Setter; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.OfflinePlayer; import org.bukkit.block.Sign; +import org.bukkit.block.sign.Side; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.scheduler.BukkitRunnable; import java.util.*; @@ -31,8 +37,8 @@ public class PlayerShop { private final Location signLocation; private final Location shopLocation; private String server; - private double price; - private int amount; + private double price = 0; + private int amount = 1; private double balance; private ItemStack itemStack; @Setter @@ -148,7 +154,7 @@ public class PlayerShop { } public boolean isInitialized() { - return type != ShopType.NONE; + return type != ShopType.NONE && itemStack != null; } public void updateSign() { @@ -172,11 +178,12 @@ public class PlayerShop { public void run() { if (!(signLocation.getBlock().getState() instanceof Sign signBlock)) return; MiniMessage miniMessage = MiniMessage.miniMessage(); + Component itemComponent = getItemStack() == null ? ShopUtil.trimmedItemNameComponent(getItemStack()): MaterialSprites.get(getItemStack().getType()).append(Component.space()).append(ShopUtil.trimmedItemNameComponent(getItemStack())); TagResolver tagResolver = TagResolver.resolver( Placeholder.unparsed("ownername", getOwnerName()), Placeholder.unparsed("price", trimPrice(String.valueOf(ShopUtil.round(getPrice())))), Placeholder.unparsed("amount", String.valueOf(getAmount())), - Placeholder.component("itemname", ShopUtil.trimmedItemNameComponent(getItemStack())) + Placeholder.component("itemname", itemComponent) ); for (int i = 0; i < 4; i++) { signBlock.getSide(Side.FRONT).line(i, miniMessage.deserialize(signLines.get(i), tagResolver)); @@ -452,4 +459,25 @@ public class PlayerShop { + " balance :" + this.balance + " lastTransaction :" + this.lastTransaction; } + + public Component getHoverComponent(Player player) { + Component component = ShopUtil.itemNameComponent(getItemStack()) + .append(Component.newline()) + .append(Component.newline()) + .append(Component.text("ShopType: " + type)) + .append(Component.newline()) + .append(Component.text("Price: " + price)) + .append(Component.newline()) + .append(Component.text("ShopType: " + amount)) + .append(Component.newline()) + .append(Component.text("World: " + shopLocation.getWorld().getName())) + .append(Component.newline()) + .append(Component.text("Coordinates: " + shopLocation.getBlockX() + ", " + shopLocation.getBlockY() + ", " + shopLocation.getBlockZ())) + ; + if (getOwnerUUID().equals(player.getUniqueId())) { + component = component.append(Component.newline()).append(Component.text("Balance: " + balance)); + } + + return component; + } } diff --git a/src/main/java/com/alttd/playershops/utils/EconomyUtils.java b/src/main/java/com/alttd/playershops/utils/EconomyUtils.java index 90c8132..2f85fb1 100644 --- a/src/main/java/com/alttd/playershops/utils/EconomyUtils.java +++ b/src/main/java/com/alttd/playershops/utils/EconomyUtils.java @@ -65,4 +65,37 @@ public class EconomyUtils { return bd.doubleValue(); } + public static Double parseValue(String input) { + Double value = null; + if (input == null || input.isEmpty()) { + return null; + } + + try { + value = Double.parseDouble(input); + } catch (NumberFormatException ex) { + Double multiplier = multiplierValue(input.substring(input.length() - 1)); + if (multiplier == null) { + multiplier = 1.0; + } + try { + value = Double.parseDouble(input.substring(0, input.length() - 1)); + } catch (NumberFormatException ignored) {} + if (value != null) { + value = value * multiplier; + } + } + + return value; + } + + private static Double multiplierValue(String input) { + Double value = null; + switch(input.toLowerCase()) { + case "k" -> value = 1000.0; + case "m" -> value = 1000000.0; + } + return value; + } + } diff --git a/src/main/java/com/alttd/playershops/utils/ShopUtil.java b/src/main/java/com/alttd/playershops/utils/ShopUtil.java index 642561e..bd3c03d 100644 --- a/src/main/java/com/alttd/playershops/utils/ShopUtil.java +++ b/src/main/java/com/alttd/playershops/utils/ShopUtil.java @@ -2,20 +2,17 @@ package com.alttd.playershops.utils; import com.alttd.playershops.shop.PlayerShop; import com.alttd.playershops.shop.ShopTransaction; +import com.alttd.playershops.utils.sprite.MaterialSprites; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.*; -import org.bukkit.block.BlockState; -import org.bukkit.block.ShulkerBox; -import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.*; -import org.bukkit.map.MapView; import java.util.*; @@ -168,7 +165,7 @@ public class ShopUtil { Component component; MiniMessage miniMessage = MiniMessage.miniMessage(); if (item == null || item.getType().equals(Material.AIR)) - return miniMessage.deserialize("NONE"); + return miniMessage.deserialize("No item"); boolean dname = item.hasItemMeta() && item.getItemMeta().hasDisplayName(); if (dname) { component = item.getItemMeta().displayName(); @@ -205,4 +202,18 @@ public class ShopUtil { public static double round(double price) { return (double) Math.round(price * 100) / 100; } + + public static Component spriteComponent(ItemStack itemStack) { + Component component = Component.empty(); + if (itemStack == null || itemStack.getType() == Material.AIR) return component; + + component = MaterialSprites.get(itemStack.getType()).append(Component.space()).append( + itemStack.displayName().hoverEvent(itemStack.asHoverEvent())); + + return component; + } + + public static Component spriteComponent(Material material) { + return MaterialSprites.get(material).append(Component.space()).append(Component.text(material.key().value())); + } }