mirror of
https://github.com/songoda/EpicHoppers.git
synced 2024-11-29 05:36:04 +01:00
Converted HopHandler to HopTask.
Optimized the hop task. Made it so rejected items without an endpoint doesn't halt all transfer. Fixed an issue with hopper teleport caching.
This commit is contained in:
parent
6f8f1fa7eb
commit
0db01630aa
@ -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<Material> getBlockedItems(Hopper hopper);
|
||||
|
||||
|
@ -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 {
|
||||
@ -66,9 +63,7 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
|
||||
private static EpicHoppersPlugin INSTANCE;
|
||||
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 SettingsManager settingsManager; private ConfigWrapper levelsFile = new ConfigWrapper(this, "", "levels.yml");
|
||||
private Locale locale;
|
||||
|
||||
private HopperManager hopperManager;
|
||||
@ -142,7 +137,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();
|
||||
|
@ -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<Material> 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<Material> materials = module.getBlockedItems(hopper);
|
||||
if (materials == null || materials.isEmpty()) continue;
|
||||
blockedMaterials.addAll(materials);
|
||||
}
|
||||
|
||||
ItemStack[] hopperContents = hopperState.getInventory().getContents();
|
||||
|
||||
Inventory override = null;
|
||||
List<Location> 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<Entity> 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<ItemStack> whiteList = hopper.getFilter().getWhiteList();
|
||||
List<ItemStack> 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<ItemStack> 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<Integer, ItemStack> 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<Integer, ItemStack> 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -38,9 +38,10 @@ 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;
|
||||
@ -48,7 +49,7 @@ public class ModuleAutoCrafting implements Module {
|
||||
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 (hopperInventory.getSize() == 0) return;
|
||||
|
||||
Map<Material, Integer> items = new HashMap<>();
|
||||
for (ItemStack item : ingredientMap) {
|
||||
@ -63,7 +64,7 @@ public class ModuleAutoCrafting implements Module {
|
||||
for (Material material : items.keySet()) {
|
||||
int amt = 0;
|
||||
ItemStack item = new ItemStack(material, items.get(material));
|
||||
for (ItemStack i : hopperBlock.getInventory().getContents()) {
|
||||
for (ItemStack i : hopperInventory.getContents()) {
|
||||
if (i == null) continue;
|
||||
if (i.getType() != material) continue;
|
||||
amt += i.getAmount();
|
||||
@ -77,19 +78,19 @@ public class ModuleAutoCrafting implements Module {
|
||||
for (Material material : items.keySet()) {
|
||||
int amtRemoved = 0;
|
||||
ItemStack toRemove = new ItemStack(material, items.get(material));
|
||||
for (ItemStack i : hopperBlock.getInventory().getContents()) {
|
||||
for (ItemStack i : hopperInventory.getContents()) {
|
||||
if (i == null || i.getType() != material) continue;
|
||||
if (toRemove.getAmount() - amtRemoved <= i.getAmount()) {
|
||||
toRemove.setAmount(toRemove.getAmount() - amtRemoved);
|
||||
hopperBlock.getInventory().removeItem(toRemove);
|
||||
hopperInventory.removeItem(toRemove);
|
||||
continue main2;
|
||||
} else {
|
||||
amtRemoved += i.getAmount();
|
||||
hopperBlock.getInventory().removeItem(i);
|
||||
hopperInventory.removeItem(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
hopperBlock.getInventory().addItem(recipe.getResult());
|
||||
hopperInventory.addItem(recipe.getResult());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<Entity> 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();
|
||||
|
@ -0,0 +1,373 @@
|
||||
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<Material> blockedMaterials = new ArrayList<>();
|
||||
|
||||
for (Module module : hopper.getLevel().getRegisteredModules()) {
|
||||
// Run Module
|
||||
module.run(hopper, hopperInventory);
|
||||
|
||||
// Add banned materials to list.
|
||||
List<Material> 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<Location> 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<Entity> 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<ItemStack> whiteList = hopper.getFilter().getWhiteList();
|
||||
List<ItemStack> 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<ItemStack> 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:
|
||||
if (item.getType().name().contains("SHULKER_BOX")) return false;
|
||||
break;
|
||||
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<Integer, ItemStack> 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<Integer, ItemStack> 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -213,5 +213,20 @@ public class SettingsManager implements Listener {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public List<String> 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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user