Outsource external checks for shop creation

Every supported plugin has its own listener for ShopCreateEvent
and ShopExtendEvent.

I also tried to clean up a bit, there can be done more though.
This commit is contained in:
Eric 2019-05-03 16:47:35 +02:00
parent 63e1b263c2
commit 1c8cdb0639
14 changed files with 960 additions and 703 deletions

View File

@ -8,6 +8,12 @@ import de.epiceric.shopchest.config.HologramFormat;
import de.epiceric.shopchest.event.ShopInitializedEvent; import de.epiceric.shopchest.event.ShopInitializedEvent;
import de.epiceric.shopchest.external.PlotSquaredShopFlag; import de.epiceric.shopchest.external.PlotSquaredShopFlag;
import de.epiceric.shopchest.external.WorldGuardShopFlag; import de.epiceric.shopchest.external.WorldGuardShopFlag;
import de.epiceric.shopchest.external.listeners.ASkyBlockListener;
import de.epiceric.shopchest.external.listeners.GriefPreventionListener;
import de.epiceric.shopchest.external.listeners.IslandWorldListener;
import de.epiceric.shopchest.external.listeners.PlotSquaredListener;
import de.epiceric.shopchest.external.listeners.TownyListener;
import de.epiceric.shopchest.external.listeners.USkyBlockListener;
import de.epiceric.shopchest.language.LanguageUtils; import de.epiceric.shopchest.language.LanguageUtils;
import de.epiceric.shopchest.listeners.AreaShopListener; import de.epiceric.shopchest.listeners.AreaShopListener;
import de.epiceric.shopchest.listeners.BlockExplodeListener; import de.epiceric.shopchest.listeners.BlockExplodeListener;
@ -196,6 +202,7 @@ public class ShopChest extends JavaPlugin {
5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
registerListeners(); registerListeners();
registerExternalListeners();
initializeShops(); initializeShops();
updater = new ShopUpdater(this); updater = new ShopUpdater(this);
@ -393,6 +400,23 @@ public class ShopChest extends JavaPlugin {
} }
} }
private void registerExternalListeners() {
if (hasASkyBlock())
getServer().getPluginManager().registerEvents(new ASkyBlockListener(this), this);
if (hasGriefPrevention())
getServer().getPluginManager().registerEvents(new GriefPreventionListener(this), this);
if (hasIslandWorld())
getServer().getPluginManager().registerEvents(new IslandWorldListener(this), this);
if (hasPlotSquared())
getServer().getPluginManager().registerEvents(new PlotSquaredListener(this), this);
if (hasTowny())
getServer().getPluginManager().registerEvents(new TownyListener(this), this);
if (hasUSkyBlock())
getServer().getPluginManager().registerEvents(new USkyBlockListener(this), this);
if (hasWorldGuard())
getServer().getPluginManager().registerEvents(new de.epiceric.shopchest.external.listeners.WorldGuardListener(this), this);
}
/** /**
* Initializes the shops * Initializes the shops
*/ */

View File

