Refactor PlayerShops to use Dialogs.

This commit is contained in:
Len 2025-12-28 19:58:45 +01:00
parent ffdafd07d2
commit 49fb85229d
26 changed files with 978 additions and 1017 deletions

View File

@ -4,7 +4,6 @@ import com.alttd.playershops.commands.PlayerShopCommand;
import com.alttd.playershops.config.Config; import com.alttd.playershops.config.Config;
import com.alttd.playershops.config.DatabaseConfig; import com.alttd.playershops.config.DatabaseConfig;
import com.alttd.playershops.config.MessageConfig; import com.alttd.playershops.config.MessageConfig;
import com.alttd.playershops.gui.GuiIcon;
import com.alttd.playershops.handler.ShopHandler; import com.alttd.playershops.handler.ShopHandler;
import com.alttd.playershops.listener.*; import com.alttd.playershops.listener.*;
import com.alttd.playershops.shop.ShopType; import com.alttd.playershops.shop.ShopType;
@ -37,7 +36,6 @@ public class PlayerShops extends JavaPlugin {
private ShopListener shopListener; private ShopListener shopListener;
private PlayerListener playerListener; private PlayerListener playerListener;
private TransactionListener transactionListener; private TransactionListener transactionListener;
private InventoryListener inventoryListener;
private GriefPreventionListener griefPreventionListener; private GriefPreventionListener griefPreventionListener;
@Getter @Getter
@ -101,7 +99,6 @@ public class PlayerShops extends JavaPlugin {
shopListener = new ShopListener(this); shopListener = new ShopListener(this);
playerListener = new PlayerListener(this); playerListener = new PlayerListener(this);
transactionListener = new TransactionListener(this); transactionListener = new TransactionListener(this);
inventoryListener = new InventoryListener(this);
griefPreventionListener = new GriefPreventionListener(this); // TODO hook into GP griefPreventionListener = new GriefPreventionListener(this); // TODO hook into GP
} }
@ -109,7 +106,6 @@ public class PlayerShops extends JavaPlugin {
shopListener.unregister(); shopListener.unregister();
playerListener.unregister(); playerListener.unregister();
transactionListener.unregister(); transactionListener.unregister();
inventoryListener.unregister();
} }
private void registerCommands() { private void registerCommands() {
@ -129,9 +125,6 @@ public class PlayerShops extends JavaPlugin {
for (ShopType shopType : ShopType.values()) { for (ShopType shopType : ShopType.values()) {
// preload ShopType to get the configs active // preload ShopType to get the configs active
} }
for (GuiIcon guiIcon : GuiIcon.values()) {
// preload to get config values generated
}
} }
} }

View File

