diff --git a/EpicHoppers-API/src/main/java/com/songoda/epichoppers/api/hopper/levels/modules/Module.java b/EpicHoppers-API/src/main/java/com/songoda/epichoppers/api/hopper/levels/modules/Module.java index c20e38c..a6e10ca 100644 --- a/EpicHoppers-API/src/main/java/com/songoda/epichoppers/api/hopper/levels/modules/Module.java +++ b/EpicHoppers-API/src/main/java/com/songoda/epichoppers/api/hopper/levels/modules/Module.java @@ -2,6 +2,7 @@ package com.songoda.epichoppers.api.hopper.levels.modules; import com.songoda.epichoppers.api.hopper.Hopper; import org.bukkit.Material; +import org.bukkit.inventory.Inventory; import java.util.List; @@ -9,7 +10,7 @@ public interface Module { String getName(); - void run(Hopper hopper, org.bukkit.block.Hopper hopperBlock); + void run(Hopper hopper, Inventory hopperInventory); List getBlockedItems(Hopper hopper); diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/EpicHoppersPlugin.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/EpicHoppersPlugin.java index 3853aaa..2558019 100644 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/EpicHoppersPlugin.java +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/EpicHoppersPlugin.java @@ -1,6 +1,5 @@ package com.songoda.epichoppers; -import com.google.common.base.Preconditions; import com.songoda.epichoppers.api.EpicHoppers; import com.songoda.epichoppers.api.EpicHoppersAPI; import com.songoda.epichoppers.api.hopper.HopperManager; @@ -12,7 +11,7 @@ import com.songoda.epichoppers.boost.BoostData; import com.songoda.epichoppers.boost.BoostManager; import com.songoda.epichoppers.command.CommandManager; import com.songoda.epichoppers.enchantment.Enchantment; -import com.songoda.epichoppers.handlers.HopHandler; +import com.songoda.epichoppers.tasks.HopTask; import com.songoda.epichoppers.handlers.TeleportHandler; import com.songoda.epichoppers.hook.HookManager; import com.songoda.epichoppers.hopper.EFilter; @@ -39,7 +38,6 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.PluginManager; @@ -57,7 +55,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; -import java.util.function.Supplier; public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers { @@ -67,7 +64,6 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers { public References references = null; public Enchantment enchantmentHandler; private SettingsManager settingsManager; - private ConfigWrapper hooksFile = new ConfigWrapper(this, "", "hooks.yml"); private ConfigWrapper levelsFile = new ConfigWrapper(this, "", "levels.yml"); private Locale locale; @@ -142,7 +138,7 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers { // Load from file loadFromFile(); - new HopHandler(this); + new HopTask(this); this.teleportHandler = new TeleportHandler(this); PluginManager pluginManager = Bukkit.getPluginManager(); diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/handlers/HopHandler.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/handlers/HopHandler.java deleted file mode 100644 index 6c0ecd9..0000000 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/handlers/HopHandler.java +++ /dev/null @@ -1,373 +0,0 @@ -package com.songoda.epichoppers.handlers; - -import com.songoda.epichoppers.EpicHoppersPlugin; -import com.songoda.epichoppers.api.hopper.levels.modules.Module; -import com.songoda.epichoppers.boost.BoostData; -import com.songoda.epichoppers.utils.Debugger; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.OfflinePlayer; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.Hopper; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.minecart.HopperMinecart; -import org.bukkit.entity.minecart.StorageMinecart; -import org.bukkit.inventory.*; - -import java.util.*; - -/** - * Created by songoda on 3/14/2017. - */ -public class HopHandler { - - private EpicHoppersPlugin instance; - - public HopHandler(EpicHoppersPlugin instance) { - try { - this.instance = instance; - Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> - Bukkit.getScheduler().scheduleSyncRepeatingTask(instance, this::hopperRunner, 0, - instance.getConfig().getLong("Main.Amount of Ticks Between Hops")), 40L); - } catch (Exception e) { - Debugger.runReport(e); - } - } - - private void hopperRunner() { - try { - main: - for (com.songoda.epichoppers.api.hopper.Hopper hopper : new HashMap<>(instance.getHopperManager().getHoppers()).values()) { - Location location = hopper.getLocation(); - - if (!location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) - continue; - - Block block = location.getBlock(); - - if (block == null || block.getType() != Material.HOPPER) { - instance.getHopperManager().removeHopper(location); - continue; - } - - if (block.isBlockPowered() || block.isBlockIndirectlyPowered()) continue; - - Hopper hopperState = (Hopper) block.getState(); - - List blockedMaterials = new ArrayList<>(); - - if (hopperState == null || hopperState.getInventory() == null) continue; - - for (Module module : hopper.getLevel().getRegisteredModules()) { - // Run Module - module.run(hopper, hopperState); - - // Add banned materials to list. - List materials = module.getBlockedItems(hopper); - if (materials == null || materials.isEmpty()) continue; - blockedMaterials.addAll(materials); - } - - ItemStack[] hopperContents = hopperState.getInventory().getContents(); - - Inventory override = null; - List linked = hopper.getLinkedBlocks(); - - if (hopper.getLinkedBlocks() == null || hopper.getLinkedBlocks().isEmpty()) { - HopperDirection hopperDirection = HopperDirection.getDirection(hopperState.getRawData()); - Location check = hopperDirection.getLocation(location); - - linked.add(check); - - Collection nearbyEntities = hopper.getLocation().getWorld().getNearbyEntities(check, .5, .5, .5); - - for (Entity entity : nearbyEntities) { - if (entity.getType() == EntityType.MINECART_HOPPER) - override = ((HopperMinecart) entity).getInventory(); - else if (entity.getType() == EntityType.MINECART_CHEST) - override = ((StorageMinecart) entity).getInventory(); - } - - if (linked.isEmpty()) continue; - } - - for (Location destinationLocation : linked) { - Block destinationBlock = destinationLocation.getBlock(); - Inventory destinationInventory = override; - if (override == null) { - if (destinationLocation == null) continue; - - if (!destinationLocation.getWorld().isChunkLoaded(destinationLocation.getBlockX() >> 4, - destinationLocation.getBlockZ() >> 4)) - continue; - - destinationBlock = destinationLocation.getBlock(); - BlockState state = destinationBlock.getState(); - if (!(state instanceof InventoryHolder)) { - hopper.clearLinkedBlocks(); - continue; - } - destinationInventory = ((InventoryHolder) state).getInventory(); - } - - BoostData boostData = instance.getBoostManager().getBoost(hopper.getPlacedBy()); - - int amount = hopper.getLevel().getAmount() * (boostData == null ? 1 : boostData.getMultiplier()); - - List whiteList = hopper.getFilter().getWhiteList(); - List blackList = hopper.getFilter().getBlackList(); - - for (int i = 0; i < 5; i++) { - if (hopperContents[i] == null) continue; - - ItemStack item = hopperContents[i].clone(); - item.setAmount(1); - - if (hopper.getLocation().getBlock().isBlockPowered() - || hopperContents[i] != null && blockedMaterials.contains(hopperContents[i].getType())) { - continue; - } - - int finalIncrement = i; - - if (!whiteList.isEmpty() - && whiteList.stream().noneMatch(itemStack -> itemStack.isSimilar(hopperContents[finalIncrement]))) { - doBlacklist(hopperState, hopper, hopperContents[i].clone(), amount, i); - continue main; - } - - if (blackList.stream().noneMatch(itemStack -> itemStack.isSimilar(hopperContents[finalIncrement]))) { - if (addItem(hopperState, hopper, destinationInventory, destinationBlock, hopperContents[i], amount, i)) { - continue main; - } - } - - if (blackList.stream().anyMatch(itemStack -> itemStack.isSimilar(hopperContents[finalIncrement]))) { - doBlacklist(hopperState, hopper, hopperContents[i].clone(), amount, i); - continue main; - } - } - } - } - } catch (Exception e) { - Debugger.runReport(e); - } - } - - - private void doBlacklist(Hopper hopperState, com.songoda.epichoppers.api.hopper.Hopper hopper, ItemStack item, int amt, int place) { - try { - Location dest = hopper.getFilter().getEndPoint(); - if (dest == null) return; - if (!dest.getWorld().isChunkLoaded(dest.getBlockX() >> 4, dest.getBlockZ() >> 4)) - return; - - Block destinationBlock = dest.getBlock(); - BlockState state = destinationBlock.getState(); - if (!(state instanceof InventoryHolder)) { - hopper.getFilter().setEndPoint(null); - return; - } - Inventory destinationInventory = ((InventoryHolder) state).getInventory(); - - addItem(hopperState, hopper, destinationInventory, destinationBlock, item, amt, place); - } catch (Exception e) { - Debugger.runReport(e); - } - } - - private boolean addItem(Hopper hopperState, com.songoda.epichoppers.api.hopper.Hopper hopper, Inventory destinationInventory, Block destinationBlock, ItemStack is, int amt, int place) { - try { - ItemStack it = null; - if (is != null) { - it = is.clone(); - it.setAmount(1); - } - - List ovoid = new ArrayList<>(hopper.getFilter().getVoidList()); - - if (is.getType() == Material.AIR) { - return true; - } - ItemStack item = is; - ItemStack newItem = is.clone(); - - if ((item.getAmount() - amt) <= 0) { - amt = item.getAmount(); - } - if ((item.getAmount() - amt) >= 1) { - newItem.setAmount(newItem.getAmount() - amt); - is = newItem.clone(); - } else { - is = null; - } - - newItem.setAmount(amt); - - if (destinationBlock.getType().equals(Material.ENDER_CHEST)) { - OfflinePlayer op = Bukkit.getOfflinePlayer(hopper.getPlacedBy()); - - if (op.isOnline() && canMove(op.getPlayer().getEnderChest(), newItem)) { - ItemStack finalIt = it; - if (ovoid.stream().noneMatch(itemStack -> itemStack.isSimilar(finalIt))) { - op.getPlayer().getEnderChest().addItem(newItem); - } - hopperState.getInventory().setItem(place, is); - } - return true; - } - if (destinationBlock.getType().name().contains("SHULKER_BOX")) { - if (item.getType().name().contains("SHULKER_BOX")) return false; - } else if (destinationBlock.getType() == Material.BREWING_STAND) { - BrewerInventory brewerInventory = (BrewerInventory) destinationInventory; - - int maxSize = newItem.getMaxStackSize(); - - String typeStr = item.getType().name().toUpperCase(); - boolean isBottle = typeStr.contains("POTION") || typeStr.contains("BOTTLE") || item.getType() == Material.DRAGON_BREATH; - boolean isLeft = item.getType() == Material.BLAZE_POWDER; - - Map output = new HashMap<>(); - if (isBottle) { - output.put(0, brewerInventory.getItem(0)); - output.put(1, brewerInventory.getItem(1)); - output.put(2, brewerInventory.getItem(2)); - } else if (isLeft) { - output.put(4, brewerInventory.getItem(4)); - } else { - output.put(3, brewerInventory.getItem(3)); - } - - ItemStack finalIt = it; - for (Map.Entry entry : output.entrySet()) { - if (ovoid.stream().noneMatch(itemStack -> itemStack.isSimilar(finalIt))) { - ItemStack currentOutput = entry.getValue(); - int currentOutputAmount = currentOutput == null ? 0 : currentOutput.getAmount(); - if (currentOutput != null && (!currentOutput.isSimilar(newItem)) - || currentOutputAmount + newItem.getAmount() > maxSize) continue; - - if (currentOutput != null) { - currentOutput.setAmount(currentOutputAmount + newItem.getAmount()); - } else { - currentOutput = newItem.clone(); - } - - brewerInventory.setItem(entry.getKey(), currentOutput); - } - hopperState.getInventory().setItem(place, is); - return true; - } - } else if (destinationBlock.getType() == Material.FURNACE) { - FurnaceInventory furnaceInventory = (FurnaceInventory) destinationInventory; - - boolean isFuel = item.getType().isFuel() && !item.getType().name().contains("LOG"); - ItemStack output = isFuel ? furnaceInventory.getFuel() : furnaceInventory.getSmelting(); - if (output != null && !output.isSimilar(newItem)) return false; - int maxSize = newItem.getMaxStackSize(); - int currentOutputAmount = output == null ? 0 : output.getAmount(); - - if (currentOutputAmount + newItem.getAmount() <= maxSize) { - ItemStack finalIt = it; - if (ovoid.stream().noneMatch(itemStack -> itemStack.isSimilar(finalIt))) { - if (output != null) { - output.setAmount(currentOutputAmount + newItem.getAmount()); - } else { - output = newItem.clone(); - } - if (isFuel) { - furnaceInventory.setFuel(output); - } else { - furnaceInventory.setSmelting(output); - } - hopperState.getInventory().setItem(place, is); - } - } - return true; - } - if (!canMove(destinationInventory, newItem)) return false; - ItemStack finalIt = it; - if (ovoid.stream().noneMatch(itemStack -> itemStack.isSimilar(finalIt))) { - destinationInventory.addItem(newItem); - } - hopperState.getInventory().setItem(place, is); - return true; - } catch (Exception e) { - Debugger.runReport(e); - } - return false; - } - - private boolean canMove(Inventory inventory, ItemStack item) { - try { - if (inventory.firstEmpty() != -1) return true; - for (ItemStack stack : inventory.getContents()) { - if (stack.isSimilar(item) && (stack.getAmount() + item.getAmount()) - 1 < stack.getMaxStackSize()) { - return true; - } - } - } catch (Exception e) { - Debugger.runReport(e); - } - return false; - } - - public enum HopperDirection { - - DOWN(0, 8, 0, -1, 0), - NORTH(2, 10, 0, 0, -1), - SOUTH(3, 11, 0, 0, 1), - WEST(4, 12, -1, 0, 0), - EAST(5, 13, 1, 0, 0); - - private int unpowered; - private int powered; - - private int x; - private int y; - private int z; - - HopperDirection(int unpowered, int powered, int x, int y, int z) { - this.unpowered = unpowered; - this.powered = powered; - - this.x = x; - this.y = y; - this.z = z; - } - - public static HopperDirection getDirection(int value) { - for (HopperDirection hopperDirection : HopperDirection.values()) { - if (hopperDirection.getPowered() == value - || hopperDirection.getUnpowered() == value) return hopperDirection; - } - return null; - } - - public Location getLocation(Location location) { - return location.add(getX(), getY(), getZ()); - } - - public int getX() { - return x; - } - - public int getY() { - return y; - } - - public int getZ() { - return z; - } - - public int getUnpowered() { - return unpowered; - } - - public int getPowered() { - return powered; - } - } -} \ No newline at end of file diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/handlers/TeleportHandler.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/handlers/TeleportHandler.java index 1a5d9a5..ab75437 100644 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/handlers/TeleportHandler.java +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/handlers/TeleportHandler.java @@ -73,7 +73,7 @@ public class TeleportHandler { boolean empty = lastHopper.getLinkedBlocks().isEmpty(); if (empty && i == 0) { if (teleportFrom.containsKey(hopper.getLocation())) - doTeleport(player, teleportFrom.get(hopper.getLocation())); + doTeleport(player, teleportFrom.get(hopper.getLocation()).clone()); return; } diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleAutoCrafting.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleAutoCrafting.java index 725224b..28ad6e2 100644 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleAutoCrafting.java +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleAutoCrafting.java @@ -15,7 +15,7 @@ import java.util.Map; public class ModuleAutoCrafting implements Module { - private final Map cachedRecipes = new HashMap<>(); + private final Map cachedRecipes = new HashMap<>(); private final Map lastMaterial = new HashMap<>(); public static List compressItemStack(List target) { @@ -38,60 +38,64 @@ public class ModuleAutoCrafting implements Module { return "AutoCrafting"; } - public void run(Hopper hopper, org.bukkit.block.Hopper hopperBlock) { - if (hopper.getAutoCrafting() == null || hopperBlock == null || hopperBlock.getInventory() == null) return; - if (hopper.getAutoCrafting() != null && canMove(hopperBlock.getInventory(), new ItemStack(hopper.getAutoCrafting()))) { + public void run(Hopper hopper, Inventory hopperInventory) { + if (hopper.getAutoCrafting() == null || hopperInventory == null) return; + + if (hopper.getAutoCrafting() != null && canMove(hopperInventory, new ItemStack(hopper.getAutoCrafting()))) { - Recipe recipe = cachedRecipes.get(hopper.getAutoCrafting()); - if (!(recipe instanceof ShapedRecipe) && !(recipe instanceof ShapelessRecipe)) return; - List ingredientMap = null; - if (recipe instanceof ShapelessRecipe) ingredientMap = ((ShapelessRecipe) recipe).getIngredientList(); - if (recipe instanceof ShapedRecipe) - ingredientMap = new ArrayList<>(((ShapedRecipe) recipe).getIngredientMap().values()); - if (hopperBlock.getInventory().getSize() == 0) return; + if (cachedRecipes.get(hopper.getAutoCrafting()) == null) return; - Map items = new HashMap<>(); - for (ItemStack item : ingredientMap) { - if (item == null) continue; - if (!items.containsKey(item.getType())) { - items.put(item.getType(), item.getAmount()); - } else { - items.put(item.getType(), items.get(item.getType()) + 1); - } - } + top: + for (Recipe recipe : cachedRecipes.get(hopper.getAutoCrafting()).getRecipes()) { + if (!(recipe instanceof ShapedRecipe) && !(recipe instanceof ShapelessRecipe)) continue; + List ingredientMap = null; + if (recipe instanceof ShapelessRecipe) ingredientMap = ((ShapelessRecipe) recipe).getIngredientList(); + if (recipe instanceof ShapedRecipe) + ingredientMap = new ArrayList<>(((ShapedRecipe) recipe).getIngredientMap().values()); + if (hopperInventory.getSize() == 0) return; - for (Material material : items.keySet()) { - int amt = 0; - ItemStack item = new ItemStack(material, items.get(material)); - for (ItemStack i : hopperBlock.getInventory().getContents()) { - if (i == null) continue; - if (i.getType() != material) continue; - amt += i.getAmount(); - } - - if (amt < item.getAmount()) { - return; - } - } - main2: - for (Material material : items.keySet()) { - int amtRemoved = 0; - ItemStack toRemove = new ItemStack(material, items.get(material)); - for (ItemStack i : hopperBlock.getInventory().getContents()) { - if (i == null || i.getType() != material) continue; - if (toRemove.getAmount() - amtRemoved <= i.getAmount()) { - toRemove.setAmount(toRemove.getAmount() - amtRemoved); - hopperBlock.getInventory().removeItem(toRemove); - continue main2; + Map items = new HashMap<>(); + for (ItemStack item : ingredientMap) { + if (item == null) continue; + if (!items.containsKey(item.getType())) { + items.put(item.getType(), item.getAmount()); } else { - amtRemoved += i.getAmount(); - hopperBlock.getInventory().removeItem(i); + items.put(item.getType(), items.get(item.getType()) + 1); } } - } - hopperBlock.getInventory().addItem(recipe.getResult()); - } + for (Material material : items.keySet()) { + int amt = 0; + ItemStack item = new ItemStack(material, items.get(material)); + for (ItemStack i : hopperInventory.getContents()) { + if (i == null) continue; + if (i.getType() != material) continue; + amt += i.getAmount(); + } + + if (amt < item.getAmount()) { + continue top; + } + } + main2: + for (Material material : items.keySet()) { + int amtRemoved = 0; + ItemStack toRemove = new ItemStack(material, items.get(material)); + for (ItemStack i : hopperInventory.getContents()) { + if (i == null || i.getType() != material) continue; + if (toRemove.getAmount() - amtRemoved <= i.getAmount()) { + toRemove.setAmount(toRemove.getAmount() - amtRemoved); + hopperInventory.removeItem(toRemove); + continue main2; + } else { + amtRemoved += i.getAmount(); + hopperInventory.removeItem(i); + } + } + } + hopperInventory.addItem(recipe.getResult()); + } + } } public List getBlockedItems(Hopper hopper) { @@ -108,20 +112,24 @@ public class ModuleAutoCrafting implements Module { } if (!cachedRecipes.containsKey(material)) { + Recipes recipes = new Recipes(); for (Recipe recipe : Bukkit.getServer().getRecipesFor(new ItemStack(material))) { - cachedRecipes.put(material, recipe); + recipes.addRecipe(recipe); } + cachedRecipes.put(material, recipes); } else { - Recipe recipe = cachedRecipes.get(material); - if (recipe instanceof ShapedRecipe) { - for (ItemStack itemStack : ((ShapedRecipe) recipe).getIngredientMap().values()) { - if (itemStack == null) continue; - materials.add(itemStack.getType()); - } - } else if (recipe instanceof ShapelessRecipe) { - for (ItemStack itemStack : ((ShapelessRecipe) recipe).getIngredientList()) { - if (itemStack == null) continue; - materials.add(itemStack.getType()); + Recipes recipes = cachedRecipes.get(material); + for (Recipe recipe : recipes.getRecipes()) { + if (recipe instanceof ShapedRecipe) { + for (ItemStack itemStack : ((ShapedRecipe) recipe).getIngredientMap().values()) { + if (itemStack == null) continue; + materials.add(itemStack.getType()); + } + } else if (recipe instanceof ShapelessRecipe) { + for (ItemStack itemStack : ((ShapelessRecipe) recipe).getIngredientList()) { + if (itemStack == null) continue; + materials.add(itemStack.getType()); + } } } } @@ -148,4 +156,21 @@ public class ModuleAutoCrafting implements Module { } return false; } + + class Recipes { + + private List recipes = new ArrayList<>(); + + public List getRecipes() { + return new ArrayList<>(recipes); + } + + public void addRecipe(Recipe recipe) { + this.recipes.add(recipe); + } + + public void clearRecipes() { + recipes.clear(); + } + } } diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleAutoSell.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleAutoSell.java index 8b15744..faa65e9 100644 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleAutoSell.java +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleAutoSell.java @@ -7,6 +7,7 @@ import com.songoda.epichoppers.hopper.EHopper; import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.RegisteredServiceProvider; @@ -29,8 +30,8 @@ public class ModuleAutoSell implements Module { } @Override - public void run(Hopper hopper, org.bukkit.block.Hopper hopperBlock) { - if (hopperBlock == null || hopperBlock.getInventory() == null) return; + public void run(Hopper hopper, Inventory hopperInventory) { + if (hopperInventory == null) return; if (((EHopper) hopper).getAutoSellTimer() == -9999) return; @@ -50,11 +51,11 @@ public class ModuleAutoSell implements Module { Material material = Material.valueOf(split[0]); double price = Double.valueOf(split[1]); - for (ItemStack itemStack : hopperBlock.getInventory().getContents()) { + for (ItemStack itemStack : hopperInventory.getContents()) { if (itemStack == null || itemStack.getType() != material) continue; econ.depositPlayer(Bukkit.getOfflinePlayer(hopper.getPlacedBy()), price * itemStack.getAmount()); - hopperBlock.getInventory().removeItem(itemStack); + hopperInventory.removeItem(itemStack); } } catch (Exception ignored) { } diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleBlockBreak.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleBlockBreak.java index 0e72dd2..b98c39d 100644 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleBlockBreak.java +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleBlockBreak.java @@ -9,6 +9,7 @@ import org.bukkit.Material; import org.bukkit.Particle; import org.bukkit.Sound; import org.bukkit.block.Block; +import org.bukkit.inventory.Inventory; import java.util.HashMap; import java.util.List; @@ -29,7 +30,7 @@ public class ModuleBlockBreak implements Module { } @Override - public void run(Hopper hopper, org.bukkit.block.Hopper hopperBlock) { + public void run(Hopper hopper, Inventory hopperInventory) { Block block = hopper.getLocation().getBlock(); if (!((EHopper)hopper).isAutoBreaking()) return; diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleSuction.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleSuction.java index 8a97a57..cd8a0d1 100644 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleSuction.java +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/hopper/levels/modules/ModuleSuction.java @@ -54,7 +54,7 @@ public class ModuleSuction implements Module { } @Override - public void run(Hopper hopper, org.bukkit.block.Hopper hopperBlock) { + public void run(Hopper hopper, Inventory hopperInventory) { double radius = amount + .5; Collection nearbyEntite = hopper.getLocation().getWorld().getNearbyEntities(hopper.getLocation().add(0.5, 0.5, 0.5), radius, radius, radius); @@ -82,7 +82,7 @@ public class ModuleSuction implements Module { if (item == null) continue; - if (!canMove(hopperBlock.getInventory(), item)) { + if (!canMove(hopperInventory, item)) { continue; } ((Item) entity).setPickupDelay(10); @@ -92,7 +92,7 @@ public class ModuleSuction implements Module { float zz = (float) (0 + (Math.random() * .1)); entity.getLocation().getWorld().spawnParticle(Particle.FLAME, entity.getLocation(), 5, xx, yy, zz, 0); - for (ItemStack itemStack : hopperBlock.getInventory().addItem(hopItem).values()) { + for (ItemStack itemStack : hopperInventory.addItem(hopItem).values()) { entity.getWorld().dropItemNaturally(entity.getLocation(), itemStack); } entity.remove(); diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/listeners/InteractListeners.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/listeners/InteractListeners.java index 4f3bc72..f334cd2 100644 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/listeners/InteractListeners.java +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/listeners/InteractListeners.java @@ -14,6 +14,7 @@ import org.bukkit.Material; import org.bukkit.block.BlockFace; 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.player.PlayerInteractEvent; @@ -52,7 +53,7 @@ public class InteractListeners implements Listener { } } - @EventHandler + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBlockInteract(PlayerInteractEvent e) { try { Player player = e.getPlayer(); diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/storage/types/StorageYaml.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/storage/types/StorageYaml.java index 38ad794..0aeae28 100644 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/storage/types/StorageYaml.java +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/storage/types/StorageYaml.java @@ -4,12 +4,10 @@ import com.songoda.epichoppers.EpicHoppersPlugin; import com.songoda.epichoppers.storage.Storage; import com.songoda.epichoppers.storage.StorageItem; import com.songoda.epichoppers.storage.StorageRow; -import org.apache.commons.io.FileUtils; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.MemorySection; -import java.io.File; -import java.io.IOException; +import java.io.*; import java.util.*; public class StorageYaml extends Storage { @@ -110,7 +108,7 @@ public class StorageYaml extends Storage { File data = new File(instance.getDataFolder(), "data.yml"); File dataClone = new File(instance.getDataFolder(), "data-backup-" + System.currentTimeMillis() + ".yml"); try { - FileUtils.copyFile(data, dataClone); + copyFile(data, dataClone); } catch (IOException e) { e.printStackTrace(); } @@ -129,4 +127,21 @@ public class StorageYaml extends Storage { public void closeConnection() { dataFile.saveConfig(); } + + private static void copyFile(File source, File dest) throws IOException { + InputStream is = null; + OutputStream os = null; + try { + is = new FileInputStream(source); + os = new FileOutputStream(dest); + byte[] buffer = new byte[1024]; + int length; + while ((length = is.read(buffer)) > 0) { + os.write(buffer, 0, length); + } + } finally { + is.close(); + os.close(); + } + } } diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/tasks/HopTask.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/tasks/HopTask.java new file mode 100644 index 0000000..d7a5d3f --- /dev/null +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/tasks/HopTask.java @@ -0,0 +1,372 @@ +package com.songoda.epichoppers.tasks; + +import com.songoda.epichoppers.EpicHoppersPlugin; +import com.songoda.epichoppers.api.hopper.levels.modules.Module; +import com.songoda.epichoppers.boost.BoostData; +import com.songoda.epichoppers.utils.SettingsManager; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.Hopper; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.minecart.HopperMinecart; +import org.bukkit.entity.minecart.StorageMinecart; +import org.bukkit.inventory.*; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.*; + +/** + * Created by songoda on 3/14/2017. + */ +public class HopTask extends BukkitRunnable { + + private static EpicHoppersPlugin plugin; + + public HopTask(EpicHoppersPlugin plug) { + plugin = plug; + runTaskTimer(plugin, 0, SettingsManager.Setting.HOP_TICKS.getInt()); + } + + @Override + public void run() { + main: + for (com.songoda.epichoppers.api.hopper.Hopper hopper : new HashMap<>(plugin.getHopperManager().getHoppers()).values()) { + Location location = hopper.getLocation(); + + if (location.getWorld() == null || !location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) + continue; + + Block block = location.getBlock(); + + if (block.getType() != Material.HOPPER) { + plugin.getHopperManager().removeHopper(location); + continue; + } + + if (block.isBlockPowered() || block.isBlockIndirectlyPowered()) continue; + + Hopper hopperState = (Hopper) block.getState(); + Inventory hopperInventory = hopperState.getInventory(); + + List blockedMaterials = new ArrayList<>(); + + for (Module module : hopper.getLevel().getRegisteredModules()) { + // Run Module + module.run(hopper, hopperInventory); + + // Add banned materials to list. + List materials = module.getBlockedItems(hopper); + if (materials == null || materials.isEmpty()) continue; + blockedMaterials.addAll(materials); + } + + // Fetch all hopper contents. + ItemStack[] hopperContents = hopperInventory.getContents(); + + Inventory override = null; + List linked = hopper.getLinkedBlocks(); + + if (hopper.getLinkedBlocks() == null || hopper.getLinkedBlocks().isEmpty()) { + HopperDirection hopperDirection = HopperDirection.getDirection(hopperState.getRawData()); + Location check = hopperDirection.getLocation(location); + + linked.add(check); + + Collection nearbyEntities = hopper.getLocation().getWorld().getNearbyEntities(check, .5, .5, .5); + + for (Entity entity : nearbyEntities) { + if (entity.getType() == EntityType.MINECART_HOPPER) + override = ((HopperMinecart) entity).getInventory(); + else if (entity.getType() == EntityType.MINECART_CHEST) + override = ((StorageMinecart) entity).getInventory(); + } + + if (linked.isEmpty()) continue; + } + + for (Location destinationLocation : linked) { + Block destinationBlock = destinationLocation.getBlock(); + Inventory destinationInventory = override; + if (override == null) { + + if (!destinationLocation.getWorld().isChunkLoaded(destinationLocation.getBlockX() >> 4, + destinationLocation.getBlockZ() >> 4)) + continue; + + destinationBlock = destinationLocation.getBlock(); + BlockState state = destinationBlock.getState(); + if (!(state instanceof InventoryHolder)) { + hopper.clearLinkedBlocks(); + continue; + } + destinationInventory = ((InventoryHolder) state).getInventory(); + } + + BoostData boostData = plugin.getBoostManager().getBoost(hopper.getPlacedBy()); + + int amount = hopper.getLevel().getAmount() * (boostData == null ? 1 : boostData.getMultiplier()); + + List whiteList = hopper.getFilter().getWhiteList(); + List blackList = hopper.getFilter().getBlackList(); + + for (int i = 0; i < 5; i++) { + if (hopperContents[i] == null) continue; + + ItemStack item = hopperContents[i].clone(); + item.setAmount(1); + + if (hopper.getLocation().getBlock().isBlockPowered() + || hopperContents[i] != null && blockedMaterials.contains(hopperContents[i].getType())) { + continue; + } + + int finalIncrement = i; + + if (!whiteList.isEmpty() + && whiteList.stream().noneMatch(itemStack -> itemStack.isSimilar(hopperContents[finalIncrement]))) { + doBlacklist(hopperInventory, hopper, hopperContents[i].clone(), amount, i); + continue main; + } + + if (blackList.stream().noneMatch(itemStack -> itemStack.isSimilar(hopperContents[finalIncrement]))) { + if (addItem(hopperInventory, hopper, destinationInventory, destinationBlock, hopperContents[i], amount, i)) { + continue main; + } + } else { + if (hopper.getFilter().getEndPoint() == null) continue; + + doBlacklist(hopperInventory, hopper, hopperContents[i].clone(), amount, i); + continue main; + } + } + } + } + } + + + private void doBlacklist(Inventory hopperInventory, com.songoda.epichoppers.api.hopper.Hopper hopper, ItemStack item, int amt, int place) { + Location dest = hopper.getFilter().getEndPoint(); + if (!dest.getWorld().isChunkLoaded(dest.getBlockX() >> 4, dest.getBlockZ() >> 4)) + return; + + Block destinationBlock = dest.getBlock(); + BlockState state = destinationBlock.getState(); + if (!(state instanceof InventoryHolder)) { + hopper.getFilter().setEndPoint(null); + return; + } + Inventory destinationInventory = ((InventoryHolder) state).getInventory(); + + addItem(hopperInventory, hopper, destinationInventory, destinationBlock, item, amt, place); + } + + private boolean addItem(Inventory hopperInventory, com.songoda.epichoppers.api.hopper.Hopper hopper, Inventory destinationInventory, Block destinationBlock, ItemStack is, int amt, int place) { + ItemStack it = null; + if (is != null) { + it = is.clone(); + it.setAmount(1); + } + + List ovoid = new ArrayList<>(hopper.getFilter().getVoidList()); + + if (is.getType() == Material.AIR) { + return true; + } + ItemStack item = is; + ItemStack newItem = is.clone(); + + if ((item.getAmount() - amt) <= 0) { + amt = item.getAmount(); + } + if ((item.getAmount() - amt) >= 1) { + newItem.setAmount(newItem.getAmount() - amt); + is = newItem.clone(); + } else { + is = null; + } + + newItem.setAmount(amt); + + if (destinationBlock.getType().equals(Material.ENDER_CHEST)) { + OfflinePlayer op = Bukkit.getOfflinePlayer(hopper.getPlacedBy()); + + if (op.isOnline() && canMove(op.getPlayer().getEnderChest(), newItem)) { + ItemStack finalIt = it; + if (ovoid.stream().noneMatch(itemStack -> itemStack.isSimilar(finalIt))) { + op.getPlayer().getEnderChest().addItem(newItem); + } + hopperInventory.setItem(place, is); + } + return true; + } + + switch (destinationBlock.getType()) { + case BLACK_SHULKER_BOX: + case BLUE_SHULKER_BOX: + case BROWN_SHULKER_BOX: + case CYAN_SHULKER_BOX: + case GRAY_SHULKER_BOX: + case GREEN_SHULKER_BOX: + case LIGHT_BLUE_SHULKER_BOX: + case LIGHT_GRAY_SHULKER_BOX: + case LIME_SHULKER_BOX: + case MAGENTA_SHULKER_BOX: + case ORANGE_SHULKER_BOX: + case PINK_SHULKER_BOX: + case PURPLE_SHULKER_BOX: + case RED_SHULKER_BOX: + case SHULKER_BOX: + case WHITE_SHULKER_BOX: + case YELLOW_SHULKER_BOX: + return false; + case BREWING_STAND: { + BrewerInventory brewerInventory = (BrewerInventory) destinationInventory; + + int maxSize = newItem.getMaxStackSize(); + + String typeStr = item.getType().name().toUpperCase(); + boolean isBottle = typeStr.contains("POTION") || typeStr.contains("BOTTLE") || item.getType() == Material.DRAGON_BREATH; + boolean isLeft = item.getType() == Material.BLAZE_POWDER; + + Map output = new HashMap<>(); + if (isBottle) { + output.put(0, brewerInventory.getItem(0)); + output.put(1, brewerInventory.getItem(1)); + output.put(2, brewerInventory.getItem(2)); + } else if (isLeft) { + output.put(4, brewerInventory.getItem(4)); + } else { + output.put(3, brewerInventory.getItem(3)); + } + + ItemStack finalIt = it; + for (Map.Entry entry : output.entrySet()) { + if (ovoid.stream().noneMatch(itemStack -> itemStack.isSimilar(finalIt))) { + ItemStack currentOutput = entry.getValue(); + int currentOutputAmount = currentOutput == null ? 0 : currentOutput.getAmount(); + if (currentOutput != null && (!currentOutput.isSimilar(newItem)) + || currentOutputAmount + newItem.getAmount() > maxSize) continue; + + if (currentOutput != null) { + currentOutput.setAmount(currentOutputAmount + newItem.getAmount()); + } else { + currentOutput = newItem.clone(); + } + + brewerInventory.setItem(entry.getKey(), currentOutput); + } + hopperInventory.setItem(place, is); + return true; + } + break; + } + case FURNACE: { + FurnaceInventory furnaceInventory = (FurnaceInventory) destinationInventory; + + boolean isFuel = item.getType().isFuel() && !item.getType().name().contains("LOG"); + ItemStack output = isFuel ? furnaceInventory.getFuel() : furnaceInventory.getSmelting(); + if (output != null && !output.isSimilar(newItem)) return false; + int maxSize = newItem.getMaxStackSize(); + int currentOutputAmount = output == null ? 0 : output.getAmount(); + + if (currentOutputAmount + newItem.getAmount() <= maxSize) { + ItemStack finalIt = it; + if (ovoid.stream().noneMatch(itemStack -> itemStack.isSimilar(finalIt))) { + if (output != null) { + output.setAmount(currentOutputAmount + newItem.getAmount()); + } else { + output = newItem.clone(); + } + if (isFuel) { + furnaceInventory.setFuel(output); + } else { + furnaceInventory.setSmelting(output); + } + hopperInventory.setItem(place, is); + } + } + return true; + } + } + + if (!canMove(destinationInventory, newItem)) return false; + ItemStack finalIt = it; + if (ovoid.stream().noneMatch(itemStack -> itemStack.isSimilar(finalIt))) { + destinationInventory.addItem(newItem); + } + hopperInventory.setItem(place, is); + return true; + } + + private boolean canMove(Inventory inventory, ItemStack item) { + if (inventory.firstEmpty() != -1) return true; + for (ItemStack stack : inventory.getContents()) { + if (stack.isSimilar(item) && (stack.getAmount() + item.getAmount()) - 1 < stack.getMaxStackSize()) { + return true; + } + } + return false; + } + + public enum HopperDirection { + + DOWN(0, 8, 0, -1, 0), + NORTH(2, 10, 0, 0, -1), + SOUTH(3, 11, 0, 0, 1), + WEST(4, 12, -1, 0, 0), + EAST(5, 13, 1, 0, 0); + + private int unpowered; + private int powered; + + private int x; + private int y; + private int z; + + HopperDirection(int unpowered, int powered, int x, int y, int z) { + this.unpowered = unpowered; + this.powered = powered; + + this.x = x; + this.y = y; + this.z = z; + } + + public static HopperDirection getDirection(int value) { + for (HopperDirection hopperDirection : HopperDirection.values()) { + if (hopperDirection.getPowered() == value + || hopperDirection.getUnpowered() == value) return hopperDirection; + } + return null; + } + + public Location getLocation(Location location) { + return location.add(getX(), getY(), getZ()); + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getZ() { + return z; + } + + public int getUnpowered() { + return unpowered; + } + + public int getPowered() { + return powered; + } + } +} \ No newline at end of file diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/SettingsManager.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/SettingsManager.java index 267a528..588fc1b 100644 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/SettingsManager.java +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/SettingsManager.java @@ -43,14 +43,14 @@ public class SettingsManager implements Listener { return; } - if (event.getInventory().getTitle().equals(pluginName + " Settings Manager")) { + if (event.getView().getTitle().equals(pluginName + " Settings Manager")) { event.setCancelled(true); if (clickedItem.getType().name().contains("STAINED_GLASS")) return; String type = ChatColor.stripColor(clickedItem.getItemMeta().getDisplayName()); this.cat.put((Player) event.getWhoClicked(), type); this.openEditor((Player) event.getWhoClicked()); - } else if (event.getInventory().getTitle().equals(pluginName + " Settings Editor")) { + } else if (event.getView().getTitle().equals(pluginName + " Settings Editor")) { event.setCancelled(true); if (clickedItem.getType().name().contains("STAINED_GLASS")) return; @@ -82,7 +82,9 @@ public class SettingsManager implements Listener { config.set(value, event.getMessage()); } - this.finishEditing(player); + Bukkit.getScheduler().scheduleSyncDelayedTask(EpicHoppersPlugin.getInstance(), () -> + this.finishEditing(player), 0L); + event.setCancelled(true); } @@ -211,5 +213,20 @@ public class SettingsManager implements Listener { this.option = option; } + public List getStringList() { + return EpicHoppersPlugin.getInstance().getConfig().getStringList(setting); + } + + public boolean getBoolean() { + return EpicHoppersPlugin.getInstance().getConfig().getBoolean(setting); + } + + public int getInt() { + return EpicHoppersPlugin.getInstance().getConfig().getInt(setting); + } + + public String getString() { + return EpicHoppersPlugin.getInstance().getConfig().getString(setting); + } } } \ No newline at end of file diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/gui/AbstractAnvilGUI.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/gui/AbstractAnvilGUI.java deleted file mode 100644 index 27cf3fc..0000000 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/gui/AbstractAnvilGUI.java +++ /dev/null @@ -1,270 +0,0 @@ -package com.songoda.epichoppers.utils.gui; - -import com.songoda.epichoppers.EpicHoppersPlugin; -import com.songoda.epichoppers.utils.version.NMSUtil; -import org.bukkit.Bukkit; -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; - -public class AbstractAnvilGUI { - - private static Class BlockPosition; - private static Class PacketPlayOutOpenWindow; - private static Class ContainerAnvil; - private static Class ChatMessage; - private static Class EntityHuman; - private static boolean loadedClasses = false; - private Player player; - @SuppressWarnings("unused") - private AnvilClickEventHandler handler; - private Map items = new HashMap<>(); - private OnClose onClose = null; - private Inventory inv; - private Listener listener; - - private Sound closeSound = Sound.ENTITY_PLAYER_LEVELUP; - - public AbstractAnvilGUI(final Player player, final AnvilClickEventHandler handler) { - loadClasses(); - this.player = player; - this.handler = handler; - - this.listener = new Listener() { - @EventHandler - public void onInventoryClick(InventoryClickEvent event) { - if (!(event.getWhoClicked() instanceof Player) || !event.getInventory().equals(inv)) return; - - event.setCancelled(true); - - ItemStack item = event.getCurrentItem(); - int slot = event.getRawSlot(); - String name = ""; - - if (item != null) { - if (item.hasItemMeta()) { - ItemMeta meta = item.getItemMeta(); - - if (meta.hasDisplayName()) { - name = meta.getDisplayName(); - } - } - } - - AnvilClickEvent clickEvent = new AnvilClickEvent(AnvilSlot.bySlot(slot), name); - - handler.onAnvilClick(clickEvent); - - if (clickEvent.getWillClose()) { - event.getWhoClicked().closeInventory(); - } - - if (clickEvent.getWillDestroy()) { - destroy(); - } - } - - @EventHandler - public void onInventoryClose(InventoryCloseEvent event) { - if (!(event.getPlayer() instanceof Player)) return; - Inventory inv = event.getInventory(); - player.setLevel(player.getLevel() - 1); - if (!inv.equals(AbstractAnvilGUI.this.inv)) return; - inv.clear(); - OnClose onClose = getOnClose(); - player.playSound(player.getLocation(), closeSound, 1F, 1F); - Bukkit.getScheduler().scheduleSyncDelayedTask(EpicHoppersPlugin.getInstance(), () -> { - if (onClose != null) onClose.OnClose(player, inv); - destroy(); - }, 1L); - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - if (!event.getPlayer().equals(getPlayer())) return; - player.setLevel(player.getLevel() - 1); - destroy(); - } - }; - - Bukkit.getPluginManager().registerEvents(listener, EpicHoppersPlugin.getInstance()); - } - - private void loadClasses() { - if (loadedClasses) return; - BlockPosition = NMSUtil.getNMSClass("BlockPosition"); - PacketPlayOutOpenWindow = NMSUtil.getNMSClass("PacketPlayOutOpenWindow"); - ContainerAnvil = NMSUtil.getNMSClass("ContainerAnvil"); - EntityHuman = NMSUtil.getNMSClass("EntityHuman"); - ChatMessage = NMSUtil.getNMSClass("ChatMessage"); - loadedClasses = true; - } - - public Player getPlayer() { - return player; - } - - public void setSlot(AnvilSlot slot, ItemStack item) { - items.put(slot, item); - } - - public void open() { - player.setLevel(player.getLevel() + 1); - - try { - Object craftPlayer = NMSUtil.getCraftClass("entity.CraftPlayer").cast(player); - Method getHandleMethod = craftPlayer.getClass().getMethod("getHandle", new Class[0]); - Object entityPlayer = getHandleMethod.invoke(craftPlayer, new Object[0]); - - Object container; - - if (NMSUtil.getVersionNumber() == 7) { - container = ContainerAnvil.getConstructor(new Class[]{NMSUtil.getNMSClass("PlayerInventory"), NMSUtil.getNMSClass("World"), Integer.TYPE, Integer.TYPE, Integer.TYPE, EntityHuman}).newInstance(new Object[]{NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "inventory", false)), NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "world", false)), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0), entityPlayer}); - } else { - container = ContainerAnvil.getConstructor(NMSUtil.getNMSClass("PlayerInventory"), NMSUtil.getNMSClass("World"), BlockPosition, EntityHuman).newInstance(NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "inventory", false)), NMSUtil.getFieldObject(entityPlayer, NMSUtil.getField(entityPlayer.getClass(), "world", false)), BlockPosition.getConstructor(int.class, int.class, int.class).newInstance(0, 0, 0), entityPlayer); - } - - NMSUtil.getField(NMSUtil.getNMSClass("Container"), "checkReachable", true).set(container, false); - - Method getBukkitViewMethod = container.getClass().getMethod("getBukkitView", new Class[0]); - Object bukkitView = getBukkitViewMethod.invoke(container); - Method getTopInventoryMethod = bukkitView.getClass().getMethod("getTopInventory", new Class[0]); - inv = (Inventory) getTopInventoryMethod.invoke(bukkitView); - - for (AnvilSlot slot : items.keySet()) { - inv.setItem(slot.getSlot(), items.get(slot)); - } - - Method nextContainerCounterMethod = entityPlayer.getClass().getMethod("nextContainerCounter", new Class[0]); - int c = (int) nextContainerCounterMethod.invoke(entityPlayer); - - Constructor chatMessageConstructor = ChatMessage.getConstructor(String.class, Object[].class); - Object packet; - - if (NMSUtil.getVersionNumber() == 7) { - packet = PacketPlayOutOpenWindow.getConstructor(new Class[]{Integer.TYPE, Integer.TYPE, String.class, Integer.TYPE, Boolean.TYPE, Integer.TYPE}).newInstance(new Object[]{Integer.valueOf(c), Integer.valueOf(8), "Repairing", Integer.valueOf(0), Boolean.valueOf(true), Integer.valueOf(0)}); - } else { - packet = PacketPlayOutOpenWindow.getConstructor(int.class, String.class, NMSUtil.getNMSClass("IChatBaseComponent"), int.class).newInstance(c, "minecraft:anvil", chatMessageConstructor.newInstance("Repairing", new Object[]{}), 0); - } - - NMSUtil.sendPacket(player, packet); - - Field activeContainerField = NMSUtil.getField(EntityHuman, "activeContainer", true); - - if (activeContainerField != null) { - activeContainerField.set(entityPlayer, container); - NMSUtil.getField(NMSUtil.getNMSClass("Container"), "windowId", true).set(activeContainerField.get(entityPlayer), c); - - Method addSlotListenerMethod = activeContainerField.get(entityPlayer).getClass().getMethod("addSlotListener", NMSUtil.getNMSClass("ICrafting")); - addSlotListenerMethod.invoke(activeContainerField.get(entityPlayer), entityPlayer); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void destroy() { - onClose = null; - player = null; - handler = null; - items = null; - - HandlerList.unregisterAll(listener); - - listener = null; - } - - private OnClose getOnClose() { - return onClose; - } - - public void setOnClose(OnClose onClose) { - this.onClose = onClose; - } - - public void setCloseSound(Sound sound) { - closeSound = sound; - } - - public enum AnvilSlot { - INPUT_LEFT(0), - INPUT_RIGHT(1), - OUTPUT(2); - - private int slot; - - private AnvilSlot(int slot) { - this.slot = slot; - } - - public static AnvilSlot bySlot(int slot) { - for (AnvilSlot anvilSlot : values()) { - if (anvilSlot.getSlot() == slot) { - return anvilSlot; - } - } - - return null; - } - - public int getSlot() { - return slot; - } - } - - public interface AnvilClickEventHandler { - void onAnvilClick(AnvilClickEvent event); - } - - public class AnvilClickEvent { - private AnvilSlot slot; - - private String name; - - private boolean close = true; - private boolean destroy = true; - - public AnvilClickEvent(AnvilSlot slot, String name) { - this.slot = slot; - this.name = name; - } - - public AnvilSlot getSlot() { - return slot; - } - - public String getName() { - return name; - } - - public boolean getWillClose() { - return close; - } - - public void setWillClose(boolean close) { - this.close = close; - } - - public boolean getWillDestroy() { - return destroy; - } - - public void setWillDestroy(boolean destroy) { - this.destroy = destroy; - } - } -} diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/gui/AbstractGUI.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/gui/AbstractGUI.java index a63c749..13c0385 100644 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/gui/AbstractGUI.java +++ b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/gui/AbstractGUI.java @@ -114,7 +114,7 @@ public abstract class AbstractGUI implements Listener { protected void init(String title, int slots) { if (inventory == null || inventory.getSize() != slots - || ChatColor.translateAlternateColorCodes('&', title) != inventory.getTitle()) { + || !ChatColor.translateAlternateColorCodes('&', title).equals(player.getOpenInventory().getTitle())) { this.inventory = Bukkit.getServer().createInventory(new GUIHolder(), slots, ChatColor.translateAlternateColorCodes('&', title)); registerClickables(); registerOnCloses(); diff --git a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/version/NMSUtil.java b/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/version/NMSUtil.java deleted file mode 100644 index eae5e67..0000000 --- a/EpicHoppers-Plugin/src/main/java/com/songoda/epichoppers/utils/version/NMSUtil.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.songoda.epichoppers.utils.version; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.lang.reflect.Field; - -public class NMSUtil { - - public static String getVersion() { - String name = Bukkit.getServer().getClass().getPackage().getName(); - return name.substring(name.lastIndexOf('.') + 1) + "."; - } - - public static int getVersionNumber() { - String name = getVersion().substring(3); - return Integer.valueOf(name.substring(0, name.length() - 4)); - } - - public static int getVersionReleaseNumber() { - String NMSVersion = getVersion(); - return Integer.valueOf(NMSVersion.substring(NMSVersion.length() - 2).replace(".", "")); - } - - public static Class getNMSClass(String className) { - try { - String fullName = "net.minecraft.server." + getVersion() + className; - Class clazz = Class.forName(fullName); - return clazz; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - public static Class getCraftClass(String className) throws ClassNotFoundException { - try { - String fullName = "org.bukkit.craftbukkit." + getVersion() + className; - Class clazz = Class.forName(fullName); - return clazz; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - public static Field getField(Class clazz, String name, boolean declared) { - try { - Field field; - - if (declared) { - field = clazz.getDeclaredField(name); - } else { - field = clazz.getField(name); - } - - field.setAccessible(true); - return field; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - public static Object getFieldObject(Object object, Field field) { - try { - return field.get(object); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - public static void setField(Object object, String fieldName, Object fieldValue, boolean declared) { - try { - Field field; - - if (declared) { - field = object.getClass().getDeclaredField(fieldName); - } else { - field = object.getClass().getField(fieldName); - } - - field.setAccessible(true); - field.set(object, fieldValue); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void sendPacket(Player player, Object packet) { - try { - Object handle = player.getClass().getMethod("getHandle").invoke(player); - Object playerConnection = handle.getClass().getField("playerConnection").get(handle); - playerConnection.getClass().getMethod("sendPacket", getNMSClass("Packet")).invoke(playerConnection, packet); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/pom.xml b/pom.xml index f16ae25..ca6a3ca 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ org.spigotmc spigot - 1.13.2 + 1.14-pre5 provided