diff --git a/pom.xml b/pom.xml
index 176e028..8ac2ab4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,6 +42,10 @@
vault-repo
http://nexus.hc.to/content/repositories/pub_releases/
+
+ sk89q-repo
+ http://maven.sk89q.com/artifactory/repo/
+
@@ -57,6 +61,11 @@
1.6
provided
+
+ com.sk89q
+ worldguard
+ 6.1.1-SNAPSHOT
+
diff --git a/src/main/java/de/epiceric/shopchest/ShopChest.java b/src/main/java/de/epiceric/shopchest/ShopChest.java
index 337ccfe..abfba73 100644
--- a/src/main/java/de/epiceric/shopchest/ShopChest.java
+++ b/src/main/java/de/epiceric/shopchest/ShopChest.java
@@ -1,5 +1,7 @@
package de.epiceric.shopchest;
+import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
+import com.sk89q.worldguard.protection.managers.storage.StorageException;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.config.Regex;
import de.epiceric.shopchest.event.ShopReloadEvent;
@@ -19,10 +21,13 @@ import de.epiceric.shopchest.utils.ShopUtils;
import de.epiceric.shopchest.utils.UpdateChecker;
import de.epiceric.shopchest.utils.UpdateChecker.UpdateCheckerResult;
import de.epiceric.shopchest.utils.Utils;
+import de.epiceric.shopchest.worldguard.ShopFlag;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
+import org.bukkit.World;
import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
@@ -45,6 +50,7 @@ public class ShopChest extends JavaPlugin {
private ShopUtils shopUtils;
private File debugLogFile;
private FileWriter fw;
+ private WorldGuardPlugin worldGuard;
/**
* @return An instance of ShopChest
@@ -138,6 +144,23 @@ public class ShopChest extends JavaPlugin {
getLogger().warning("Plugin may still work, but more errors are expected!");
}
+ Plugin worldGuardPlugin = Bukkit.getServer().getPluginManager().getPlugin("WorldGuard");
+ if (worldGuardPlugin instanceof WorldGuardPlugin) {
+ worldGuard = (WorldGuardPlugin) worldGuardPlugin;
+ ShopFlag.init();
+
+ try {
+ // Reload WorldGuard regions, so that custom flags are applied
+ for (World world : getServer().getWorlds()) {
+ worldGuard.getRegionManager(world).load();
+ }
+ } catch (StorageException e) {
+ getLogger().severe("Failed to reload WorldGuard region manager. WorldGuard support will probably not work!");
+ debug("Failed to load WorldGuard region manager");
+ debug(e);
+ }
+ }
+
debug("Loading utils and extras...");
LanguageUtils.load();
@@ -298,6 +321,9 @@ public class ShopChest extends JavaPlugin {
if (!Utils.getServerVersion().equals("v1_8_R1"))
getServer().getPluginManager().registerEvents(new BlockExplodeListener(this), this);
+ if (hasWorldGuard())
+ getServer().getPluginManager().registerEvents(new WorldGuardListener(this), this);
+
initializeShops();
}
@@ -369,6 +395,20 @@ public class ShopChest extends JavaPlugin {
debug("Initialized " + count + " Shops");
}
+ /**
+ * @return Whether the plugin 'WorldGuard' is enabled
+ */
+ public boolean hasWorldGuard() {
+ return worldGuard != null;
+ }
+
+ /**
+ * @return An instance of {@link WorldGuardPlugin} or {@code null} if WorldGuard is not enabled
+ */
+ public WorldGuardPlugin getWorldGuard() {
+ return worldGuard;
+ }
+
/**
* @return ShopChest's {@link ShopUtils} containing some important methods
*/
diff --git a/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java b/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java
index 94786c1..e5c1958 100644
--- a/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java
+++ b/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java
@@ -1,5 +1,9 @@
package de.epiceric.shopchest.listeners;
+import com.sk89q.worldguard.bukkit.RegionContainer;
+import com.sk89q.worldguard.bukkit.RegionQuery;
+import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
+import com.sk89q.worldguard.protection.flags.StateFlag;
import de.epiceric.shopchest.ShopChest;
import de.epiceric.shopchest.config.Config;
import de.epiceric.shopchest.config.Regex;
@@ -15,6 +19,7 @@ import de.epiceric.shopchest.sql.Database;
import de.epiceric.shopchest.utils.ClickType;
import de.epiceric.shopchest.utils.ShopUtils;
import de.epiceric.shopchest.utils.Utils;
+import de.epiceric.shopchest.worldguard.ShopFlag;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.economy.EconomyResponse;
import net.milkbowl.vault.permission.Permission;
@@ -49,6 +54,7 @@ public class ShopInteractListener implements Listener {
private Database database;
private ShopUtils shopUtils;
private Config config;
+ private WorldGuardPlugin worldGuard;
public ShopInteractListener(ShopChest plugin) {
this.plugin = plugin;
@@ -57,6 +63,7 @@ public class ShopInteractListener implements Listener {
this.database = plugin.getShopDatabase();
this.shopUtils = plugin.getShopUtils();
this.config = plugin.getShopChestConfig();
+ this.worldGuard = plugin.getWorldGuard();
}
@EventHandler(priority = EventPriority.HIGH)
@@ -70,10 +77,20 @@ public class ShopInteractListener implements Listener {
if (ClickType.getPlayerClickType(p) != null) {
if (ClickType.getPlayerClickType(p).getClickType() == ClickType.EnumClickType.CREATE) {
if (!shopUtils.isShop(b.getLocation())) {
- if (e.isCancelled() && !perm.has(p, "shopchest.create.protected")) {
+
+ boolean worldGuardAllowed = true;
+
+ if (plugin.hasWorldGuard()) {
+ RegionContainer container = worldGuard.getRegionContainer();
+ RegionQuery query = container.createQuery();
+ worldGuardAllowed = query.testState(b.getLocation(), p, ShopFlag.CREATE_SHOP);
+ }
+
+ if ((e.isCancelled() || !worldGuardAllowed) && !perm.has(p, "shopchest.create.protected")) {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_CREATE_PROTECTED));
ClickType.removePlayerClickType(p);
plugin.debug(p.getName() + " is not allowed to create a shop on the selected chest");
+ e.setCancelled(true);
return;
}
@@ -181,19 +198,41 @@ public class ShopInteractListener implements Listener {
plugin.debug(p.getName() + " wants to buy");
if (shop.getBuyPrice() > 0) {
if (perm.has(p, "shopchest.buy")) {
+ boolean worldGuardAllowed = true;
+
if (shop.getShopType() == ShopType.ADMIN) {
- buy(p, shop);
- } else {
- Chest c = (Chest) b.getState();
- if (Utils.getAmount(c.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) {
+ if (plugin.hasWorldGuard()) {
+ RegionContainer container = worldGuard.getRegionContainer();
+ RegionQuery query = container.createQuery();
+ worldGuardAllowed = query.testState(b.getLocation(), p, ShopFlag.USE_ADMIN_SHOP);
+ }
+
+ if (worldGuardAllowed) {
buy(p, shop);
} else {
- if (config.auto_calculate_item_amount && Utils.getAmount(c.getInventory(), shop.getProduct()) > 0) {
+ plugin.debug(p.getName() + " doesn't have worldguard permission");
+ }
+ } else {
+ if (plugin.hasWorldGuard()) {
+ RegionContainer container = worldGuard.getRegionContainer();
+ RegionQuery query = container.createQuery();
+ worldGuardAllowed = query.testState(b.getLocation(), p, ShopFlag.USE_SHOP);
+ }
+
+ if (worldGuardAllowed) {
+ Chest c = (Chest) b.getState();
+ if (Utils.getAmount(c.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) {
buy(p, shop);
} else {
- p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OUT_OF_STOCK));
- plugin.debug("Shop is out of stock");
+ if (config.auto_calculate_item_amount && Utils.getAmount(c.getInventory(), shop.getProduct()) > 0) {
+ buy(p, shop);
+ } else {
+ p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.OUT_OF_STOCK));
+ plugin.debug("Shop is out of stock");
+ }
}
+ } else {
+ plugin.debug(p.getName() + " doesn't have worldguard permission");
}
}
} else {
@@ -226,15 +265,29 @@ public class ShopInteractListener implements Listener {
plugin.debug(p.getName() + " wants to sell");
if (shop.getSellPrice() > 0) {
if (perm.has(p, "shopchest.sell")) {
- if (Utils.getAmount(p.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) {
- sell(p, shop);
- } else {
- if (config.auto_calculate_item_amount && Utils.getAmount(p.getInventory(), shop.getProduct()) > 0) {
+ boolean worldGuardAllowed = true;
+
+ if (plugin.hasWorldGuard()) {
+ RegionContainer container = worldGuard.getRegionContainer();
+ RegionQuery query = container.createQuery();
+
+ StateFlag flag = (shop.getShopType() == ShopType.ADMIN ? ShopFlag.USE_ADMIN_SHOP : ShopFlag.USE_SHOP);
+ worldGuardAllowed = query.testState(b.getLocation(), p, flag);
+ }
+
+ if (worldGuardAllowed) {
+ if (Utils.getAmount(p.getInventory(), shop.getProduct()) >= shop.getProduct().getAmount()) {
sell(p, shop);
} else {
- p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS));
- plugin.debug(p.getName() + " doesn't have enough items");
+ if (config.auto_calculate_item_amount && Utils.getAmount(p.getInventory(), shop.getProduct()) > 0) {
+ sell(p, shop);
+ } else {
+ p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NOT_ENOUGH_ITEMS));
+ plugin.debug(p.getName() + " doesn't have enough items");
+ }
}
+ } else {
+ plugin.debug(p.getName() + " doesn't have worldguard permission");
}
} else {
p.sendMessage(LanguageUtils.getMessage(LocalizedMessage.Message.NO_PERMISSION_SELL));
diff --git a/src/main/java/de/epiceric/shopchest/listeners/WorldGuardListener.java b/src/main/java/de/epiceric/shopchest/listeners/WorldGuardListener.java
new file mode 100644
index 0000000..c84fd16
--- /dev/null
+++ b/src/main/java/de/epiceric/shopchest/listeners/WorldGuardListener.java
@@ -0,0 +1,112 @@
+package de.epiceric.shopchest.listeners;
+
+import com.sk89q.worldguard.LocalPlayer;
+import com.sk89q.worldguard.bukkit.RegionContainer;
+import com.sk89q.worldguard.bukkit.RegionQuery;
+import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
+import com.sk89q.worldguard.bukkit.event.block.UseBlockEvent;
+import com.sk89q.worldguard.protection.flags.StateFlag;
+import de.epiceric.shopchest.ShopChest;
+import de.epiceric.shopchest.shop.Shop;
+import de.epiceric.shopchest.utils.ClickType;
+import de.epiceric.shopchest.worldguard.ShopFlag;
+import org.bukkit.Location;
+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.Action;
+import org.bukkit.event.inventory.InventoryOpenEvent;
+import org.bukkit.event.inventory.InventoryType;
+import org.bukkit.event.player.PlayerInteractEvent;
+
+public class WorldGuardListener implements Listener {
+
+ private ShopChest plugin;
+ private WorldGuardPlugin worldGuard;
+
+ public WorldGuardListener(ShopChest plugin) {
+ this.plugin = plugin;
+ this.worldGuard = plugin.getWorldGuard();
+ }
+
+
+ private boolean isAllowed(UseBlockEvent event, Location location, Action action) {
+ Player p = event.getCause().getFirstPlayer();
+
+ LocalPlayer localPlayer = worldGuard.wrapPlayer(p);
+ RegionContainer container = worldGuard.getRegionContainer();
+ RegionQuery query = container.createQuery();
+
+ if (action == Action.RIGHT_CLICK_BLOCK) {
+
+ if (ClickType.getPlayerClickType(p) != null) {
+
+ switch (ClickType.getPlayerClickType(p).getClickType()) {
+
+ case CREATE:
+ return query.testState(location, localPlayer, ShopFlag.CREATE_SHOP);
+ case REMOVE:
+ case INFO:
+ return true;
+ }
+ } else {
+ if (plugin.getShopUtils().isShop(location)) {
+ Shop shop = plugin.getShopUtils().getShop(location);
+
+ if (shop.getVendor().getUniqueId().equals(p.getUniqueId()) && shop.getShopType() != Shop.ShopType.ADMIN) {
+ return true;
+ }
+
+ if (!shop.getVendor().getUniqueId().equals(p.getUniqueId()) && p.isSneaking()) {
+ return p.hasPermission("shopchest.openOther");
+ }
+
+ StateFlag flag = (shop.getShopType() == Shop.ShopType.NORMAL ? ShopFlag.USE_SHOP : ShopFlag.USE_ADMIN_SHOP);
+
+ return query.testState(location, localPlayer, flag);
+ }
+ }
+ } else if (action == Action.LEFT_CLICK_BLOCK) {
+ if (plugin.getShopUtils().isShop(location)) {
+ Shop shop = plugin.getShopUtils().getShop(location);
+
+ StateFlag flag = (shop.getShopType() == Shop.ShopType.NORMAL ? ShopFlag.USE_SHOP : ShopFlag.USE_ADMIN_SHOP);
+
+ return query.testState(location, localPlayer, flag);
+ }
+ }
+
+ return false;
+ }
+
+ @EventHandler(priority = EventPriority.LOW)
+ public void onUseBlock(UseBlockEvent event) {
+ if (event.getCause().getFirstPlayer() == null) return;
+
+ if (event.getOriginalEvent() instanceof PlayerInteractEvent) {
+ PlayerInteractEvent orig = (PlayerInteractEvent) event.getOriginalEvent();
+
+ if (orig.hasBlock()) {
+ Material type = orig.getClickedBlock().getType();
+ if (type == Material.CHEST || type == Material.TRAPPED_CHEST) {
+ if (isAllowed(event, orig.getClickedBlock().getLocation(), orig.getAction())) {
+ event.setAllowed(true);
+ orig.setCancelled(false);
+ }
+ }
+ }
+ } else if (event.getOriginalEvent() instanceof InventoryOpenEvent) {
+ InventoryOpenEvent orig = (InventoryOpenEvent) event.getOriginalEvent();
+
+ if (orig.getInventory().getType() == InventoryType.CHEST) {
+ if (isAllowed(event, orig.getInventory().getLocation(), Action.RIGHT_CLICK_BLOCK)) {
+ event.setAllowed(true);
+ orig.setCancelled(false);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/de/epiceric/shopchest/worldguard/ShopFlag.java b/src/main/java/de/epiceric/shopchest/worldguard/ShopFlag.java
new file mode 100644
index 0000000..f306771
--- /dev/null
+++ b/src/main/java/de/epiceric/shopchest/worldguard/ShopFlag.java
@@ -0,0 +1,46 @@
+package de.epiceric.shopchest.worldguard;
+
+import com.sk89q.worldguard.protection.flags.DefaultFlag;
+import com.sk89q.worldguard.protection.flags.Flag;
+import com.sk89q.worldguard.protection.flags.StateFlag;
+import org.bukkit.Bukkit;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+public class ShopFlag {
+
+ private static Flag>[] customFlagList;
+
+ public static final StateFlag CREATE_SHOP;
+ public static final StateFlag USE_SHOP;
+ public static final StateFlag USE_ADMIN_SHOP;
+
+ static {
+ CREATE_SHOP = new StateFlag("create-shop", false);
+ USE_SHOP = new StateFlag("use-shop", false);
+ USE_ADMIN_SHOP = new StateFlag("use-admin-shop", false);
+
+ customFlagList = new Flag[] {CREATE_SHOP, USE_SHOP, USE_ADMIN_SHOP};
+ }
+
+ public static void init() {
+ // Add custom flags to WorldGuard's flag list
+ try {
+ Field flagListField = DefaultFlag.class.getField("flagsList");
+
+ Flag>[] flags = new Flag[DefaultFlag.flagsList.length + customFlagList.length];
+ System.arraycopy(DefaultFlag.flagsList, 0, flags, 0, DefaultFlag.flagsList.length);
+ System.arraycopy(customFlagList, 0, flags, DefaultFlag.flagsList.length, customFlagList.length);
+
+ Field modifiersField = Field.class.getDeclaredField("modifiers");
+ modifiersField.setAccessible(true);
+ modifiersField.setInt(flagListField, flagListField.getModifiers() & ~Modifier.FINAL);
+
+ flagListField.set(null, flags);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index c1fc722..b537f59 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -5,6 +5,7 @@ main: de.epiceric.shopchest.ShopChest
version: ${project.version}
author: EpicEric
website: ${project.url}
+softdepend: [WorldGuard]
depend: [Vault]
permissions:
@@ -55,7 +56,7 @@ permissions:
description: Allows you to check for updates.
default: op
shopchest.limit.*:
- default: op
+ default: true
shopchest.config:
description: Allows you to change configuration values per command.
default: op