@ -3,7 +3,7 @@ package com.alttd.playershops.commands;
import com.alttd.playershops.PlayerShops; import com.alttd.playershops.PlayerShops;
import com.alttd.playershops.commands.arguments.OfflinePlayerArgument; import com.alttd.playershops.commands.arguments.OfflinePlayerArgument;
import com.alttd.playershops.commands.subcommands.CheckStockCommand; 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.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode; import com.mojang.brigadier.tree.LiteralCommandNode;
@ -28,14 +28,13 @@ public class PlayerShopCommand {
if (!(source.getSource().getSender() instanceof Player player)) if (!(source.getSource().getSender() instanceof Player player))
return 1; return 1;
// TODO -- DIALOG ShopDialog shopDialog = new ShopDialog(player.getUniqueId());
HomeGui gui = new HomeGui(player.getUniqueId()); shopDialog.open();
gui.open();
return 1; return 1;
}) })
.then( .then(
Commands.literal("reload") Commands.literal("reload")
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + "reload")) .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".reload"))
.executes(source -> { .executes(source -> {
PlayerShops.getInstance().reloadConfigs(); PlayerShops.getInstance().reloadConfigs();
return 1; return 1;
@ -43,7 +42,7 @@ public class PlayerShopCommand {
) )
.then( .then(
Commands.literal("checkstock") Commands.literal("checkstock")
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + "checkstock") .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".checkstock")
&& commandSourceStack.getSender() instanceof Player) && commandSourceStack.getSender() instanceof Player)
.then( .then(
Commands.argument("range", IntegerArgumentType.integer(1, 100)) Commands.argument("range", IntegerArgumentType.integer(1, 100))
@ -72,7 +71,7 @@ public class PlayerShopCommand {
) )
.then( .then(
Commands.literal("transfershops") Commands.literal("transfershops")
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + "transfershops")) .requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".transfershops"))
.then( .then(
Commands.argument("old", new OfflinePlayerArgument()) Commands.argument("old", new OfflinePlayerArgument())
.then( .then(

View File

@ -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;
}
}
}

View File

@ -1,10 +0,0 @@
package com.alttd.playershops.conversation;
public enum ConversationType {
CHANGE_ITEM,
CHANGE_AMOUNT,
CHANGE_TYPE,
CHANGE_PRICE,
WITHDRAW_BALANCE,
ADD_BALANCE;
}

View File

@ -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<ActionButton> actions = new ArrayList<>();
List<DialogInput> inputs = new ArrayList<>();
List<DialogBody> texts = new ArrayList<>();
ActionButton closeButton;
AbstractDialog(UUID uuid) {
this.uuid = uuid;
this.lastDialog = null;
closeButton = ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Go back</gold>")).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;
}
}

View File

@ -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<UUID> 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()
);
}
}
}

View File

@ -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<PlayerShop> 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<PlayerShop> 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("<gold>This menu will <red>not</red> 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("<gold>Collect sales</gold>"))
.tooltip(MiniMessage.miniMessage().deserialize("<gold>Click to collect all balance from your shops.</gold>"))
.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 ? "<green>You have collected <balance> from <count> shops." : "<red>No shops to be collected from.", placeholders);
}, ClickCallback.Options.builder()
.lifetime(Duration.ofMinutes(5))
.build())
)
.build()
);
}
}
}

View File

@ -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("<gold>PlayerShop - <playername>", 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("<gold>ShopType</gold>"),
Arrays.stream(ShopType.values()).map(
shopType -> SingleOptionDialogInput.OptionEntry.create(shopType.name(), MiniMessage.miniMessage().deserialize("<green>" + shopType.name()), shop.getType() == shopType)
).toList())
.build()
);
inputs.add(
DialogInput.text("balance", MiniMessage.miniMessage().deserialize("<gold>Balance</gold>"))
.initial(String.valueOf(shop.getBalance()))
.width(300)
.build()
);
inputs.add(
DialogInput.bool("changeitem", MiniMessage.miniMessage().deserialize("<gold>Change item?</gold>"))
.initial(false)
.build()
);
inputs.add(
DialogInput.singleOption("item", MiniMessage.miniMessage().deserialize("<gold>Item</gold>"), 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("<gold>Change amount</gold>"), 1f, (float) maxQty)
.step(1f)
.initial((float) initialQty)
.width(300)
.build()
);
inputs.add(
DialogInput.text("price", MiniMessage.miniMessage().deserialize("<gold>Change price</gold>"))
.initial(String.valueOf(shop.getPrice()))
.width(300)
.build()
);
ActionButton saveButton = ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Confirm</gold>")).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<SingleOptionDialogInput.OptionEntry> itemEntries() {
List<SingleOptionDialogInput.OptionEntry> optionEntries = new ArrayList<>();
if (getPlayer() == null) {
return optionEntries;
}
optionEntries.add(
SingleOptionDialogInput.OptionEntry.create("reset", MiniMessage.miniMessage().deserialize("<gold>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;
}
}

View File

@ -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<PlayerShop> 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<Material, List<PlayerShop>> 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());
}
}
}

View File

@ -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()
);
}
}

View File