@ -0,0 +1,37 @@
package de.epiceric.shopchest.event;
import de.epiceric.shopchest.shop.Shop;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
/**
* Called when a player extends a shop (making a chest a double chest)
*/
public class ShopExtendEvent extends ShopEvent implements Cancellable {
private boolean cancelled;
private Location newChestLocation;
public ShopExtendEvent(Player player, Shop shop, Location newChest) {
super(player, shop);
this.newChestLocation = newChest;
}
/**
* @return Location of the placed chest
*/
public Location getNewChestLocation() {
return newChestLocation;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
}

View File

@ -0,0 +1,62 @@
package de.epiceric.shopchest.external.listeners;
import java.util.Set;
import com.wasteofplastic.askyblock.ASkyBlockAPI;
import com.wasteofplastic.askyblock.Island;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.event.ShopCreateEvent;
import de.epiceric.shopchest.event.ShopExtendEvent;
import de.epiceric.shopchest.utils.Utils;
public class ASkyBlockListener implements Listener {
private final ShopChest plugin;
public ASkyBlockListener(ShopChest plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCreateShop(ShopCreateEvent e) {
if (!Config.enableASkyblockIntegration)
return;
Set<Location> chestLocations = Utils.getChestLocations(e.getShop());
for (Location loc : chestLocations) {
if (handleForLocation(e.getPlayer(), loc, e))
return;
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onExtendShop(ShopExtendEvent e) {
if (!Config.enableASkyblockIntegration)
return;
handleForLocation(e.getPlayer(), e.getNewChestLocation(), e);
}
private boolean handleForLocation(Player player, Location loc, Cancellable e) {
Island island = ASkyBlockAPI.getInstance().getIslandAt(loc);
if (island == null)
return false;
if (!player.getUniqueId().equals(island.getOwner()) && !island.getMembers().contains(player.getUniqueId())) {
e.setCancelled(true);
plugin.debug("Cancel Reason: ASkyBlock");
return true;
}
return false;
}
}

View File

@ -0,0 +1,62 @@
package de.epiceric.shopchest.external.listeners;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.event.ShopCreateEvent;
import de.epiceric.shopchest.event.ShopExtendEvent;
import de.epiceric.shopchest.utils.Utils;
import me.ryanhamshire.GriefPrevention.Claim;
import me.ryanhamshire.GriefPrevention.GriefPrevention;
public class GriefPreventionListener implements Listener {
private final ShopChest plugin;
private final GriefPrevention griefPrevention;
public GriefPreventionListener(ShopChest plugin) {
this.plugin = plugin;
this.griefPrevention = plugin.getGriefPrevention();
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCreateShop(ShopCreateEvent e) {
if (!Config.enableGriefPreventionIntegration)
return;
Set<Location> chestLocations = Utils.getChestLocations(e.getShop());
for (Location loc : chestLocations) {
if (handleForLocation(e.getPlayer(), loc, e))
return;
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onExtendShop(ShopExtendEvent e) {
if (!Config.enableASkyblockIntegration)
return;
handleForLocation(e.getPlayer(), e.getNewChestLocation(), e);
}
private boolean handleForLocation(Player player, Location loc, Cancellable e) {
Claim claim = griefPrevention.dataStore.getClaimAt(loc, false, null);
if (claim == null)
return false;
if (claim.allowContainers(player) != null) {
e.setCancelled(true);
plugin.debug("Cancel Reason: GriefPrevention");
return true;
}
return false;
}
}

View File

@ -0,0 +1,59 @@
package de.epiceric.shopchest.external.listeners;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.event.ShopCreateEvent;
import de.epiceric.shopchest.event.ShopExtendEvent;
import de.epiceric.shopchest.utils.Utils;
import pl.islandworld.api.IslandWorldApi;
public class IslandWorldListener implements Listener {
private final ShopChest plugin;
public IslandWorldListener(ShopChest plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCreateShop(ShopCreateEvent e) {
if (!Config.enableIslandWorldIntegration || !IslandWorldApi.isInitialized())
return;
Set<Location> chestLocations = Utils.getChestLocations(e.getShop());
for (Location loc : chestLocations) {
if (handleForLocation(e.getPlayer(), loc, e))
return;
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onExtendShop(ShopExtendEvent e) {
if (!Config.enableIslandWorldIntegration || !IslandWorldApi.isInitialized())
return;
handleForLocation(e.getPlayer(), e.getNewChestLocation(), e);
}
private boolean handleForLocation(Player player, Location loc, Cancellable e) {
if (!loc.getWorld().getName().equals(IslandWorldApi.getIslandWorld().getName()))
return false;
if (!IslandWorldApi.canBuildOnLocation(player, loc, true)) {
e.setCancelled(true);
plugin.debug("Cancel Reason: IslandWorld");
return true;
}
return false;
}
}

View File

@ -0,0 +1,80 @@
package de.epiceric.shopchest.external.listeners;
import java.util.Set;
import com.github.intellectualsites.plotsquared.plot.object.Location;
import com.github.intellectualsites.plotsquared.plot.object.Plot;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.event.ShopCreateEvent;
import de.epiceric.shopchest.event.ShopExtendEvent;
import de.epiceric.shopchest.external.PlotSquaredShopFlag;
import de.epiceric.shopchest.utils.Utils;
public class PlotSquaredListener implements Listener {
private final ShopChest plugin;
public PlotSquaredListener(ShopChest plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCreateShop(ShopCreateEvent e) {
if (!Config.enablePlotsquaredIntegration)
return;
Set<org.bukkit.Location> chestLocations = Utils.getChestLocations(e.getShop());
for (org.bukkit.Location loc : chestLocations) {
if (handleForLocation(e.getPlayer(), loc, e))
return;
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onExtendShop(ShopExtendEvent e) {
if (!Config.enablePlotsquaredIntegration)
return;
handleForLocation(e.getPlayer(), e.getNewChestLocation(), e);
}
// TODO: Outsource shop use external permission
// @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
// public void onBuySell(ShopBuySellEvent e) {
// if (!Config.enablePlotsquaredIntegration)
// return;
// ShopType shopType = e.getShop().getShopType();
// GroupFlag flag = shopType == ShopType.ADMIN ? PlotSquaredShopFlag.USE_ADMIN_SHOP : PlotSquaredShopFlag.USE_SHOP;
// Set<org.bukkit.Location> chestLocations = Utils.getChestLocations(e.getShop());
// for (org.bukkit.Location loc : chestLocations) {
// Location plotLocation = new Location(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
// Plot plot = plotLocation.getOwnedPlot();
// if (!isFlagAllowed(plot, flag, e.getPlayer())) {
// e.setCancelled(true);
// plugin.debug("Cancel Reason: PlotSquared");
// return;
// }
// }
// }
private boolean handleForLocation(Player player, org.bukkit.Location loc, Cancellable e) {
Location plotLocation = new Location(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
Plot plot = plotLocation.getOwnedPlot();
if (!PlotSquaredShopFlag.isFlagAllowedOnPlot(plot, PlotSquaredShopFlag.CREATE_SHOP, player)) {
e.setCancelled(true);
plugin.debug("Cancel Reason: PlotSquared");
return true;
}
return false;
}
}

View File

@ -0,0 +1,84 @@
package de.epiceric.shopchest.external.listeners;
import java.util.Optional;
import java.util.Set;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownBlock;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.event.ShopCreateEvent;
import de.epiceric.shopchest.event.ShopExtendEvent;
import de.epiceric.shopchest.utils.Utils;
public class TownyListener implements Listener {
private final ShopChest plugin;
public TownyListener(ShopChest plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCreateShop(ShopCreateEvent e) {
if (!Config.enableTownyIntegration)
return;
Set<Location> chestLocations = Utils.getChestLocations(e.getShop());
for (Location loc : chestLocations) {
if (handleForLocation(e.getPlayer(), loc, e))
return;
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onExtendShop(ShopExtendEvent e) {
if (!Config.enablePlotsquaredIntegration)
return;
handleForLocation(e.getPlayer(), e.getNewChestLocation(), e);
}
private boolean handleForLocation(Player player, Location loc, Cancellable e) {
TownBlock townBlock = TownyUniverse.getTownBlock(loc);
if (townBlock == null)
return false;
try {
Town town = townBlock.getTown();
Optional<Resident> playerResident = town.getResidents().stream()
.filter(r -> r.getName().equals(player.getName()))
.findFirst();
if (!playerResident.isPresent()) {
e.setCancelled(true);
plugin.debug("Cancel Reason: Towny (no resident)");
return true;
}
Resident resident = playerResident.get();
String plotType = townBlock.getType().name();
boolean cancel = (resident.isMayor() && !Config.townyShopPlotsMayor.contains(plotType))
|| (resident.isKing() && !Config.townyShopPlotsKing.contains(plotType))
|| (!resident.isKing() && !resident.isMayor() && !Config.townyShopPlotsResidents.contains(plotType));
if (cancel) {
e.setCancelled(true);
plugin.debug("Cancel Reason: Towny (no permission)");
return true;
}
} catch (NotRegisteredException ignored) {
}
return false;
}
}

View File

@ -0,0 +1,61 @@
package de.epiceric.shopchest.external.listeners;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.event.ShopCreateEvent;
import de.epiceric.shopchest.event.ShopExtendEvent;
import de.epiceric.shopchest.utils.Utils;
import us.talabrek.ultimateskyblock.api.IslandInfo;
import us.talabrek.ultimateskyblock.api.uSkyBlockAPI;
public class USkyBlockListener implements Listener {
private final ShopChest plugin;
private final uSkyBlockAPI uSkyBlockAPI;
public USkyBlockListener(ShopChest plugin) {
this.plugin = plugin;
this.uSkyBlockAPI = plugin.getUSkyBlock();
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCreateShop(ShopCreateEvent e) {
if (!Config.enableUSkyblockIntegration)
return;
Set<Location> chestLocations = Utils.getChestLocations(e.getShop());
for (Location loc : chestLocations) {
if (handleForLocation(e.getPlayer(), loc, e))
return;
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onExtendShop(ShopExtendEvent e) {
if (!Config.enablePlotsquaredIntegration)
return;
handleForLocation(e.getPlayer(), e.getNewChestLocation(), e);
}
private boolean handleForLocation(Player player, Location loc, Cancellable e) {
IslandInfo islandInfo = uSkyBlockAPI.getIslandInfo(loc);
if (islandInfo == null)
return false;
if (!player.getName().equals(islandInfo.getLeader()) && !islandInfo.getMembers().contains(player.getName())) {
e.setCancelled(true);
plugin.debug("Cancel Reason: uSkyBlock");
return true;
}
return false;
}
}

View File

@ -0,0 +1,92 @@
package de.epiceric.shopchest.external.listeners;
import java.util.Optional;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.codemc.worldguardwrapper.WorldGuardWrapper;
import org.codemc.worldguardwrapper.flag.IWrappedFlag;
import org.codemc.worldguardwrapper.flag.WrappedState;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.event.ShopCreateEvent;
import de.epiceric.shopchest.event.ShopExtendEvent;
import de.epiceric.shopchest.utils.Utils;
public class WorldGuardListener implements Listener {
private final ShopChest plugin;
private final WorldGuardWrapper wgWrapper;
public WorldGuardListener(ShopChest plugin) {
this.plugin = plugin;
this.wgWrapper = WorldGuardWrapper.getInstance();
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCreateShop(ShopCreateEvent e) {
if (!Config.enableWorldGuardIntegration)
return;
Set<Location> chestLocations = Utils.getChestLocations(e.getShop());
IWrappedFlag<WrappedState> flag = getStateFlag("create-shop");
for (Location loc : chestLocations) {
if (handleForLocation(e.getPlayer(), loc, e, flag))
return;
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onExtendShop(ShopExtendEvent e) {
if (!Config.enableWorldGuardIntegration)
return;
handleForLocation(e.getPlayer(), e.getNewChestLocation(), e, getStateFlag("create-shop"));
}
// TODO: Outsource shop use external permission
// @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
// public void onBuySell(ShopBuySellEvent e) {
// if (!Config.enableWorldGuardIntegration)
// return;
// Set<Location> chestLocations = Utils.getChestLocations(e.getShop());
// String flagName = e.getShop().getShopType() == ShopType.ADMIN ? "use-admin-shop" : "use-shop";
// IWrappedFlag<WrappedState> flag = getStateFlag(flagName);
// for (Location loc : chestLocations) {
// WrappedState state = wgWrapper.queryFlag(e.getPlayer(), loc, flag).orElse(WrappedState.DENY);
// if (state == WrappedState.DENY) {
// e.setCancelled(true);
// return;
// }
// }
// }
private boolean handleForLocation(Player player, Location loc, Cancellable e, IWrappedFlag<WrappedState> flag) {
WrappedState state = wgWrapper.queryFlag(player, loc, flag).orElse(WrappedState.DENY);
if (state == WrappedState.DENY) {
e.setCancelled(true);
plugin.debug("Cancel Reason: WorldGuard");
return true;
}
return false;
}
private IWrappedFlag<WrappedState> getStateFlag(String flagName) {
Optional<IWrappedFlag<WrappedState>> flagOptional = wgWrapper.getFlag(flagName, WrappedState.class);
if (!flagOptional.isPresent()) {
plugin.getLogger().severe("Failed to get WorldGuard flag '" + flagName + "'.");
plugin.debug("WorldGuard flag '" + flagName + "' is not present!");
return null;
}
return flagOptional.get();
}
}

View File

@ -7,9 +7,9 @@ public class Replacement {
private Placeholder placeholder; private Placeholder placeholder;
private String replacement; private String replacement;
public Replacement(Placeholder placeholder, String replacement) { public Replacement(Placeholder placeholder, Object replacement) {
this.placeholder = placeholder; this.placeholder = placeholder;
this.replacement = replacement; this.replacement = String.valueOf(replacement);
} }
/** /**

View File

@ -1,19 +1,12 @@
package de.epiceric.shopchest.listeners; package de.epiceric.shopchest.listeners;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownBlock;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import com.wasteofplastic.askyblock.ASkyBlockAPI;
import com.wasteofplastic.askyblock.Island;
import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config; import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.config.Placeholder; import de.epiceric.shopchest.config.Placeholder;
import de.epiceric.shopchest.external.PlotSquaredShopFlag; import de.epiceric.shopchest.event.ShopExtendEvent;
import de.epiceric.shopchest.language.LanguageUtils; import de.epiceric.shopchest.language.LanguageUtils;
import de.epiceric.shopchest.language.Message; import de.epiceric.shopchest.language.Message;
import de.epiceric.shopchest.language.Replacement; import de.epiceric.shopchest.language.Replacement;
import de.epiceric.shopchest.nms.Hologram;
import de.epiceric.shopchest.shop.Shop; import de.epiceric.shopchest.shop.Shop;
import de.epiceric.shopchest.shop.Shop.ShopType; import de.epiceric.shopchest.shop.Shop.ShopType;
import de.epiceric.shopchest.utils.Callback; import de.epiceric.shopchest.utils.Callback;
@ -21,9 +14,9 @@ import de.epiceric.shopchest.utils.ItemUtils;
import de.epiceric.shopchest.utils.Permissions; import de.epiceric.shopchest.utils.Permissions;
import de.epiceric.shopchest.utils.ShopUtils; import de.epiceric.shopchest.utils.ShopUtils;
import de.epiceric.shopchest.utils.Utils; import de.epiceric.shopchest.utils.Utils;
import me.ryanhamshire.GriefPrevention.Claim;
import net.milkbowl.vault.economy.EconomyResponse; import net.milkbowl.vault.economy.EconomyResponse;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -31,27 +24,18 @@ import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest; import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest; import org.bukkit.block.DoubleChest;
import org.bukkit.block.data.type.Chest.Type; import org.bukkit.block.data.type.Chest.Type;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryHolder;
import org.codemc.worldguardwrapper.WorldGuardWrapper;
import org.codemc.worldguardwrapper.flag.IWrappedFlag;
import org.codemc.worldguardwrapper.flag.WrappedState;
import pl.islandworld.api.IslandWorldApi;
import us.talabrek.ultimateskyblock.api.IslandInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Optional;
public class ChestProtectListener implements Listener { public class ChestProtectListener implements Listener {
@ -153,6 +137,9 @@ public class ChestProtectListener implements Listener {
Chest c = (Chest) b.getState(); Chest c = (Chest) b.getState();
Block b2; Block b2;
// Can't use Utils::getChestLocations since inventory holder
// has not been updated yet in this event (for 1.13+)
if (Utils.getMajorVersion() < 13) { if (Utils.getMajorVersion() < 13) {
InventoryHolder ih = c.getInventory().getHolder(); InventoryHolder ih = c.getInventory().getHolder();
if (!(ih instanceof DoubleChest)) { if (!(ih instanceof DoubleChest)) {
@ -197,85 +184,32 @@ public class ChestProtectListener implements Listener {
b2 = b.getRelative(neighborFacing); b2 = b.getRelative(neighborFacing);
} }
if (shopUtils.isShop(b.getLocation()) || shopUtils.isShop(b2.getLocation())) {
final Shop shop = shopUtils.getShop(b2.getLocation()); final Shop shop = shopUtils.getShop(b2.getLocation());
if (shop == null)
return;
plugin.debug(String.format("%s tries to extend %s's shop (#%d)", p.getName(), shop.getVendor().getName(), shop.getID())); plugin.debug(String.format("%s tries to extend %s's shop (#%d)", p.getName(), shop.getVendor().getName(), shop.getID()));
boolean externalPluginsAllowed = true; ShopExtendEvent event = new ShopExtendEvent(p, shop, b.getLocation());
Bukkit.getPluginManager().callEvent(event);
if (plugin.hasWorldGuard() && Config.enableWorldGuardIntegration) { if (event.isCancelled() && !p.hasPermission(Permissions.EXTEND_PROTECTED)) {
WorldGuardWrapper wgWrapper = WorldGuardWrapper.getInstance(); e.setCancelled(true);
Optional<IWrappedFlag<WrappedState>> flag = wgWrapper.getFlag("create-shop", WrappedState.class); p.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_EXTEND_PROTECTED));
if (!flag.isPresent()) plugin.debug("WorldGuard flag 'create-shop' is not present!"); return;
WrappedState state = flag.map(f -> wgWrapper.queryFlag(p, b.getLocation(), f).orElse(WrappedState.DENY)).orElse(WrappedState.DENY);
externalPluginsAllowed = state == WrappedState.ALLOW;
} }
if (externalPluginsAllowed && plugin.hasTowny() && Config.enableTownyIntegration) { if (!p.getUniqueId().equals(shop.getVendor().getUniqueId()) && !p.hasPermission(Permissions.EXTEND_OTHER)) {
TownBlock townBlock = TownyUniverse.getTownBlock(b.getLocation()); e.setCancelled(true);
if (townBlock != null) { p.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_EXTEND_OTHERS));
try { return;
Town town = townBlock.getTown();
for (Resident resident : town.getResidents()) {
if (resident.getName().equals(p.getName())) {
if (resident.isMayor()) {
externalPluginsAllowed = (Config.townyShopPlotsMayor.contains(townBlock.getType().name()));
} else if (resident.isKing()) {
externalPluginsAllowed = (Config.townyShopPlotsKing.contains(townBlock.getType().name()));
} else {
externalPluginsAllowed = (Config.townyShopPlotsResidents.contains(townBlock.getType().name()));
}
break;
}
}
} catch (Exception ex) {
plugin.debug(ex);
}
}
} }
if (externalPluginsAllowed && plugin.hasPlotSquared() && Config.enablePlotsquaredIntegration) { if (!ItemUtils.isAir(b.getRelative(BlockFace.UP).getType())) {
com.github.intellectualsites.plotsquared.plot.object.Location loc = e.setCancelled(true);
new com.github.intellectualsites.plotsquared.plot.object.Location(b.getWorld().getName(), b.getX(), b.getY(), b.getZ()); p.sendMessage(LanguageUtils.getMessage(Message.CHEST_BLOCKED));
return;
externalPluginsAllowed = PlotSquaredShopFlag.isFlagAllowedOnPlot(loc.getOwnedPlot(), PlotSquaredShopFlag.CREATE_SHOP, p);
} }
if (externalPluginsAllowed && plugin.hasUSkyBlock() && Config.enableUSkyblockIntegration) {
IslandInfo islandInfo = plugin.getUSkyBlock().getIslandInfo(b.getLocation());
if (islandInfo != null) {
externalPluginsAllowed = islandInfo.getMembers().contains(p.getName()) || islandInfo.getLeader().equals(p.getName());
}
}
if (externalPluginsAllowed && plugin.hasASkyBlock() && Config.enableASkyblockIntegration) {
Island island = ASkyBlockAPI.getInstance().getIslandAt(b.getLocation());
if (island != null) {
if (island.getOwner() == null) {
externalPluginsAllowed = island.getMembers().contains(p.getUniqueId());
} else {
externalPluginsAllowed = island.getMembers().contains(p.getUniqueId()) || island.getOwner().equals(p.getUniqueId());
}
}
}
if (externalPluginsAllowed && plugin.hasIslandWorld() && Config.enableIslandWorldIntegration && IslandWorldApi.isInitialized()) {
if (b.getWorld().getName().equals(IslandWorldApi.getIslandWorld().getName())) {
externalPluginsAllowed = IslandWorldApi.canBuildOnLocation(p, b.getLocation(), true);
}
}
if (externalPluginsAllowed && plugin.hasGriefPrevention() && Config.enableGriefPreventionIntegration) {
Claim claim = plugin.getGriefPrevention().dataStore.getClaimAt(b.getLocation(), false, null);
if (claim != null) {
externalPluginsAllowed = claim.allowContainers(p) == null;
}
}
if (externalPluginsAllowed || p.hasPermission(Permissions.EXTEND_PROTECTED)) {
if (shop.getVendor().getUniqueId().equals(p.getUniqueId()) || p.hasPermission(Permissions.EXTEND_OTHER)) {
if (ItemUtils.isAir(b.getRelative(BlockFace.UP).getType())) {
final Shop newShop = new Shop(shop.getID(), plugin, shop.getVendor(), shop.getProduct(), shop.getLocation(), shop.getBuyPrice(), shop.getSellPrice(), shop.getShopType()); final Shop newShop = new Shop(shop.getID(), plugin, shop.getVendor(), shop.getProduct(), shop.getLocation(), shop.getBuyPrice(), shop.getSellPrice(), shop.getShopType());
shopUtils.removeShop(shop, true, new Callback<Void>(plugin) { shopUtils.removeShop(shop, true, new Callback<Void>(plugin) {
@ -286,28 +220,6 @@ public class ChestProtectListener implements Listener {
plugin.debug(String.format("%s extended %s's shop (#%d)", p.getName(), shop.getVendor().getName(), shop.getID())); plugin.debug(String.format("%s extended %s's shop (#%d)", p.getName(), shop.getVendor().getName(), shop.getID()));
} }
}); });
} else {
e.setCancelled(true);
p.sendMessage(LanguageUtils.getMessage(Message.CHEST_BLOCKED));
}
} else {
e.setCancelled(true);
p.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_EXTEND_OTHERS));
}
} else {
e.setCancelled(true);
p.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_EXTEND_PROTECTED));
}
}
}
@EventHandler(ignoreCancelled = true)
public void onHologramDamage(EntityDamageEvent e) {
if (e.getEntity() instanceof ArmorStand) {
if (Hologram.isPartOfHologram((ArmorStand) e.getEntity())) {
e.setCancelled(true);
}
}
} }
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)

View File

@ -1,13 +1,7 @@
package de.epiceric.shopchest.listeners; package de.epiceric.shopchest.listeners;
import com.google.gson.JsonPrimitive;
import com.github.intellectualsites.plotsquared.plot.object.Plot; import com.github.intellectualsites.plotsquared.plot.object.Plot;
import com.palmergames.bukkit.towny.object.Resident; import com.google.gson.JsonPrimitive;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownBlock;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import com.wasteofplastic.askyblock.ASkyBlockAPI;
import com.wasteofplastic.askyblock.Island;
import de.epiceric.shopchest.ShopChest; import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config; import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.config.Placeholder; import de.epiceric.shopchest.config.Placeholder;
@ -33,7 +27,6 @@ import de.epiceric.shopchest.utils.Permissions;
import de.epiceric.shopchest.utils.ShopUtils; import de.epiceric.shopchest.utils.ShopUtils;
import de.epiceric.shopchest.utils.Utils; import de.epiceric.shopchest.utils.Utils;
import fr.xephi.authme.api.v3.AuthMeApi; import fr.xephi.authme.api.v3.AuthMeApi;
import me.ryanhamshire.GriefPrevention.Claim;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.economy.EconomyResponse; import net.milkbowl.vault.economy.EconomyResponse;
@ -54,12 +47,10 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent; import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@ -67,9 +58,6 @@ import org.codemc.worldguardwrapper.WorldGuardWrapper;
import org.codemc.worldguardwrapper.flag.IWrappedFlag; import org.codemc.worldguardwrapper.flag.IWrappedFlag;
import org.codemc.worldguardwrapper.flag.WrappedState; import org.codemc.worldguardwrapper.flag.WrappedState;
import pl.islandworld.api.IslandWorldApi;
import us.talabrek.ultimateskyblock.api.IslandInfo;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -124,193 +112,36 @@ public class ShopInteractListener implements Listener {
}.runTaskLater(plugin, 1L); }.runTaskLater(plugin, 1L);
} }
@EventHandler(ignoreCancelled = true)
public void onPlayerManipulateArmorStand(PlayerArmorStandManipulateEvent e) {
// When clicking an armor stand with an armor item, the armor stand will take it.
// As a hologram consists of armor stands, they would also take the item.
ArmorStand armorStand = e.getRightClicked();
if (Hologram.isPartOfHologram(armorStand)) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGH) @EventHandler(priority = EventPriority.HIGH)
public void onPlayerInteractCreate(PlayerInteractEvent e) { public void onPlayerInteractCreate(PlayerInteractEvent e) {
Player p = e.getPlayer(); Player p = e.getPlayer();
Block b = e.getClickedBlock(); Block b = e.getClickedBlock();
if (Config.enableAuthMeIntegration && plugin.hasAuthMe() && !AuthMeApi.getInstance().isAuthenticated(p)) return; if (e.getAction() != Action.RIGHT_CLICK_BLOCK)
if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (b.getType().equals(Material.CHEST) || b.getType().equals(Material.TRAPPED_CHEST)) {
if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (ClickType.getPlayerClickType(p) != null) {
if (ClickType.getPlayerClickType(p).getClickType() == ClickType.EnumClickType.CREATE) {
if (!shopUtils.isShop(b.getLocation())) {
boolean externalPluginsAllowed = true;
Location[] chestLocations = {b.getLocation(), null};
InventoryHolder ih = ((Chest) b.getState()).getInventory().getHolder();
if (ih instanceof DoubleChest) {
DoubleChest dc = (DoubleChest) ih;
chestLocations[0] = ((Chest) dc.getLeftSide()).getLocation();
chestLocations[1] = ((Chest) dc.getRightSide()).getLocation();
}
String denyReason = "Event Cancelled";
if (plugin.hasWorldGuard() && Config.enableWorldGuardIntegration) {
plugin.debug("Checking if WorldGuard allows shop creation...");
WorldGuardWrapper wgWrapper = WorldGuardWrapper.getInstance();
Optional<IWrappedFlag<WrappedState>> flag = wgWrapper.getFlag("create-shop", WrappedState.class);
if (flag.isPresent()) {
for (Location loc : chestLocations) {
if (loc != null) {
WrappedState state = wgWrapper.queryFlag(p, loc, flag.get()).orElse(WrappedState.DENY);
externalPluginsAllowed = state == WrappedState.ALLOW;
}
}
} else {
plugin.debug("WorldGuard flag 'create-shop' is not present!");
}
if (!externalPluginsAllowed) denyReason = "WorldGuard";
}
if (externalPluginsAllowed && plugin.hasTowny() && Config.enableTownyIntegration) {
plugin.debug("Checking if Towny allows shop creation...");
for (Location loc : chestLocations) {
if (loc != null) {
TownBlock townBlock = TownyUniverse.getTownBlock(loc);
if (townBlock != null) {
plugin.debug("Plot Type is " + townBlock.getType().name());
try {
Town town = townBlock.getTown();
boolean residentFound = false;
for (Resident resident : town.getResidents()) {
if (resident.getName().equals(p.getName())) {
residentFound = true;
if (resident.isMayor()) {
plugin.debug(p.getName() + " is mayor of town");
externalPluginsAllowed &= (Config.townyShopPlotsMayor.contains(townBlock.getType().name()));
} else if (resident.isKing()) {
plugin.debug(p.getName() + " is king of town");
externalPluginsAllowed &= (Config.townyShopPlotsKing.contains(townBlock.getType().name()));
} else {
plugin.debug(p.getName() + " is resident in town");
externalPluginsAllowed &= (Config.townyShopPlotsResidents.contains(townBlock.getType().name()));
}
break;
}
}
if (!residentFound) {
plugin.debug(p.getName() + " is not resident in town");
externalPluginsAllowed = false;
}
} catch (Exception ex) {
plugin.debug(ex);
}
}
}
}
if (!externalPluginsAllowed) denyReason = "Towny";
}
if (externalPluginsAllowed && plugin.hasPlotSquared() && Config.enablePlotsquaredIntegration) {
plugin.debug("Checking if PlotSquared allows shop creation...");
for (Location loc : chestLocations) {
if (loc != null) {
com.github.intellectualsites.plotsquared.plot.object.Location plotLocation = new com.github.intellectualsites.plotsquared.plot.object.Location(
loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
Plot plot = plotLocation.getOwnedPlot();
externalPluginsAllowed &= PlotSquaredShopFlag.isFlagAllowedOnPlot(plot, PlotSquaredShopFlag.CREATE_SHOP, p);
}
}
if (!externalPluginsAllowed) denyReason = "PlotSquared";
}
if (externalPluginsAllowed && plugin.hasUSkyBlock() && Config.enableUSkyblockIntegration) {
plugin.debug("Checking if uSkyBlock allows shop creation...");
for (Location loc : chestLocations) {
if (loc != null) {
IslandInfo islandInfo = plugin.getUSkyBlock().getIslandInfo(loc);
if (islandInfo != null) {
plugin.debug("Chest is on island of " + islandInfo.getLeader());
externalPluginsAllowed &= islandInfo.getMembers().contains(p.getName()) || islandInfo.getLeader().equals(p.getName());
}
}
}
if (!externalPluginsAllowed) denyReason = "uSkyBlock";
}
if (externalPluginsAllowed && plugin.hasASkyBlock() && Config.enableASkyblockIntegration) {
plugin.debug("Checking if ASkyBlock allows shop creation...");
for (Location loc : chestLocations) {
if (loc != null) {
Island island = ASkyBlockAPI.getInstance().getIslandAt(loc);
if (island != null) {
if (island.getOwner() == null) {
plugin.debug("Chest is on an unowned island.");
externalPluginsAllowed &= island.getMembers().contains(p.getUniqueId());
} else {
plugin.debug("Chest is on island of " + Bukkit.getOfflinePlayer(island.getOwner()).getName());
externalPluginsAllowed &= island.getMembers().contains(p.getUniqueId()) || island.getOwner().equals(p.getUniqueId());
}
}
}
}
if (!externalPluginsAllowed) denyReason = "ASkyBlock";
}
if (externalPluginsAllowed && plugin.hasIslandWorld() && Config.enableIslandWorldIntegration && IslandWorldApi.isInitialized()) {
plugin.debug("Checking if IslandWorld allows shop creation...");
for (Location loc : chestLocations) {
if (loc != null) {
if (loc.getWorld().getName().equals(IslandWorldApi.getIslandWorld().getName())) {
plugin.debug("Chest is in island world");
externalPluginsAllowed &= IslandWorldApi.canBuildOnLocation(p, loc, true);
}
}
}
if (!externalPluginsAllowed) denyReason = "IslandWorld";
}
if (externalPluginsAllowed && plugin.hasGriefPrevention() && Config.enableGriefPreventionIntegration) {
plugin.debug("Checking if GriefPrevention allows shop creation...");
String gpDenyReason = null;
for (Location loc : chestLocations) {
if (loc != null) {
Claim claim = plugin.getGriefPrevention().dataStore.getClaimAt(loc, false, null);
if (claim != null) {
plugin.debug("Checking if claim allows container access");
gpDenyReason = claim.allowContainers(p);
externalPluginsAllowed &= gpDenyReason == null;
}
}
}
if (!externalPluginsAllowed) denyReason = "GriefPrevention (" + gpDenyReason + ")";
}
if ((e.isCancelled() || !externalPluginsAllowed) && !p.hasPermission(Permissions.CREATE_PROTECTED)) {
p.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_CREATE_PROTECTED));
ClickType.removePlayerClickType(p);
plugin.debug(p.getName() + " is not allowed to create a shop on the selected chest because " + denyReason);
e.setCancelled(true);
return; return;
}
e.setCancelled(true); if (ClickType.getPlayerClickType(p) == null)
return;
if (ItemUtils.isAir(b.getRelative(BlockFace.UP).getType())) { if (b.getType() != Material.CHEST && b.getType() != Material.TRAPPED_CHEST)
return;
if (ClickType.getPlayerClickType(p).getClickType() != ClickType.EnumClickType.CREATE)
return;
if (Config.enableAuthMeIntegration && plugin.hasAuthMe() && !AuthMeApi.getInstance().isAuthenticated(p))
return;
if (shopUtils.isShop(b.getLocation())) {
p.sendMessage(LanguageUtils.getMessage(Message.CHEST_ALREADY_SHOP));
plugin.debug("Chest is already a shop");
} else if (e.isCancelled() && !p.hasPermission(Permissions.CREATE_PROTECTED)) {
p.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_CREATE_PROTECTED));
plugin.debug(p.getName() + " is not allowed to create a shop on the selected chest");
} else if (!ItemUtils.isAir(b.getRelative(BlockFace.UP).getType())) {
p.sendMessage(LanguageUtils.getMessage(Message.CHEST_BLOCKED));
plugin.debug("Chest is blocked");
} else {
ClickType clickType = ClickType.getPlayerClickType(p); ClickType clickType = ClickType.getPlayerClickType(p);
ShopProduct product = clickType.getProduct(); ShopProduct product = clickType.getProduct();
double buyPrice = clickType.getBuyPrice(); double buyPrice = clickType.getBuyPrice();
@ -318,23 +149,11 @@ public class ShopInteractListener implements Listener {
ShopType shopType = clickType.getShopType(); ShopType shopType = clickType.getShopType();
create(p, b.getLocation(), product, buyPrice, sellPrice, shopType); create(p, b.getLocation(), product, buyPrice, sellPrice, shopType);
} else {
p.sendMessage(LanguageUtils.getMessage(Message.CHEST_BLOCKED));
plugin.debug("Chest is blocked");
}
} else {
e.setCancelled(true);
p.sendMessage(LanguageUtils.getMessage(Message.CHEST_ALREADY_SHOP));
plugin.debug("Chest is already a shop");
} }
e.setCancelled(true);
ClickType.removePlayerClickType(p); ClickType.removePlayerClickType(p);
} }
}
}
}
}
}
private Map<UUID, Set<Integer>> needsConfirmation = new HashMap<>(); private Map<UUID, Set<Integer>> needsConfirmation = new HashMap<>();
@ -343,72 +162,51 @@ public class ShopInteractListener implements Listener {
Player p = e.getPlayer(); Player p = e.getPlayer();
boolean inverted = Config.invertMouseButtons; boolean inverted = Config.invertMouseButtons;
if (Utils.getMajorVersion() >= 9) { if (Utils.getMajorVersion() >= 9 && e.getHand() == EquipmentSlot.OFF_HAND)
if (e.getHand() == EquipmentSlot.OFF_HAND) return; return;
if (e.getAction() != Action.RIGHT_CLICK_BLOCK && e.getAction() != Action.LEFT_CLICK_BLOCK)
return;
if (b.getType() != Material.CHEST && b.getType() != Material.TRAPPED_CHEST)
return;
if (ClickType.getPlayerClickType(p) != null) {
if (e.getAction() != Action.RIGHT_CLICK_BLOCK)
return;
Shop shop = shopUtils.getShop(b.getLocation());
if (shop == null && ClickType.getPlayerClickType(p).getClickType() != ClickType.EnumClickType.CREATE) {
p.sendMessage(LanguageUtils.getMessage(Message.CHEST_NO_SHOP));
plugin.debug("Chest is not a shop");
return;
} }
if (e.getAction() == Action.RIGHT_CLICK_BLOCK || e.getAction() == Action.LEFT_CLICK_BLOCK) {
if (b.getType().equals(Material.CHEST) || b.getType().equals(Material.TRAPPED_CHEST)) {
if (ClickType.getPlayerClickType(p) != null) {
if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
Shop shop = shopUtils.getShop(b.getLocation());
if (shop != null || ClickType.getPlayerClickType(p).getClickType() == ClickType.EnumClickType.CREATE) {
switch (ClickType.getPlayerClickType(p).getClickType()) { switch (ClickType.getPlayerClickType(p).getClickType()) {
case CREATE: case CREATE:
break; return;
case INFO: case INFO:
e.setCancelled(true);
info(p, shop); info(p, shop);
ClickType.removePlayerClickType(p);
break; break;
case REMOVE: case REMOVE:
e.setCancelled(true);
if (shop.getShopType() == ShopType.ADMIN) {
if (p.hasPermission(Permissions.REMOVE_ADMIN)) {
remove(p, shop); remove(p, shop);
} else {
p.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_REMOVE_ADMIN));
plugin.debug(p.getName() + " is not permitted to remove an admin shop");
}
} else {
if (shop.getVendor().getUniqueId().equals(p.getUniqueId()) || p.hasPermission(Permissions.REMOVE_OTHER)) {
remove(p, shop);
} else {
p.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_REMOVE_OTHERS));
plugin.debug(p.getName() + " is not permitted to remove another player's shop");
}
}
ClickType.removePlayerClickType(p);
break; break;
case OPEN: case OPEN:
e.setCancelled(true);
if (p.getUniqueId().equals(shop.getVendor().getUniqueId()) || p.hasPermission(Permissions.OPEN_OTHER)) {
open(p, shop, true); open(p, shop, true);
} else {
p.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_OPEN_OTHERS));
plugin.debug(p.getName() + " is not permitted to open another player's shop");
}
ClickType.removePlayerClickType(p);
break; break;
} }
} else {
p.sendMessage(LanguageUtils.getMessage(Message.CHEST_NO_SHOP)); e.setCancelled(true);
plugin.debug("Chest is not a shop"); ClickType.removePlayerClickType(p);
}
}
} else { } else {
Shop shop = shopUtils.getShop(b.getLocation()); Shop shop = shopUtils.getShop(b.getLocation());
if (shop != null) { if (shop == null)
return;
boolean confirmed = needsConfirmation.containsKey(p.getUniqueId()) && needsConfirmation.get(p.getUniqueId()).contains(shop.getID()); boolean confirmed = needsConfirmation.containsKey(p.getUniqueId()) && needsConfirmation.get(p.getUniqueId()).contains(shop.getID());
if (e.getAction() == Action.LEFT_CLICK_BLOCK && p.isSneaking() && Utils.hasAxeInHand(p)) { if (e.getAction() == Action.LEFT_CLICK_BLOCK && p.isSneaking() && Utils.hasAxeInHand(p)) {
@ -454,6 +252,7 @@ public class ShopInteractListener implements Listener {
if (shop.getBuyPrice() > 0) { if (shop.getBuyPrice() > 0) {
if (p.hasPermission(Permissions.BUY)) { if (p.hasPermission(Permissions.BUY)) {
// TODO: Outsource shop use external permission
boolean externalPluginsAllowed = true; boolean externalPluginsAllowed = true;
if (plugin.hasPlotSquared() && Config.enablePlotsquaredIntegration) { if (plugin.hasPlotSquared() && Config.enablePlotsquaredIntegration) {
@ -568,6 +367,7 @@ public class ShopInteractListener implements Listener {
if (shop.getSellPrice() > 0) { if (shop.getSellPrice() > 0) {
if (p.hasPermission(Permissions.SELL)) { if (p.hasPermission(Permissions.SELL)) {
// TODO: Outsource shop use external permission
boolean externalPluginsAllowed = true; boolean externalPluginsAllowed = true;
if (plugin.hasPlotSquared() && Config.enablePlotsquaredIntegration) { if (plugin.hasPlotSquared() && Config.enablePlotsquaredIntegration) {
@ -651,9 +451,6 @@ public class ShopInteractListener implements Listener {
} }
} }
} }
}
}
}
@EventHandler @EventHandler
@ -752,17 +549,16 @@ public class ShopInteractListener implements Listener {
ShopCreateEvent event = new ShopCreateEvent(executor, shop, creationPrice); ShopCreateEvent event = new ShopCreateEvent(executor, shop, creationPrice);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled() && !executor.hasPermission(Permissions.CREATE_PROTECTED)) {
if (event.isCancelled()) {
plugin.debug("Create event cancelled"); plugin.debug("Create event cancelled");
executor.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_CREATE_PROTECTED));
return; return;
} }
EconomyResponse r = plugin.getEconomy().withdrawPlayer(executor, location.getWorld().getName(), creationPrice); EconomyResponse r = plugin.getEconomy().withdrawPlayer(executor, location.getWorld().getName(), creationPrice);
if (!r.transactionSuccess()) { if (!r.transactionSuccess()) {
plugin.debug("Economy transaction failed: " + r.errorMessage); plugin.debug("Economy transaction failed: " + r.errorMessage);
executor.sendMessage(LanguageUtils.getMessage(Message.ERROR_OCCURRED, executor.sendMessage(LanguageUtils.getMessage(Message.ERROR_OCCURRED, new Replacement(Placeholder.ERROR, r.errorMessage)));
new Replacement(Placeholder.ERROR, r.errorMessage)));
return; return;
} }
@ -771,14 +567,8 @@ public class ShopInteractListener implements Listener {
plugin.debug("Shop created"); plugin.debug("Shop created");
shopUtils.addShop(shop, true); shopUtils.addShop(shop, true);
Replacement placeholder = new Replacement( Message message = shopType == ShopType.ADMIN ? Message.ADMIN_SHOP_CREATED : Message.SHOP_CREATED;
Placeholder.CREATION_PRICE, String.valueOf(creationPrice)); executor.sendMessage(LanguageUtils.getMessage(message, new Replacement(Placeholder.CREATION_PRICE, creationPrice)));
if (shopType == ShopType.ADMIN) {
executor.sendMessage(LanguageUtils.getMessage(Message.ADMIN_SHOP_CREATED, placeholder));
} else {
executor.sendMessage(LanguageUtils.getMessage(Message.SHOP_CREATED, placeholder));
}
} }
/** /**
@ -787,6 +577,17 @@ public class ShopInteractListener implements Listener {
* @param shop Shop to be removed * @param shop Shop to be removed
*/ */
private void remove(Player executor, Shop shop) { private void remove(Player executor, Shop shop) {
if (shop.getShopType() == ShopType.ADMIN && !executor.hasPermission(Permissions.REMOVE_ADMIN)) {
executor.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_REMOVE_ADMIN));
return;
}
if (shop.getShopType() == ShopType.NORMAL && !executor.getUniqueId().equals(shop.getVendor().getUniqueId())
&& !executor.hasPermission(Permissions.REMOVE_OTHER)) {
executor.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_REMOVE_OTHERS));
return;
}
plugin.debug(executor.getName() + " is removing " + shop.getVendor().getName() + "'s shop (#" + shop.getID() + ")"); plugin.debug(executor.getName() + " is removing " + shop.getVendor().getName() + "'s shop (#" + shop.getID() + ")");
ShopRemoveEvent event = new ShopRemoveEvent(executor, shop); ShopRemoveEvent event = new ShopRemoveEvent(executor, shop);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
@ -817,6 +618,11 @@ public class ShopInteractListener implements Listener {
* @param message Whether the player should receive the {@link Message#OPENED_SHOP} message * @param message Whether the player should receive the {@link Message#OPENED_SHOP} message
*/ */
private void open(Player executor, Shop shop, boolean message) { private void open(Player executor, Shop shop, boolean message) {
if (!executor.getUniqueId().equals(shop.getVendor().getUniqueId()) && !executor.hasPermission(Permissions.OPEN_OTHER)) {
executor.sendMessage(LanguageUtils.getMessage(Message.NO_PERMISSION_OPEN_OTHERS));
return;
}
plugin.debug(executor.getName() + " is opening " + shop.getVendor().getName() + "'s shop (#" + shop.getID() + ")"); plugin.debug(executor.getName() + " is opening " + shop.getVendor().getName() + "'s shop (#" + shop.getID() + ")");
ShopOpenEvent event = new ShopOpenEvent(executor, shop); ShopOpenEvent event = new ShopOpenEvent(executor, shop);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);

View File

@ -1,37 +1,28 @@
package de.epiceric.shopchest.listeners; package de.epiceric.shopchest.listeners;
import de.epiceric.shopchest.ShopChest; import java.util.Optional;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.nms.Hologram;
import de.epiceric.shopchest.shop.Shop;
import de.epiceric.shopchest.utils.ClickType;
import de.epiceric.shopchest.utils.ClickType.EnumClickType;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Chest; import org.bukkit.block.Chest;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.Event.Result;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.codemc.worldguardwrapper.WorldGuardWrapper; import org.codemc.worldguardwrapper.WorldGuardWrapper;
import org.codemc.worldguardwrapper.event.AbstractWrappedEvent;
import org.codemc.worldguardwrapper.event.WrappedDamageEntityEvent;
import org.codemc.worldguardwrapper.event.WrappedUseBlockEvent; import org.codemc.worldguardwrapper.event.WrappedUseBlockEvent;
import org.codemc.worldguardwrapper.event.WrappedUseEntityEvent;
import org.codemc.worldguardwrapper.flag.IWrappedFlag; import org.codemc.worldguardwrapper.flag.IWrappedFlag;
import org.codemc.worldguardwrapper.flag.WrappedState; import org.codemc.worldguardwrapper.flag.WrappedState;
import java.util.Optional; import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.shop.Shop;
import de.epiceric.shopchest.utils.ClickType;
import de.epiceric.shopchest.utils.ClickType.EnumClickType;
public class WorldGuardListener implements Listener { public class WorldGuardListener implements Listener {
@ -61,7 +52,7 @@ public class WorldGuardListener implements Listener {
if (shop != null) { if (shop != null) {
// Don't show 'permission denied' messages for any kind of // Don't show 'permission denied' messages for any kind of
// shop interaction even if entity/block interaction is not // shop interaction even if block interaction is not
// allowed in the region. // allowed in the region.
return true; return true;
} }
@ -69,44 +60,6 @@ public class WorldGuardListener implements Listener {
return false; return false;
} }
private void handleEntityInteraction(Player player, Entity entity, AbstractWrappedEvent event) {
if (entity.getType() == EntityType.ARMOR_STAND) {
if (!Hologram.isPartOfHologram((ArmorStand) entity))
return;
for (Shop shop : plugin.getShopUtils().getShops()) {
if (shop.getHologram() != null && shop.getHologram().contains((ArmorStand) entity)) {
if (isAllowed(player, shop.getLocation())) {
event.setResult(Result.ALLOW);
}
return;
}
}
}
}
@EventHandler(priority = EventPriority.LOW)
public void onUseEntity(WrappedUseEntityEvent event) {
if (Config.enableWorldGuardIntegration) {
Player player = event.getPlayer();
if (event.getOriginalEvent() instanceof PlayerInteractAtEntityEvent) {
handleEntityInteraction(player, event.getEntity(), event);
}
}
}
@EventHandler(priority = EventPriority.LOW)
public void onDamageEntity(WrappedDamageEntityEvent event) {
if (Config.enableWorldGuardIntegration) {
Player player = event.getPlayer();
if (event.getOriginalEvent() instanceof EntityDamageByEntityEvent) {
handleEntityInteraction(player, event.getEntity(), event);
}
}
}
@EventHandler(priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)
public void onUseBlock(WrappedUseBlockEvent event) { public void onUseBlock(WrappedUseBlockEvent event) {
if (Config.enableWorldGuardIntegration) { if (Config.enableWorldGuardIntegration) {

View File

@ -1,26 +1,5 @@
package de.epiceric.shopchest.utils; package de.epiceric.shopchest.utils;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Placeholder;
import de.epiceric.shopchest.language.LanguageUtils;
import de.epiceric.shopchest.language.Message;
import de.epiceric.shopchest.language.Replacement;
import de.epiceric.shopchest.nms.CustomBookMeta;
import de.epiceric.shopchest.nms.JsonBuilder;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.*;
import org.bukkit.util.Vector;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -29,12 +8,40 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Base64; import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.Vector;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Placeholder;
import de.epiceric.shopchest.language.LanguageUtils;
import de.epiceric.shopchest.language.Message;
import de.epiceric.shopchest.language.Replacement;
import de.epiceric.shopchest.nms.CustomBookMeta;
import de.epiceric.shopchest.nms.JsonBuilder;
import de.epiceric.shopchest.shop.Shop;
public class Utils { public class Utils {
/** /**
@ -285,6 +292,24 @@ public class Utils {
return true; return true;
} }
/**
* Get a set for the location(s) of the shop's chest(s)
* @param shop The shop
* @return A set of 1 or 2 locations
*/
public static Set<Location> getChestLocations(Shop shop) {
Set<Location> chestLocations = new HashSet<>();
InventoryHolder ih = shop.getInventoryHolder();
if (ih instanceof DoubleChest) {
DoubleChest dc = (DoubleChest) ih;
chestLocations.add(((Chest) dc.getLeftSide()).getLocation());
chestLocations.add(((Chest) dc.getRightSide()).getLocation());
} else {
chestLocations.add(shop.getLocation());
}
return chestLocations;
}
/** /**
* Send a clickable update notification to the given player. * Send a clickable update notification to the given player.
* @param plugin An instance of the {@link ShopChest} plugin * @param plugin An instance of the {@link ShopChest} plugin