Implement shop interaction

Product string of shop info message is still WIP
This commit is contained in:
Eric 2022-08-20 22:32:14 +02:00
parent 52d3833961
commit 1e4ba02e72
13 changed files with 1481 additions and 3 deletions

View File

@ -0,0 +1,101 @@
package de.epiceric.shopchest.api.event;
import de.epiceric.shopchest.api.player.ShopPlayer;
import de.epiceric.shopchest.api.shop.Shop;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventPriority;
/**
* Called when a player buys or sells something from or to a shop
* <p>
* The transaction takes place with {@link EventPriority#HIGHEST}.
* If the transaction fails, this should be checked in a listener with
* {@link EventPriority#MONITOR}.
*
* @since 1.13
*/
public class ShopUseEvent extends ShopEvent implements Cancellable {
private Type type;
private int amount;
private double price;
private boolean cancelled;
public ShopUseEvent(ShopPlayer player, Shop shop, Type type, int amount, double price) {
super(player, shop);
this.type = type;
this.amount = amount;
this.price = price;
}
/**
* Gets whether the shop use is a buy or a sell
*
* @return the type of shop use
* @since 1.13
*/
public Type getType() {
return type;
}
/**
* Gets the amount which might be modified by automatic item amount
* calculation
*
* @return the amount
* @since 1.13
*/
public int getAmount() {
return amount;
}
/**
* Sets the amount of items the player will buy or sell
* <p>
* This might not be equal to the amount specified in {@link Shop#getProduct()}.
*
* @param amount the amount
* @since 1.13
*/
public void setAmount(int amount) {
this.amount = amount;
}
/**
* Gets the price the player and the vendor of the shop will pay or receive
* <p>
* This might not be equal to {@link Shop#getBuyPrice()} or
* {@link Shop#getSellPrice()} due to automatic item amount calculation.
*
* @return the price
* @since 1.13
*/
public double getPrice() {
return price;
}
/**
* Sets the amount of money the player and the vendor of the shop will pay or
* receive
*
* @param price the price
* @since 1.13
*/
public void setPrice(double price) {
this.price = price;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
public enum Type {
BUY, SELL;
}
}

View File

@ -0,0 +1,196 @@
package de.epiceric.shopchest.listener;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.api.config.Config;
import de.epiceric.shopchest.api.event.ShopCreateEvent;
import de.epiceric.shopchest.api.event.ShopPreCreateEvent;
import de.epiceric.shopchest.api.event.ShopSelectItemEvent;
import de.epiceric.shopchest.api.flag.CreateFlag;
import de.epiceric.shopchest.api.flag.SelectFlag;
import de.epiceric.shopchest.api.player.ShopPlayer;
import de.epiceric.shopchest.api.shop.Shop;
import de.epiceric.shopchest.api.shop.ShopProduct;
import de.epiceric.shopchest.shop.ShopProductImpl;
import de.epiceric.shopchest.util.Logger;
public class ShopCreateListener implements Listener {
private final ShopChest plugin;
public ShopCreateListener(ShopChest plugin) {
this.plugin = plugin;
}
private boolean isInt(double d) {
return d % 1 == 0;
}
private boolean validateItem(ShopPlayer player, Material type, double buyPrice, double sellPrice) {
// Check if item is blacklisted
if (Config.SHOP_CREATION_BLACKLIST.get().getList().contains(type)) {
player.sendMessage("§cYou cannot create a shop with this item."); // TODO: i18n
return false;
}
// Check if minimum price is followed
double minPrice = Config.SHOP_CREATION_MINIMUM_PRICES.get().getMap().getOrDefault(type, 0d);
if (buyPrice > 0 && buyPrice < minPrice) {
player.sendMessage("§cThe buy price must be higher than " + plugin.formatEconomy(minPrice) + "."); // TODO: i18n
return false;
} else if (sellPrice > 0 && sellPrice < minPrice) {
player.sendMessage("§cThe sell price must be higher than " + plugin.formatEconomy(minPrice) + "."); // TODO: i18n
return false;
}
// Check if maximum price is followed
double maxPrice = Config.SHOP_CREATION_MAXIMUM_PRICES.get().getMap().getOrDefault(type, Double.MAX_VALUE);
if (buyPrice > 0 && buyPrice > maxPrice) {
player.sendMessage("§cThe buy price must be lower than " + plugin.formatEconomy(maxPrice) + "."); // TODO: i18n
return false;
} else if (sellPrice > 0 && sellPrice > maxPrice) {
player.sendMessage("§cThe sell price must be lower than " + plugin.formatEconomy(maxPrice) + "."); // TODO: i18n
return false;
}
return true;
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeCommand(ShopPreCreateEvent e) {
ShopPlayer player = e.getPlayer();
double buyPrice = e.getBuyPrice();
double sellPrice = e.getSellPrice();
// Check permission admin shop
if (e.isAdminShop() && !player.hasPermission("shopchest.create.admin")) {
e.setCancelled(true);
player.sendMessage("§cYou don't have permission to create an admin shop."); // TODO: i18n
return;
}
// TODO: buy/sell and item based permission
// Check permission normal shop
if (!e.isAdminShop() && !player.hasPermission("shopchest.create")) {
e.setCancelled(true);
player.sendMessage("§cYou don't have permission to create a shop."); // TODO: i18n
return;
}
// Check shop limit
if (player.getShopAmount() >= player.getShopLimit()) {
e.setCancelled(true);
player.sendMessage("§cYou don't have permission to create any more shops."); // TODO: i18n
return;
}
// Check if either buying or selling is enabled
if (buyPrice <= 0 && sellPrice <= 0) {
e.setCancelled(true);
player.sendMessage("§cYou cannot have both prices set to zero."); // TODO: i18n
return;
}
// Check if prices are integers
boolean allowDecimals = Config.SHOP_CREATION_ALLOW_DECIMAL_PRICES.get();
if (!allowDecimals && (!isInt(buyPrice) || !isInt(buyPrice))) {
e.setCancelled(true);
player.sendMessage("§cThe prices must not contain decimals."); // TODO: i18n
return;
}
// Check if buy price is higher than sell price
boolean buyHigherSell = Config.FEATURES_VENDOR_MONEY_PROTECTION.get();
if (buyHigherSell && buyPrice > 0 && buyPrice < sellPrice) {
e.setCancelled(true);
player.sendMessage("§cThe buy price must at least be as high as the sell price to prevent players from stealing your money."); // TODO: i18n
return;
}
if (e.isItemSelected()) {
// Check if item is in blacklist, and if minimum/maximum prices are followed
Material type = e.getItemStack().getType();
if (!validateItem(player, type, buyPrice, sellPrice)) {
e.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCommand(ShopPreCreateEvent e) {
ShopPlayer player = e.getPlayer();
if (!e.isItemSelected()) {
if (!(player.getFlag().orElse(null) instanceof SelectFlag)) {
// Set flag only if player doesn't already have SelectFlag
SelectFlag.Type type = e.isAdminShop() ? SelectFlag.Type.ADMIN : SelectFlag.Type.NORMAL;
SelectFlag flag = new SelectFlag(e.getAmount(),
e.getBuyPrice(), e.getSellPrice(), type,
player.getBukkitPlayer().getGameMode());
player.setFlag(flag);
player.getBukkitPlayer().setGameMode(GameMode.CREATIVE);
player.sendMessage("§aOpen your inventory and select the item you want to sell or buy."); // TODO: 18n
}
} else {
ShopProduct product = new ShopProductImpl(e.getItemStack(), e.getAmount());
player.setFlag(new CreateFlag(plugin, product, e.getBuyPrice(), e.getSellPrice(), e.isAdminShop()));
player.sendMessage("§aClick a chest within 15 seconds to create a shop."); // TODO: 18n
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeSelect(ShopSelectItemEvent e) {
if (!validateItem(e.getPlayer(), e.getItem().getType(), e.getBuyPrice(), e.getSellPrice())) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onSelect(ShopSelectItemEvent e) {
ShopProduct product = new ShopProductImpl(e.getItem(), e.getAmount());
ShopPlayer player = e.getPlayer();
if (!e.isEditingShop()) {
player.setFlag(new CreateFlag(plugin, product, e.getBuyPrice(), e.getSellPrice(), e.isAdminShop()));
player.sendMessage("§aItem has been selected: §e{0}", product.getLocalizedName()); // TODO: 18n
player.sendMessage("§aClick a chest within 15 seconds to create a shop."); // TODO: 18n
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onAction(ShopCreateEvent e) {
if (e.isCancelled() && !e.getPlayer().hasPermission("shopchest.create.protected")) {
e.getPlayer().sendMessage("§cYou don't have permission to create a shop here."); // TODO: i18n
return;
}
Shop shop = e.getShop();
if (shop.isAdminShop()) {
plugin.getShopManager()
.addAdminShop(shop.getProduct(), shop.getLocation(), shop.getBuyPrice(), shop.getSellPrice())
.thenAccept(newShop -> e.getPlayer().sendMessage("§aAdmin shop has been added with ID {0}.", newShop.getId())) // TODO: i18n
.exceptionally(ex -> {
Logger.severe("Failed to add admin shop");
Logger.severe(ex);
e.getPlayer().sendMessage("§cFailed to add admin shop: {0}", ex.getMessage()); // TODO: i18n
return null;
});
} else {
plugin.getShopManager()
.addShop(shop.getVendor().get(), shop.getProduct(), shop.getLocation(), shop.getBuyPrice(), shop.getSellPrice())
.thenAccept(newShop -> e.getPlayer().sendMessage("§aShop has been added with ID {0}.", newShop.getId())) // TODO: i18n
.exceptionally(ex -> {
Logger.severe("Failed to add shop");
Logger.severe(ex);
e.getPlayer().sendMessage("§cFailed to add shop: {0}", ex.getMessage()); // TODO: i18n
return null;
});
}
}
}

View File

@ -0,0 +1,208 @@
package de.epiceric.shopchest.listener;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.ShopChestImpl;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.api.config.Config;
import de.epiceric.shopchest.api.event.ShopEditEvent;
import de.epiceric.shopchest.api.event.ShopPreEditEvent;
import de.epiceric.shopchest.api.event.ShopSelectItemEvent;
import de.epiceric.shopchest.api.flag.EditFlag;
import de.epiceric.shopchest.api.flag.SelectFlag;
import de.epiceric.shopchest.api.player.ShopPlayer;
import de.epiceric.shopchest.api.shop.Shop;
import de.epiceric.shopchest.api.shop.ShopProduct;
import de.epiceric.shopchest.shop.ShopImpl;
import de.epiceric.shopchest.shop.ShopProductImpl;
import de.epiceric.shopchest.util.Logger;
public class ShopEditListener implements Listener {
private final ShopChest plugin;
public ShopEditListener(ShopChest plugin) {
this.plugin = plugin;
}
private boolean isInt(double d) {
return d % 1 == 0;
}
private boolean validateItem(ShopPlayer player, Material type, double buyPrice, double sellPrice) {
// Check if item is blacklisted
if (Config.SHOP_CREATION_BLACKLIST.get().getList().contains(type)) {
player.sendMessage("§cYou cannot create a shop with this item."); // TODO: i18n
return false;
}
// Check if minimum price is followed
double minPrice = Config.SHOP_CREATION_MINIMUM_PRICES.get().getMap().getOrDefault(type, 0d);
if (buyPrice > 0 && buyPrice < minPrice) {
player.sendMessage("§cThe buy price must be higher than " + plugin.formatEconomy(minPrice) + "."); // TODO: i18n
return false;
} else if (sellPrice > 0 && sellPrice < minPrice) {
player.sendMessage("§cThe sell price must be higher than " + plugin.formatEconomy(minPrice) + "."); // TODO: i18n
return false;
}
// Check if maximum price is followed
double maxPrice = Config.SHOP_CREATION_MAXIMUM_PRICES.get().getMap().getOrDefault(type, Double.MAX_VALUE);
if (buyPrice > 0 && buyPrice > maxPrice) {
player.sendMessage("§cThe buy price must be lower than " + plugin.formatEconomy(maxPrice) + "."); // TODO: i18n
return false;
} else if (sellPrice > 0 && sellPrice > maxPrice) {
player.sendMessage("§cThe sell price must be lower than " + plugin.formatEconomy(maxPrice) + "."); // TODO: i18n
return false;
}
return true;
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeCommand(ShopPreEditEvent e) {
ShopPlayer player = e.getPlayer();
double buyPrice = e.getBuyPrice();
double sellPrice = e.getSellPrice();
// Check permission normal shop
if (!player.hasPermission("shopchest.edit")) {
e.setCancelled(true);
player.sendMessage("§cYou don't have permission to edit a shop."); // TODO: i18n
return;
}
// TODO: buy/sell and item based permission
if (e.hasBuyPrice() && e.hasSellPrice()) {
// Check if either buying or selling is enabled
if (e.getBuyPrice() == 0 && e.getSellPrice() == 0) {
e.setCancelled(true);
player.sendMessage("§cYou cannot have both prices set to zero."); // TODO: i18n
return;
}
// Check if buy price is higher than sell price
boolean buyHigherSell = Config.FEATURES_VENDOR_MONEY_PROTECTION.get();
if (buyHigherSell && e.getBuyPrice() > 0 && e.getBuyPrice() < e.getSellPrice()) {
e.setCancelled(true);
player.sendMessage("§cThe buy price must at least be as high as the sell price to prevent players from stealing your money."); // TODO: i18n
return;
}
}
// Check if prices are integers
if (!Config.SHOP_CREATION_ALLOW_DECIMAL_PRICES.get()) {
boolean isBuyPriceInt = e.hasBuyPrice() && isInt(e.getBuyPrice());
boolean isSellPriceInt = e.hasSellPrice() && isInt(e.getSellPrice());
if (!isBuyPriceInt || !isSellPriceInt) {
e.setCancelled(true);
player.sendMessage("§cThe prices must not contain decimals."); // TODO: i18n
return;
}
}
if (e.hasItemStack()) {
// Check if item is in blacklist, and if minimum/maximum prices are followed
Material type = e.getItemStack().getType();
if (!validateItem(player, type, buyPrice, sellPrice)) {
e.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCommand(ShopPreEditEvent e) {
ShopPlayer player = e.getPlayer();
if (!e.hasItemStack() && e.willEditItem()) {
if (!(player.getFlag().orElse(null) instanceof SelectFlag)) {
// Set flag only if player doesn't already have SelectFlag
SelectFlag flag = new SelectFlag(e.getAmount(),
e.getBuyPrice(), e.getSellPrice(), SelectFlag.Type.EDIT,
player.getBukkitPlayer().getGameMode());
player.setFlag(flag);
player.getBukkitPlayer().setGameMode(GameMode.CREATIVE);
player.sendMessage("§aOpen your inventory and select the item you want to sell or buy."); // TODO: 18n
}
} else {
player.setFlag(new EditFlag(plugin, e.getItemStack(), e.getAmount(), e.getBuyPrice(), e.getSellPrice()));
player.sendMessage("§aClick a chest within 15 seconds to make the edit."); // TODO: 18n
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeSelect(ShopSelectItemEvent e) {
if (!validateItem(e.getPlayer(), e.getItem().getType(), e.getBuyPrice(), e.getSellPrice())) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onSelect(ShopSelectItemEvent e) {
ShopProduct product = new ShopProductImpl(e.getItem(), e.getAmount());
ShopPlayer player = e.getPlayer();
if (e.isEditingShop()) {
player.setFlag(new EditFlag(plugin, e.getItem(), e.getAmount(), e.getBuyPrice(), e.getSellPrice()));
player.sendMessage("§aItem has been selected: §e{0}", product.getLocalizedName()); // TODO: 18n
player.sendMessage("§aClick a chest within 15 seconds to make the edit."); // TODO: 18n
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeAction(ShopEditEvent e) {
Shop shop = e.getShop();
ShopPlayer player = e.getPlayer();
// Check if either buying or selling is enabled
if (e.getBuyPrice() == 0 && e.getSellPrice() == 0) {
player.sendMessage("§cYou cannot have both prices set to zero."); // TODO: i18n
e.setCancelled(true);
return;
}
// Check if buy price is higher than sell price
boolean buyHigherSell = Config.FEATURES_VENDOR_MONEY_PROTECTION.get();
if (buyHigherSell && e.getBuyPrice() > 0 && e.getBuyPrice() < e.getSellPrice()) {
e.setCancelled(true);
player.sendMessage("§cThe buy price must at least be as high as the sell price to prevent players from stealing your money."); // TODO: i18n
return;
}
// Check permissions
if (shop.isAdminShop() && !player.hasPermission("shopchest.edit.admin")) {
player.sendMessage("§cYou don't have permission to edit an admin shop."); // TODO: i18n
e.setCancelled(true);
return;
}
if (!player.isVendor(shop) && !player.hasPermission("shopchest.edit.other")) {
player.sendMessage("§cYou don't have permission to edit this shop."); // TODO: i18n
e.setCancelled(true);
return;
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onAction(ShopEditEvent e) {
ShopImpl shop = (ShopImpl) e.getShop();
shop.setBuyPrice(e.getBuyPrice());
shop.setSellPrice(e.getSellPrice());
shop.setProduct(new ShopProductImpl(e.getItemStack(), e.getAmount()));
((ShopChestImpl) plugin).getDatabase()
.updateShop(shop)
.thenRun(() -> e.getPlayer().sendMessage("§aShop has been edited.")) // TODO: i18n
.exceptionally(ex -> {
Logger.severe("Failed to save shop edit");
Logger.severe(ex);
e.getPlayer().sendMessage("§cFailed to save edit: {0}", ex.getMessage());
return null;
});
}
}

View File

@ -0,0 +1,74 @@
package de.epiceric.shopchest.listener;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.api.event.ShopExtendEvent;
import de.epiceric.shopchest.api.player.ShopPlayer;
import de.epiceric.shopchest.api.shop.Shop;
import de.epiceric.shopchest.util.Logger;
public class ShopExtendListener implements Listener {
private final ShopChest plugin;
private final Set<UUID> hasSentPermisionMessage = new HashSet<>();
public ShopExtendListener(ShopChest plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeAction(ShopExtendEvent e) {
ShopPlayer player = e.getPlayer();
UUID uuid = player.getBukkitPlayer().getUniqueId();
if (e.getShop().isAdminShop()) {
if (!player.hasPermission("shopchest.extend.admin")) {
player.sendMessage("§cYou don't have permission to extend admin shops."); // TODO: i18n
hasSentPermisionMessage.add(uuid);
e.setCancelled(true);
}
} else if (!player.isVendor(e.getShop())) {
if (!player.hasPermission("shopchest.extend.other")) {
player.sendMessage("§cYou don't have permission to extend this shop."); // TODO: i18n
hasSentPermisionMessage.add(uuid);
e.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onAction(ShopExtendEvent e) {
UUID uuid = e.getPlayer().getBukkitPlayer().getUniqueId();
if (e.isCancelled() && !e.getPlayer().hasPermission("shopchest.create.protected")) {
if (!hasSentPermisionMessage.contains(uuid)) {
e.getPlayer().sendMessage("§cYou don't have permission to extend this shop here."); // TODO: i18n
}
hasSentPermisionMessage.remove(uuid);
return;
}
Shop shop = e.getShop();
plugin.getShopManager().removeShop(shop)
.thenCompose((v) -> {
if (shop.isAdminShop()) {
return plugin.getShopManager().addAdminShop(shop.getProduct(),
shop.getLocation(), shop.getBuyPrice(), shop.getSellPrice());
} else {
return plugin.getShopManager().addShop(shop.getVendor().get(), shop.getProduct(),
shop.getLocation(), shop.getBuyPrice(), shop.getSellPrice());
}
})
.exceptionally(ex -> {
Logger.severe("Failed to extend shop");
Logger.severe(ex);
e.getPlayer().sendMessage("§cFailed to extend shop: {0}", ex.getMessage());
return null;
});
}
}

View File

@ -0,0 +1,98 @@
package de.epiceric.shopchest.listener;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.api.event.ShopInfoEvent;
import de.epiceric.shopchest.api.event.ShopPreInfoEvent;
import de.epiceric.shopchest.api.exceptions.ChestNotFoundException;
import de.epiceric.shopchest.api.flag.InfoFlag;
import de.epiceric.shopchest.api.player.ShopPlayer;
import de.epiceric.shopchest.api.shop.Shop;
import de.epiceric.shopchest.api.shop.ShopProduct;
import de.epiceric.shopchest.util.ItemUtil;
public class ShopInfoListener implements Listener {
private final ShopChest plugin;
public ShopInfoListener(ShopChest plugin) {
this.plugin = plugin;
}
// TODO: Move to nms modules or get rid of nms references
/* private BaseComponent[] getProductMessage(ShopProduct product) {
try {
TextComponent title = new TextComponent("Product: ");
title.setColor(ChatColor.GOLD);
TextComponent amount = new TextComponent(product.getAmount() + " x ");
amount.setColor(ChatColor.WHITE);
NBTTagCompound nbt = CraftItemStack.asNMSCopy(product.getItemStack()).save(new NBTTagCompound());
String itemJson = new JsonPrimitive(nbt.toString()).toString();
TextComponent item = new TextComponent(product.getLocalizedName());
item.setColor(ChatColor.WHITE);
item.setUnderlined(true);
item.setHoverEvent(new HoverEvent(Action.SHOW_ITEM, new BaseComponent[] { new TextComponent(itemJson) }));
return new BaseComponent[] { title, amount, item };
} catch (Exception e) {
Logger.severe("Failed to create JSON for item. Product preview will not be available.");
Logger.severe(e);
return TextComponent.fromLegacyText(MessageFormat.format("§6Product: §f{0} x {1}",
product.getAmount(), product.getLocalizedName())); // TODO: i18n
}
} */
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onCommand(ShopPreInfoEvent e) {
ShopPlayer player = e.getPlayer();
player.setFlag(new InfoFlag(plugin));
player.sendMessage("§aClick a shop within 15 seconds to retrieve information about it."); // TODO: 18n
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onAction(ShopInfoEvent e) {
Shop shop = e.getShop();
ShopProduct product = shop.getProduct();
ShopPlayer player = e.getPlayer();
// TODO: i18n
player.sendMessage("§e--------- §fShop Info §e-----------------------------");
player.sendMessage("§7Hover over the underlined product for more details");
player.sendMessage("§6Vendor: §f{0}", shop.getVendor().map(OfflinePlayer::getName).orElse("Admin"));
// player.getBukkitPlayer().spigot().sendMessage(getProductMessage(product)); // TODO
if (!shop.isAdminShop()) {
int inStock = 0;
int freeSpace = 0;
try {
for (ItemStack content : shop.getInventory().getStorageContents()) {
if (ItemUtil.isEqual(content, product.getItemStack())) {
freeSpace += content.getMaxStackSize() - content.getAmount();
inStock += content.getAmount();
} else if (content == null || content.getType() == Material.AIR) {
freeSpace += product.getItemStack().getMaxStackSize();
}
}
} catch (ChestNotFoundException ignored) {
// Should not be possible since chest has to be clicked
// for this event to be fired.
}
// TODO: i18n
if (shop.canPlayerBuy()) player.sendMessage("§6In stock: §f{0}", inStock);
if (shop.canPlayerSell()) player.sendMessage("§6Free space: §f{0}", freeSpace);
}
if (shop.canPlayerBuy()) player.sendMessage("§6Buy for: §f{0}", plugin.formatEconomy(shop.getBuyPrice()));
if (shop.canPlayerSell()) player.sendMessage("§6Sell for: §f{0}", plugin.formatEconomy(shop.getSellPrice()));
}
}

View File

@ -0,0 +1,42 @@
package de.epiceric.shopchest.listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.api.event.ShopOpenEvent;
import de.epiceric.shopchest.api.event.ShopPreOpenEvent;
import de.epiceric.shopchest.api.flag.OpenFlag;
import de.epiceric.shopchest.api.player.ShopPlayer;
public class ShopOpenListener implements Listener {
private final ShopChest plugin;
public ShopOpenListener(ShopChest plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeCommand(ShopPreOpenEvent e) {
if (!e.getPlayer().hasPermission("shopchest.open.other")) {
e.setCancelled(true);
e.getPlayer().sendMessage("§cYou don't have permission to open this shop."); // TODO: i18n
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onCommand(ShopPreOpenEvent e) {
ShopPlayer player = e.getPlayer();
player.setFlag(new OpenFlag(plugin));
player.sendMessage("§aClick a shop within 15 seconds to open it."); // TODO: i18n
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeAction(ShopOpenEvent e) {
if (e.getShop().isAdminShop()) {
e.setCancelled(true);
e.getPlayer().sendMessage("§cYou cannot open an admin shop."); // TODO: i18n
}
}
}

View File

@ -0,0 +1,90 @@
package de.epiceric.shopchest.listener;
import java.text.MessageFormat;
import java.util.concurrent.CompletableFuture;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.api.event.ShopPreRemoveEvent;
import de.epiceric.shopchest.api.event.ShopRemoveAllEvent;
import de.epiceric.shopchest.api.event.ShopRemoveEvent;
import de.epiceric.shopchest.api.flag.RemoveFlag;
import de.epiceric.shopchest.api.player.ShopPlayer;
import de.epiceric.shopchest.util.Logger;
public class ShopRemoveListener implements Listener {
private final ShopChest plugin;
public ShopRemoveListener(ShopChest plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onCommand(ShopPreRemoveEvent e) {
ShopPlayer player = e.getPlayer();
player.setFlag(new RemoveFlag(plugin));
player.sendMessage("§aClick a shop within 15 seconds to remove it."); // TODO: 18n
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeAction(ShopRemoveEvent e) {
ShopPlayer player = e.getPlayer();
if (e.getShop().isAdminShop()) {
if (!player.hasPermission("shopchest.remove.admin")) {
player.sendMessage("§cYou don't have permission to remove admin shops."); // TODO: i18n
e.setCancelled(true);
}
} else if (!player.isVendor(e.getShop())) {
if (!player.hasPermission("shopchest.remove.other")) {
player.sendMessage("§cYou don't have permission to remove this shop."); // TODO: i18n
e.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onAction(ShopRemoveEvent e) {
plugin.getShopManager()
.removeShop(e.getShop())
.thenRun(() -> e.getPlayer().sendMessage("§aShop has been removed.")) // TODO: i18n
.exceptionally(ex -> {
Logger.severe("Failed to remove shop");
Logger.severe(ex);
e.getPlayer().sendMessage("§cFailed to remove shop: {0}", ex.getMessage()); // TODO: i18n
return null;
});
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeActionAll(ShopRemoveAllEvent e) {
if (!e.getSender().hasPermission("shopchest.remove.all")) {
e.setCancelled(true);
e.getSender().sendMessage("§cYou don't have permission to remove those shops."); // TODO: i18n
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onActionAll(ShopRemoveAllEvent e) {
CompletableFuture<?>[] futures = e.getShops().stream()
.map(shop -> plugin.getShopManager().removeShop(shop))
.toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures)
.thenRun(() -> {
int amount = e.getShops().size();
String shops = amount == 1 ? "shop" : "shops";
e.getSender().sendMessage(MessageFormat.format("§aYou have removed §e{0} {1} §aowned by §e{2}§a.", // TODO: i18n
amount, shops, e.getVendor().getName()));
})
.exceptionally(ex -> {
Logger.severe("Failed to remove all shops of {0}", e.getVendor().getName());
Logger.severe(ex);
e.getSender().sendMessage(MessageFormat.format("§cFailed to remove shops: {0}", ex.getMessage())); // TODO: i18n
return null;
});
}
}

View File

@ -0,0 +1,250 @@
package de.epiceric.shopchest.listener;
import java.text.MessageFormat;
import java.util.Optional;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import de.epiceric.shopchest.ShopChestImpl;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.api.config.Config;
import de.epiceric.shopchest.api.event.ShopUseEvent;
import de.epiceric.shopchest.api.event.ShopUseEvent.Type;
import de.epiceric.shopchest.api.exceptions.ChestNotFoundException;
import de.epiceric.shopchest.api.player.ShopPlayer;
import de.epiceric.shopchest.api.shop.Shop;
import de.epiceric.shopchest.api.shop.ShopProduct;
import de.epiceric.shopchest.util.ItemUtil;
import de.epiceric.shopchest.util.Logger;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.economy.EconomyResponse;
public class ShopUseListener implements Listener {
private static final class InventoryData {
private final int amount;
private final int freeSpace;
private InventoryData(int amount, int freeSpace) {
this.amount = amount;
this.freeSpace = freeSpace;
}
}
private final ShopChest plugin;
public ShopUseListener(ShopChest plugin) {
this.plugin = plugin;
}
private void sendVendorMessage(Optional<OfflinePlayer> vendor, String message, Object... args) {
if (Config.FEATURES_VENDOR_MESSAGES.get()) {
vendor.filter(OfflinePlayer::isOnline)
.map(OfflinePlayer::getPlayer)
.ifPresent(p -> p.sendMessage(MessageFormat.format(message, args)));
}
}
private void checkShiftClick(Shop shop, Player player, ShopUseEvent e) {
int amount = e.getAmount();
double price = e.getPrice();
if (player.isSneaking()) {
int newAmount = shop.getProduct().getItemStack().getMaxStackSize();
double newPrice = price * newAmount / amount;
if (!Config.SHOP_CREATION_ALLOW_DECIMAL_PRICES.get()) {
newPrice = e.getType() == Type.BUY ? Math.ceil(newPrice) : Math.floor(newPrice);
}
e.setPrice(newPrice);
e.setAmount(newAmount);
}
}
private InventoryData getInventoryData(Inventory inventory, ItemStack itemStack) {
int amount = 0;
int freeSpace = 0;
for (ItemStack content : inventory.getStorageContents()) {
if (ItemUtil.isEqual(content, itemStack)) {
amount += content.getAmount();
freeSpace += content.getMaxStackSize() - content.getAmount();
} else if (content == null || content.getType() == Material.AIR) {
freeSpace += itemStack.getMaxStackSize();;
}
}
return new InventoryData(amount, freeSpace);
}
@EventHandler(priority = EventPriority.LOWEST)
public void beforeAction(ShopUseEvent e) {
Shop shop = e.getShop();
ShopProduct product = shop.getProduct();
ShopPlayer player = e.getPlayer();
Player bukkitPlayer = player.getBukkitPlayer();
Economy economy = ((ShopChestImpl) plugin).getEconomy();
if (!player.hasPermission("shopchest.use")) {
player.sendMessage("§cYou don't have permission to use a shop.");
e.setCancelled(true);
return;
}
InventoryData playerData = getInventoryData(bukkitPlayer.getInventory(), product.getItemStack());
InventoryData chestData;
try {
chestData = getInventoryData(shop.getInventory(), product.getItemStack());
} catch (ChestNotFoundException ex) {
Logger.severe("A non-existent chest has been clicked?!");
Logger.severe(ex);
player.sendMessage("§cThe shop chest you clicked does not seem to exist"); // TODO: i18n
e.setCancelled(true);
return;
}
checkShiftClick(shop, bukkitPlayer, e);
// TODO: auto adjust item amount
// Check money, space and available items
if (e.getType() == Type.BUY) {
if (playerData.freeSpace < e.getAmount()) {
player.sendMessage("§cYou don't have enough space in your inventory."); // TODO: i18n
e.setCancelled(true);
return;
}
if (!economy.has(bukkitPlayer, shop.getWorld().getName(), e.getPrice())) {
player.sendMessage("§cYou don't have enough money."); // TODO: i18n
e.setCancelled(true);
return;
}
if (!shop.isAdminShop()) {
if (chestData.amount < e.getAmount()) {
player.sendMessage("§cThis shop is out of items to sell."); // TODO: i18n
sendVendorMessage(shop.getVendor(), "§cYour shop selling §e{0} x {1} §cis out of stick.", // TODO: i18n
product.getAmount(), product.getLocalizedName());
e.setCancelled(true);
return;
}
}
} else if (e.getType() == Type.SELL) {
if (playerData.amount < e.getAmount()) {
player.sendMessage("§cYou don't have enough items to sell."); // TODO: i18n
e.setCancelled(true);
return;
}
if (!shop.isAdminShop()) {
if (!economy.has(shop.getVendor().get(), shop.getWorld().getName(), e.getPrice())) {
player.sendMessage("§cThe vendor of this shop doesn't have enough money."); // TODO: i18n
e.setCancelled(true);
return;
}
if (chestData.freeSpace < e.getAmount()) {
player.sendMessage("§cThis shop doesn't have enough space for your items."); // TODO: i18n
sendVendorMessage(shop.getVendor(), "§cYour shop buying §e{0} x {1} §cis full.", // TODO: i18n
product.getAmount(), product.getLocalizedName());
e.setCancelled(true);
return;
}
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPrepareAction(ShopUseEvent e) {
if (e.isCancelled() && !e.getPlayer().hasPermission("shopchest.use.protected")) {
e.getPlayer().sendMessage("§cYou don't have permission to use this shop.");
return;
}
// Money transaction in highest priority
Shop shop = e.getShop();
Economy economy = ((ShopChestImpl) plugin).getEconomy();
Player bukkitPlayer = e.getPlayer().getBukkitPlayer();
String worldName = e.getShop().getWorld().getName();
if (e.getType() == Type.BUY) {
EconomyResponse rPlayer = economy.withdrawPlayer(bukkitPlayer, worldName, e.getPrice());
if (!rPlayer.transactionSuccess()) {
e.setCancelled(true);
e.getPlayer().sendMessage("§cFailed to withdraw money: {0}", rPlayer.errorMessage); // TODO: i18n
return;
}
shop.getVendor().ifPresent(vendor -> {
EconomyResponse rVendor = economy.depositPlayer(vendor, worldName, e.getPrice());
if (!rVendor.transactionSuccess()) {
e.setCancelled(true);
e.getPlayer().sendMessage("§cFailed to deposit money to vendor: {0}", rVendor.errorMessage); // TODO: i18n
EconomyResponse rBack = economy.depositPlayer(bukkitPlayer, worldName, e.getPrice());
if (!rBack.transactionSuccess()) {
e.getPlayer().sendMessage("§cFailed to reverse your withdrawal: {0}", rBack.errorMessage); // TODO: i18n
}
return;
}
});
} else if (e.getType() == Type.SELL) {
EconomyResponse rPlayer = economy.depositPlayer(bukkitPlayer, worldName, e.getPrice());
if (!rPlayer.transactionSuccess()) {
e.setCancelled(true);
e.getPlayer().sendMessage("§cFailed to deposit money: {0}", rPlayer.errorMessage); // TODO: i18n
return;
}
shop.getVendor().ifPresent(vendor -> {
EconomyResponse rVendor = economy.withdrawPlayer(vendor, worldName, e.getPrice());
if (!rVendor.transactionSuccess()) {
e.setCancelled(true);
e.getPlayer().sendMessage("§cFailed to withdraw money from vendor: {0}", rVendor.errorMessage); // TODO: i18n
EconomyResponse rBack = economy.withdrawPlayer(bukkitPlayer, worldName, e.getPrice());
if (!rBack.transactionSuccess()) {
e.getPlayer().sendMessage("§cFailed to reverse your deposit: {0}", rBack.errorMessage); // TODO: i18n
}
return;
}
});
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onAction(ShopUseEvent e) {
Shop shop = e.getShop();
ShopPlayer player = e.getPlayer();
ShopProduct product = shop.getProduct();
Player bukkitPlayer = player.getBukkitPlayer();
try {
if (e.getType() == Type.BUY) {
for (int i = 0; i < e.getAmount(); i++) {
bukkitPlayer.getInventory().addItem(product.getItemStack());
if (!shop.isAdminShop()) {
shop.getInventory().removeItem(product.getItemStack());
}
}
player.sendMessage("§aYou bought §e{0} x {1} §afor §e{2}.", e.getAmount(),
product.getLocalizedName(), plugin.formatEconomy(e.getPrice()));
} else {
for (int i = 0; i < e.getAmount(); i++) {
bukkitPlayer.getInventory().removeItem(product.getItemStack());
if (!shop.isAdminShop()) {
shop.getInventory().addItem(product.getItemStack());
}
}
player.sendMessage("§aYou sold §e{0} x {1} §afor §e{2}.", e.getAmount(),
product.getLocalizedName(), plugin.formatEconomy(e.getPrice()));
}
} catch (ChestNotFoundException ex) {
Logger.severe("A non-existent chest has been clicked?!");
Logger.severe(ex);
player.sendMessage("§cThe shop chest you clicked does not seem to exist"); // TODO: i18n
}
}
}

View File

@ -0,0 +1,152 @@
package de.epiceric.shopchest.listener.internal;
import java.util.Optional;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Chest;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.api.config.Config;
import de.epiceric.shopchest.api.event.ShopUseEvent;
import de.epiceric.shopchest.api.event.ShopCreateEvent;
import de.epiceric.shopchest.api.event.ShopEditEvent;
import de.epiceric.shopchest.api.event.ShopInfoEvent;
import de.epiceric.shopchest.api.event.ShopOpenEvent;
import de.epiceric.shopchest.api.event.ShopRemoveEvent;
import de.epiceric.shopchest.api.event.ShopUseEvent.Type;
import de.epiceric.shopchest.api.flag.CreateFlag;
import de.epiceric.shopchest.api.flag.EditFlag;
import de.epiceric.shopchest.api.flag.Flag;
import de.epiceric.shopchest.api.flag.InfoFlag;
import de.epiceric.shopchest.api.flag.OpenFlag;
import de.epiceric.shopchest.api.flag.RemoveFlag;
import de.epiceric.shopchest.api.player.ShopPlayer;
import de.epiceric.shopchest.api.shop.Shop;
import de.epiceric.shopchest.shop.ShopImpl;
public class ChestInteractListener implements Listener {
private ShopChest plugin;
public ChestInteractListener(ShopChest plugin) {
this.plugin = plugin;
}
private void handleShopUse(Shop shop, ShopPlayer player, Type type, Cancellable e) {
if (player.isVendor(shop)) {
return; // vendors cannot use their own shops
}
e.setCancelled(true);
if (player.getBukkitPlayer().getGameMode() == GameMode.CREATIVE) {
player.sendMessage("§cYou cannot use a shop in creative mode."); // TODO: i18n
return;
}
if (Config.CORE_INVERT_MOUSE_BUTTONS.get()) {
type = type == Type.BUY ? Type.SELL : Type.BUY;
}
double price = type == Type.BUY ? shop.getBuyPrice() : shop.getSellPrice();
if (price <= 0) {
String typeStr = type == Type.BUY ? "buy" : "sell";
player.sendMessage("§cYou cannot {0} at this shop.", typeStr); // TODO: i18n
return;
}
plugin.getServer().getPluginManager()
.callEvent(new ShopUseEvent(player, shop, type, shop.getProduct().getAmount(), price));
}
private void handleFlags(ShopPlayer player, Shop shop, Cancellable e) {
if (!player.getFlag().isPresent()) {
return;
}
Flag flag = player.getFlag().get();
player.removeFlag();
if (flag instanceof InfoFlag) {
plugin.getServer().getPluginManager().callEvent(new ShopInfoEvent(player, shop));
e.setCancelled(true);
} else if (flag instanceof RemoveFlag) {
plugin.getServer().getPluginManager().callEvent(new ShopRemoveEvent(player, shop));
e.setCancelled(true);
} else if (flag instanceof OpenFlag) {
ShopOpenEvent event = new ShopOpenEvent(player, shop);
plugin.getServer().getPluginManager().callEvent(event);
e.setCancelled(event.isCancelled());
} else if (flag instanceof EditFlag) {
EditFlag editFlag = (EditFlag) flag;
plugin.getServer().getPluginManager().callEvent(new ShopEditEvent(player, shop, editFlag.getItemStack(),
editFlag.getAmount(), editFlag.getBuyPrice(), editFlag.getSellPrice()));
e.setCancelled(true);
} else if (flag instanceof CreateFlag) {
e.setCancelled(true);
player.sendMessage("§cThis chest already is a shop."); // TODO: i18n
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerInteract(PlayerInteractEvent e) {
if (e.getAction() != Action.RIGHT_CLICK_BLOCK && e.getAction() != Action.LEFT_CLICK_BLOCK) {
return;
}
if (e.getHand() != EquipmentSlot.HAND) {
return;
}
if (!(e.getClickedBlock().getState() instanceof Chest)) {
return;
}
Location location = e.getClickedBlock().getLocation();
ShopPlayer player = plugin.wrapPlayer(e.getPlayer());
Optional<Shop> shopOpt = plugin.getShopManager().getShop(location);
if (shopOpt.isPresent()) {
Shop shop = shopOpt.get();
if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (player.getFlag().isPresent()) {
// handle flags
handleFlags(player, shop, e);
} else if (e.hasItem() && e.getItem().getType() == Config.CORE_SHOP_INFO_ITEM.get()) {
// handle shop interaction item
plugin.getServer().getPluginManager().callEvent(new ShopInfoEvent(player, shopOpt.get()));
e.setCancelled(true);
return;
} else {
// handle buy
handleShopUse(shop, player, Type.BUY, e);
}
} else {
// handle sell
handleShopUse(shop, player, Type.SELL, e);
}
} else {
// handle create
if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
player.getFlag().filter(flag -> flag instanceof CreateFlag).ifPresent(f -> {
e.setCancelled(true);
CreateFlag flag = (CreateFlag) f;
player.removeFlag();
OfflinePlayer vendor = flag.isAdminShop() ? null : player.getBukkitPlayer();
plugin.getServer().getPluginManager().callEvent(new ShopCreateEvent(player,
new ShopImpl(vendor, flag.getProduct(), location, flag.getBuyPrice(), flag.getSellPrice()),
Config.SHOP_CREATION_PRICE.get()));
});
}
}
}
}

View File

@ -0,0 +1,52 @@
package de.epiceric.shopchest.listener.internal;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Chunk;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
import de.epiceric.shopchest.ShopChestImpl;
import de.epiceric.shopchest.ShopManagerImpl;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.util.Logger;
public class ChunkLoadListener implements Listener {
private ShopChest plugin;
private final Set<Chunk> newLoadedChunks = new HashSet<>();
public ChunkLoadListener(ShopChest plugin) {
this.plugin = plugin;
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent e) {
if (!((ShopChestImpl) plugin).getDatabase().isInitialized()) {
return;
}
// Wait 10 ticks after first event is triggered, so that multiple
// chunk loads can be handled at the same time without having to
// send a database request for each chunk.
if (newLoadedChunks.isEmpty()) {
plugin.getServer().getScheduler().runTaskLater(plugin, () -> {
int chunkCount = newLoadedChunks.size();
((ShopManagerImpl) plugin.getShopManager())
.loadShops(newLoadedChunks.toArray(new Chunk[chunkCount]))
.exceptionally(ex -> {
Logger.severe("Failed to load shops in newly loaded chunks");
Logger.severe(ex);
return null;
});
newLoadedChunks.clear();
}, 10L);
}
newLoadedChunks.add(e.getChunk());
}
}

View File

@ -0,0 +1,185 @@
package de.epiceric.shopchest.listener.internal;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockMultiPlaceEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.api.event.ShopSelectItemEvent;
import de.epiceric.shopchest.api.flag.SelectFlag;
import de.epiceric.shopchest.api.player.ShopPlayer;
public class CreativeSelectListener implements Listener {
private final ShopChest plugin;
public CreativeSelectListener(ShopChest plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onInventoryClick(InventoryClickEvent e) {
if (!(e.getWhoClicked() instanceof Player)) {
return;
}
ShopPlayer player = plugin.wrapPlayer((Player) e.getWhoClicked());
player.getFlag().filter(flag -> flag instanceof SelectFlag).ifPresent(f -> {
e.setCancelled(true);
if (e.getCursor() == null || e.getCursor().getType() == Material.AIR) {
return;
}
SelectFlag flag = (SelectFlag) f;
player.removeFlag();
plugin.getServer().getScheduler().runTask(plugin, () -> player.getBukkitPlayer().closeInventory());
plugin.getServer().getPluginManager().callEvent(new ShopSelectItemEvent(player, e.getCursor(),
flag.getAmount(), flag.getBuyPrice(), flag.getSellPrice(), flag.getType()));
});
}
@EventHandler
public void onInventoryClose(InventoryCloseEvent e) {
if (!(e.getPlayer() instanceof Player)) {
return;
}
ShopPlayer player = plugin.wrapPlayer((Player) e.getPlayer());
if (hasSelectFlag(player)) {
player.removeFlag();
player.sendMessage("§cShop creation has been cancelled.");
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
// Remove flag to reset game mode if SelectFlag is assigned
plugin.wrapPlayer(e.getPlayer()).removeFlag();
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onInventoryDrag(InventoryDragEvent e) {
// Cancel any inventory drags if SelectFlag is assigned
if (!(e.getWhoClicked() instanceof Player)) {
return;
}
ShopPlayer player = plugin.wrapPlayer((Player) e.getWhoClicked());
if (hasSelectFlag(player)) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onInventoryMove(InventoryMoveItemEvent e) {
// Cancel any inventory movement if SelectFlag is assigned
if (!(e.getSource().getHolder() instanceof Player)) {
return;
}
ShopPlayer player = plugin.wrapPlayer((Player) e.getSource().getHolder());
if (hasSelectFlag(player)) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onEntityPickup(EntityPickupItemEvent e) {
// Cancel any item pickups if SelectFlag is assigned
if (!(e.getEntity() instanceof Player)) {
return;
}
ShopPlayer player = plugin.wrapPlayer((Player) e.getEntity());
if (hasSelectFlag(player)) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onBlockBreak(BlockBreakEvent e) {
// Cancel any block breaks if SelectFlag is assigned
ShopPlayer player = plugin.wrapPlayer(e.getPlayer());
if (hasSelectFlag(player)) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onBlockPlace(BlockPlaceEvent e) {
// Cancel any block places if SelectFlag is assigned
ShopPlayer player = plugin.wrapPlayer(e.getPlayer());
if (hasSelectFlag(player)) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onBlockMultiPlace(BlockMultiPlaceEvent e) {
// Cancel any block places if SelectFlag is assigned
ShopPlayer player = plugin.wrapPlayer(e.getPlayer());
if (hasSelectFlag(player)) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerInteract(PlayerInteractEvent e) {
// Cancel any interactions if SelectFlag is assigned
ShopPlayer player = plugin.wrapPlayer(e.getPlayer());
if (hasSelectFlag(player)) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent e) {
// Cancel any entity interactions if SelectFlag is assigned
ShopPlayer player = plugin.wrapPlayer(e.getPlayer());
if (hasSelectFlag(player)) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerDamageEntity(EntityDamageByEntityEvent e) {
// Cancel any entity damaging if SelectFlag is assigned
if (!(e.getDamager() instanceof Player)) {
return;
}
ShopPlayer player = plugin.wrapPlayer((Player) e.getDamager());
if (hasSelectFlag(player)) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerMove(PlayerMoveEvent e) {
// Cancel any player movement if SelectFlag is assigned
ShopPlayer player = plugin.wrapPlayer(e.getPlayer());
if (hasSelectFlag(player)) {
e.setCancelled(true);
}
}
private boolean hasSelectFlag(ShopPlayer player) {
return player.getFlag().filter(flag -> flag instanceof SelectFlag).isPresent();
}
}

View File

@ -0,0 +1,30 @@
package de.epiceric.shopchest.listener.internal;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import de.epiceric.shopchest.api.ShopChest;
import de.epiceric.shopchest.player.ShopPlayerImpl;
import de.epiceric.shopchest.shop.ShopImpl;
public class PlayerJoinQuitListener implements Listener {
private final ShopChest plugin;
public PlayerJoinQuitListener(ShopChest plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
// TODO: Make dynamic
plugin.getShopManager().getShops(e.getPlayer().getWorld())
.forEach(shop -> ((ShopImpl) shop).getHologram().showPlayer(e.getPlayer()));
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
ShopPlayerImpl.unregister(e.getPlayer());
}
}

View File

@ -64,9 +64,9 @@
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.15.2-R0.1-SNAPSHOT</version>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>