@ -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<PlayerSettings.Option> entry : playerSettings.optionsMap.object2BooleanEntrySet()) {
String setting = entry.getKey().name();
System.out.println(setting);
inputs.add(
DialogInput.bool(setting, MiniMessage.miniMessage().deserialize("<gold>" + entry.getKey().toString() + "</gold>"))
.initial(playerSettings.getOption(entry.getKey()))
.build()
);
}
actions.add(
ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Confirm</gold>")).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("<gold>Set shop default values</gold>")).action(
DialogAction.customClick((view, audience) -> {
if (!(audience instanceof Player player)) {
return;
}
}, ClickCallback.Options.builder()
.lifetime(Duration.ofMinutes(5))
.uses(-1)
.build())
).build()
);
}
}

View File

@ -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());
}
}

View File

@ -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<String> 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<Component> 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();
}
}

View File

@ -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();
}*/
}
}

View File

@ -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<UUID> 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();
}
}

View File

@ -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<PlayerShop> 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 ? "<green>You have collected <balance> from <count> shops." : "<red>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();
}
}

View File

@ -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<ShopTransaction> 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();
}
}
}

View File

@ -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<PlayerSettings.Option> 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("<setting>")
.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;
}
}

View File

@ -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<Component> 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: <balance>", placeholders));
lore.add(Util.parseMiniMessage("item: <itemname>", placeholders));
lore.add(Util.parseMiniMessage("amount: <amount>", placeholders));
lore.add(Util.parseMiniMessage("Type: <shoptype>", placeholders));
lore.add(Util.parseMiniMessage("Price: <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("<green>You have collected <balance> from <count> 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("<red>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("<red>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);
}
}

View File

@ -6,11 +6,13 @@ import com.alttd.playershops.shop.PlayerSettings;
import com.alttd.playershops.shop.PlayerShop; import com.alttd.playershops.shop.PlayerShop;
import com.alttd.playershops.storage.database.DatabaseHelper; import com.alttd.playershops.storage.database.DatabaseHelper;
import com.alttd.playershops.utils.Logger; 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.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import lombok.Getter; import lombok.Getter;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; 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() + "."); 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<Material, List<PlayerShop>> shopByMaterial() {
// TODO -- make this a cache. update cache on change, do not calc dynamicly
TreeMap<Material, List<PlayerShop>> shopByMaterialTreeSet = new TreeMap<>();
for (PlayerShop shop : getShops()) {
if (!shop.isInitialized()) {
continue;
}
Material material = shop.getItemStack().getType();
List<PlayerShop> shopList = shopByMaterialTreeSet.computeIfAbsent(material, v -> new ArrayList<>());
shopList.add(shop);
}
return shopByMaterialTreeSet;
}
} }

View File

@ -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);
}
}

View File

@ -2,7 +2,7 @@ package com.alttd.playershops.listener;
import com.alttd.playershops.PlayerShops; import com.alttd.playershops.PlayerShops;
import com.alttd.playershops.config.MessageConfig; 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.handler.ShopHandler;
import com.alttd.playershops.hook.WorldGuardHook; import com.alttd.playershops.hook.WorldGuardHook;
import com.alttd.playershops.shop.PlayerShop; import com.alttd.playershops.shop.PlayerShop;
@ -92,8 +92,10 @@ public class TransactionListener extends EventListener {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop); // ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop);
gui.open(); // gui.open();
ManageShopDialog manageShopDialog = new ManageShopDialog(player.getUniqueId(), playerShop);
manageShopDialog.open();
event.setCancelled(true); event.setCancelled(true);
return; return;
} }

View File

