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:
Brianna 2019-04-24 23:02:45 -04:00
parent 6f8f1fa7eb
commit 0db01630aa
10 changed files with 414 additions and 400 deletions

View File

@ -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);

View File

@ -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();

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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());
}
}

View File

@ -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) {
}

View File

@ -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;

View File

@ -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();

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}