mirror of
https://github.com/songoda/EpicHoppers.git
synced 2024-12-01 14:44:09 +01:00
Merge branch 'development' into 'master'
1.14 Support See merge request Songoda/epichoppers!23
This commit is contained in:
commit
34929f241c
@ -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 {
|
||||
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ import java.util.Map;
|
||||
|
||||
public class ModuleAutoCrafting implements Module {
|
||||
|
||||
private final Map<Material, Recipe> cachedRecipes = new HashMap<>();
|
||||
private final Map<Material, Recipes> cachedRecipes = new HashMap<>();
|
||||
private final Map<Hopper, Material> lastMaterial = new HashMap<>();
|
||||
|
||||
public static List<ItemStack> compressItemStack(List<ItemStack> 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;
|
||||
|
||||
Recipe recipe = cachedRecipes.get(hopper.getAutoCrafting());
|
||||
if (!(recipe instanceof ShapedRecipe) && !(recipe instanceof ShapelessRecipe)) return;
|
||||
List<ItemStack> 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 (hopper.getAutoCrafting() != null && canMove(hopperInventory, new ItemStack(hopper.getAutoCrafting()))) {
|
||||
|
||||
Map<Material, Integer> 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);
|
||||
}
|
||||
}
|
||||
if (cachedRecipes.get(hopper.getAutoCrafting()) == null) 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();
|
||||
}
|
||||
top:
|
||||
for (Recipe recipe : cachedRecipes.get(hopper.getAutoCrafting()).getRecipes()) {
|
||||
if (!(recipe instanceof ShapedRecipe) && !(recipe instanceof ShapelessRecipe)) continue;
|
||||
List<ItemStack> 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;
|
||||
|
||||
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<Material, Integer> 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<Material> 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<Recipe> recipes = new ArrayList<>();
|
||||
|
||||
public List<Recipe> getRecipes() {
|
||||
return new ArrayList<>(recipes);
|
||||
}
|
||||
|
||||
public void addRecipe(Recipe recipe) {
|
||||
this.recipes.add(recipe);
|
||||
}
|
||||
|
||||
public void clearRecipes() {
|
||||
recipes.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<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:
|
||||
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<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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<AnvilSlot, ItemStack> 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user