@ -12,7 +12,12 @@ import java.util.UUID;
public class PlayerSettings { public class PlayerSettings {
public enum Option { public enum Option {
SALE_OWNER_NOTIFICATIONS, SALE_USER_NOTIFICATIONS, 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; private final UUID uuid;

View File

@ -3,19 +3,25 @@ package com.alttd.playershops.shop;
import com.alttd.playershops.PlayerShops; import com.alttd.playershops.PlayerShops;
import com.alttd.playershops.events.*; import com.alttd.playershops.events.*;
import com.alttd.playershops.utils.*; import com.alttd.playershops.utils.*;
import com.alttd.playershops.utils.sprite.MaterialSprites;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; 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.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.block.Sign; import org.bukkit.block.Sign;
import org.bukkit.block.sign.Side;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import java.util.*; import java.util.*;
@ -31,8 +37,8 @@ public class PlayerShop {
private final Location signLocation; private final Location signLocation;
private final Location shopLocation; private final Location shopLocation;
private String server; private String server;
private double price; private double price = 0;
private int amount; private int amount = 1;
private double balance; private double balance;
private ItemStack itemStack; private ItemStack itemStack;
@Setter @Setter
@ -148,7 +154,7 @@ public class PlayerShop {
} }
public boolean isInitialized() { public boolean isInitialized() {
return type != ShopType.NONE; return type != ShopType.NONE && itemStack != null;
} }
public void updateSign() { public void updateSign() {
@ -172,11 +178,12 @@ public class PlayerShop {
public void run() { public void run() {
if (!(signLocation.getBlock().getState() instanceof Sign signBlock)) return; if (!(signLocation.getBlock().getState() instanceof Sign signBlock)) return;
MiniMessage miniMessage = MiniMessage.miniMessage(); 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( TagResolver tagResolver = TagResolver.resolver(
Placeholder.unparsed("ownername", getOwnerName()), Placeholder.unparsed("ownername", getOwnerName()),
Placeholder.unparsed("price", trimPrice(String.valueOf(ShopUtil.round(getPrice())))), Placeholder.unparsed("price", trimPrice(String.valueOf(ShopUtil.round(getPrice())))),
Placeholder.unparsed("amount", String.valueOf(getAmount())), Placeholder.unparsed("amount", String.valueOf(getAmount())),
Placeholder.component("itemname", ShopUtil.trimmedItemNameComponent(getItemStack())) Placeholder.component("itemname", itemComponent)
); );
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
signBlock.getSide(Side.FRONT).line(i, miniMessage.deserialize(signLines.get(i), tagResolver)); signBlock.getSide(Side.FRONT).line(i, miniMessage.deserialize(signLines.get(i), tagResolver));
@ -452,4 +459,25 @@ public class PlayerShop {
+ " balance :" + this.balance + " balance :" + this.balance
+ " lastTransaction :" + this.lastTransaction; + " 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;
}
} }

View File

@ -65,4 +65,37 @@ public class EconomyUtils {
return bd.doubleValue(); 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;
}
} }

View File

@ -2,20 +2,17 @@ package com.alttd.playershops.utils;
import com.alttd.playershops.shop.PlayerShop; import com.alttd.playershops.shop.PlayerShop;
import com.alttd.playershops.shop.ShopTransaction; import com.alttd.playershops.shop.ShopTransaction;
import com.alttd.playershops.utils.sprite.MaterialSprites;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.*; 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.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.*; import org.bukkit.inventory.meta.*;
import org.bukkit.map.MapView;
import java.util.*; import java.util.*;
@ -168,7 +165,7 @@ public class ShopUtil {
Component component; Component component;
MiniMessage miniMessage = MiniMessage.miniMessage(); MiniMessage miniMessage = MiniMessage.miniMessage();
if (item == null || item.getType().equals(Material.AIR)) if (item == null || item.getType().equals(Material.AIR))
return miniMessage.deserialize("NONE"); return miniMessage.deserialize("No item");
boolean dname = item.hasItemMeta() && item.getItemMeta().hasDisplayName(); boolean dname = item.hasItemMeta() && item.getItemMeta().hasDisplayName();
if (dname) { if (dname) {
component = item.getItemMeta().displayName(); component = item.getItemMeta().displayName();
@ -205,4 +202,18 @@ public class ShopUtil {
public static double round(double price) { public static double round(double price) {
return (double) Math.round(price * 100) / 100; 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()));
}
} }