Added the ability to link a hopper to more than one hopper.

This commit is contained in:
Brianna O'Keefe 2018-12-01 06:42:04 -05:00
parent 78021b6d0d
commit a0fe05eaae
19 changed files with 195 additions and 123 deletions

View File

@ -6,6 +6,7 @@ import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.UUID;
public interface Hopper {
@ -13,16 +14,16 @@ public interface Hopper {
org.bukkit.block.Hopper getHopper();
/**
* This will sync this hopper with another hopper.
* This will link this hopper with another hopper.
*
* @param toSync the block containing the hopper
* that this hopper will be synchronized
* with
* @param filtered whether or not this action is for the
* filtered sync or not
* filtered link or not
* @param player the player initializing the synchronization
*/
void sync(Block toSync, boolean filtered, Player player);
void link(Block toSync, boolean filtered, Player player);
/**
* Get location of the hopper.
@ -108,22 +109,11 @@ public interface Hopper {
*/
void setTeleportTrigger(TeleportTrigger teleportTrigger);
/**
* Get the Block containing the hopper that is
* currently synchronised with this hopper.
*
* @return the Block in which this hopper is
* currently synchronized too
*/
Block getSyncedBlock();
List<Block> getLinkedBlocks();
/**
* Set the Block containing a hopper in which
* to synchronize this hopper with.
*
* @param syncedBlock block to sync with
*/
void setSyncedBlock(Block syncedBlock);
void addLinkedBlock(Block block);
void clearLinkedBlocks();
/**
* Get the filter associated with this hopper

View File

@ -51,6 +51,8 @@ public interface Level {
boolean isTeleport();
int getLinkAmount();
/**
* Get the cost in experience in order to upgrade
* to this level.

View File

@ -15,12 +15,12 @@ public interface LevelManager {
* @param level The level of the hopper
* @param costExperience The cost in experience to upgrade the hopper
* @param costEconomy The cost in economy to upgrade the hopper
* @param range The range in which this hopper will need to be in order to sync with another hopper
* @param range The range in which this hopper will need to be in order to link with another hopper
* @param amount The amount of items this hopper will transfer at a single time
* @param filter Whether or not access to the filter is allowed.
* @param teleport Whether or not teleporting through hoppers is allowed.
*/
void addLevel(int level, int costExperience, int costEconomy, int range, int amount, boolean filter, boolean teleport, ArrayList<Module> modules);
void addLevel(int level, int costExperience, int costEconomy, int range, int amount, boolean filter, boolean teleport, int linkAmount, ArrayList<Module> modules);
/**
* Get {@link Level} by corresponding integer value.

View File

@ -147,15 +147,20 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
* Register hoppers into HopperManger from configuration
*/
Bukkit.getScheduler().runTaskLater(this, () -> {
if (storage.containsGroup("sync")) {
for (StorageRow row : storage.getRowsByGroup("sync")) {
if (storage.containsGroup("link")) {
for (StorageRow row : storage.getRowsByGroup("link")) {
Location location = Serialize.getInstance().unserializeLocation(row.getKey());
if (location == null || location.getBlock() == null) return;
int level = row.get("level").asInt();
String blockLoc = row.get("block").asString();
Block block = blockLoc == null ? null : Arconix.pl().getApi().serialize().unserializeLocation(blockLoc).getBlock();
List<String> blockLoc = row.get("block").asStringList();
List<Block> blocks = new ArrayList<>();
if (blockLoc != null) {
for (String string : blockLoc) {
blocks.add(Arconix.pl().getApi().serialize().unserializeLocation(string).getBlock());
}
}
TeleportTrigger teleportTrigger = TeleportTrigger.valueOf(row.get("teleporttrigger").asString() == null ? "DISABLED" : row.get("teleporttrigger").asString());
@ -180,7 +185,7 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
filter.setVoidList(voidList);
filter.setEndPoint(black);
EHopper hopper = new EHopper(location, levelManager.getLevel(level), lastPlayer, placedBy, block, filter, teleportTrigger, autoCrafting);
EHopper hopper = new EHopper(location, levelManager.getLevel(level), lastPlayer, placedBy, blocks, filter, teleportTrigger, autoCrafting);
hopperManager.addHopper(location, hopper);
}
@ -302,9 +307,9 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
continue;
String locationStr = Arconix.pl().getApi().serialize().serializeLocation(hopper.getLocation());
storage.prepareSaveItem("sync", new StorageItem("location", locationStr),
storage.prepareSaveItem("link", new StorageItem("location", locationStr),
new StorageItem("level", hopper.getLevel().getLevel()),
new StorageItem("block", hopper.getSyncedBlock() == null ? null : Arconix.pl().getApi().serialize().serializeLocation(hopper.getSyncedBlock().getLocation())),
new StorageItem("block", true, hopper.getLinkedBlocks() == null || hopper.getLinkedBlocks().isEmpty() ? new ArrayList<>() : hopper.getLinkedBlocks()),
new StorageItem("placedby", hopper.getPlacedBy() == null ? null : hopper.getPlacedBy().toString()),
new StorageItem("player", hopper.getLastPlayer() == null ? null : hopper.getLastPlayer().toString()),
new StorageItem("teleporttrigger", hopper.getTeleportTrigger().toString()),
@ -342,6 +347,7 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
int radius = levels.getInt("Range");
int amount = levels.getInt("Amount");
int linkAmount = levels.getInt("Link-amount", 1);
boolean filter = levels.getBoolean("Filter");
boolean teleport = levels.getBoolean("Teleport");
int costExperiance = levels.getInt("Cost-xp");
@ -359,8 +365,7 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
}
}
levelManager.addLevel(level, costExperiance, costEconomy, radius, amount, filter, teleport, modules);
levelManager.addLevel(level, costExperiance, costEconomy, radius, amount, filter, teleport, linkAmount, modules);
}
}
@ -385,11 +390,13 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
levels.set("Level-3.Amount", 3);
levels.set("Level-3.Suction", 1);
levels.set("Level-3.Cost-xp", 30);
levels.set("Level-3.Link-amount", 2);
levels.set("Level-3.Cost-eco", 10000);
levels.set("Level-4.Range", 40);
levels.set("Level-4.Amount", 4);
levels.set("Level-4.Suction", 2);
levels.set("Level-4.Link-amount", 2);
levels.set("Level-4.BlockBreak", 4);
levels.set("Level-4.Cost-xp", 35);
levels.set("Level-4.Cost-eco", 12000);
@ -398,6 +405,7 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
levels.set("Level-5.Amount", 5);
levels.set("Level-5.Suction", 3);
levels.set("Level-5.BlockBreak", 2);
levels.set("Level-5.Link-amount", 3);
levels.set("Level-5.Cost-xp", 40);
levels.set("Level-5.Cost-eco", 15000);
@ -407,6 +415,7 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
levels.set("Level-6.BlockBreak", 2);
levels.set("Level-6.Filter", true);
levels.set("Level-6.Teleport", true);
levels.set("Level-6.Link-amount", 3);
levels.set("Level-6.Cost-xp", 45);
levels.set("Level-6.Cost-eco", 20000);
@ -417,6 +426,7 @@ public class EpicHoppersPlugin extends JavaPlugin implements EpicHoppers {
levels.set("Level-7.Filter", true);
levels.set("Level-7.Teleport", true);
levels.set("Level-7.AutoCrafting", true);
levels.set("Level-7.Link-amount", 4);
levels.set("Level-7.Cost-xp", 50);
levels.set("Level-7.Cost-eco", 30000);

View File

@ -41,12 +41,12 @@ public class HopHandler {
private void hopperCleaner() {
try {
ConfigurationSection data = instance.getConfig().createSection("data");
if (!data.contains("sync")) return;
for (String key : data.getConfigurationSection("sync").getKeys(false)) {
if (!data.contains("link")) return;
for (String key : data.getConfigurationSection("link").getKeys(false)) {
if (Arconix.pl().getApi().serialize().unserializeLocation(key).getWorld() == null) continue;
Block block = Arconix.pl().getApi().serialize().unserializeLocation(key).getBlock();
if (block != null && block.getState() instanceof Hopper) continue;
data.getConfigurationSection("sync").set(key, null);
data.getConfigurationSection("link").set(key, null);
instance.getLogger().info("EpicHoppers Removing non-hopper entry: " + key);
}
} catch (Exception e) {
@ -56,6 +56,7 @@ public class HopHandler {
private void hopperRunner() {
try {
main:
for (com.songoda.epichoppers.api.hopper.Hopper hopper : instance.getHopperManager().getHoppers().values()) {
Location location = hopper.getLocation();
@ -95,63 +96,68 @@ public class HopHandler {
blockedMaterials.addAll(materials);
}
if (hopper.getSyncedBlock() == null) continue;
Location dest = hopper.getSyncedBlock().getLocation();
if (dest == null) continue;
if (hopper.getLinkedBlocks() == null || hopper.getLinkedBlocks().isEmpty()) continue;
int destx = location.getBlockX() >> 4;
int destz = location.getBlockZ() >> 4;
if (!dest.getWorld().isChunkLoaded(destx, destz)) {
continue;
}
for (Block destBlock : hopper.getLinkedBlocks()) {
Location dest = destBlock.getLocation();
if (dest == null) continue;
Block b2 = dest.getBlock();
if (!(b2.getState() instanceof InventoryHolder || b2.getType() == Material.ENDER_CHEST)) {
hopper.setSyncedBlock(null);
continue;
}
//InventoryHolder inventoryHolder = (InventoryHolder) b2.getState();
//TODO add some restrictions here if needed
BoostData boostData = instance.getBoostManager().getBoost(hopper.getPlacedBy());
int amt = 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++) {
ItemStack it;
if (is[i] != null) {
it = is[i].clone();
it.setAmount(1);
}
if (hopper.getLocation().getBlock().isBlockPowered()
|| is[i] != null && blockedMaterials.contains(is[i].getType())) {
i++;
if (i >= 5) continue;
int destx = location.getBlockX() >> 4;
int destz = location.getBlockZ() >> 4;
if (!dest.getWorld().isChunkLoaded(destx, destz)) {
continue;
}
int finalI = i;
if (is[i] != null
&& !whiteList.isEmpty()
&& whiteList.stream().noneMatch(itemStack -> itemStack.isSimilar(is[finalI]))) {
doBlacklist(hopperBlock, hopper, is[i].clone(), is, amt, i);
} else {
if (is[i] != null && blackList.stream().noneMatch(itemStack -> itemStack.isSimilar(is[finalI]))) {
Block b2 = dest.getBlock();
if (!(b2.getState() instanceof InventoryHolder)) {
hopper.clearLinkedBlocks();
continue;
}
int im = addItem(hopperBlock, hopper, b2, is[i], is, amt, i);
if (im != 10)
i = im;
//InventoryHolder inventoryHolder = (InventoryHolder) b2.getState();
//TODO add some restrictions here if needed
BoostData boostData = instance.getBoostManager().getBoost(hopper.getPlacedBy());
int amt = 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++) {
ItemStack it;
if (is[i] != null) {
it = is[i].clone();
it.setAmount(1);
}
if (hopper.getLocation().getBlock().isBlockPowered()
|| is[i] != null && blockedMaterials.contains(is[i].getType())) {
i++;
if (i >= 5) continue;
}
int finalI = i;
if (is[i] != null
&& !whiteList.isEmpty()
&& whiteList.stream().noneMatch(itemStack -> itemStack.isSimilar(is[finalI]))) {
doBlacklist(hopperBlock, hopper, is[i].clone(), is, amt, i);
continue main;
} else {
if (is[i] != null && blackList.stream().anyMatch(itemStack -> itemStack.isSimilar(is[finalI]))) {
doBlacklist(hopperBlock, hopper, is[i].clone(), is, amt, i);
if (is[i] != null && blackList.stream().noneMatch(itemStack -> itemStack.isSimilar(is[finalI]))) {
if (addItem(hopperBlock, hopper, b2, is[i], is, amt, i)) {
continue main;
}
} else {
if (is[i] != null && blackList.stream().anyMatch(itemStack -> itemStack.isSimilar(is[finalI]))) {
doBlacklist(hopperBlock, hopper, is[i].clone(), is, amt, i);
continue main;
}
}
}
}
}
}
}
} catch (Exception e) {
@ -175,13 +181,14 @@ public class HopHandler {
Block b2 = dest.getBlock();
addItem(hopperBlock, hopper, b2, item, isS, amt, place);
}
} catch (Exception e) {
Debugger.runReport(e);
}
}
private int addItem(Hopper hopperBlock, com.songoda.epichoppers.api.hopper.Hopper hopper, Block b2, ItemStack is, ItemStack[] isS, int amt, int place) {
private boolean addItem(Hopper hopperBlock, com.songoda.epichoppers.api.hopper.Hopper hopper, Block b2, ItemStack is, ItemStack[] isS, int amt, int place) {
try {
ItemStack it = null;
if (is != null) {
@ -192,7 +199,7 @@ public class HopHandler {
List<ItemStack> ovoid = new ArrayList<>(hopper.getFilter().getVoidList());
if (is.getType() == Material.AIR) {
return 10;
return true;
}
ItemStack item = is;
ItemStack newItem = is.clone();
@ -257,14 +264,14 @@ public class HopHandler {
isS[place] = is;
hopperBlock.getInventory().setContents(isS);
return 4;
return true;
}
} else if (b2.getType() == Material.FURNACE) {
FurnaceInventory furnaceInventory = (FurnaceInventory) outputContainer.getInventory();
boolean isFuel = item.getType().isFuel();
ItemStack output = isFuel ? furnaceInventory.getFuel() : furnaceInventory.getSmelting();
if (output != null && !output.isSimilar(newItem)) return 4;
if (output != null && !output.isSimilar(newItem)) return false;
int maxSize = newItem.getMaxStackSize();
int currentOutputAmount = output == null ? 0 : output.getAmount();
@ -284,9 +291,9 @@ public class HopHandler {
hopperBlock.getInventory().setContents(isS);
}
}
return 4;
return true;
} else {
if (!canMove(outputContainer.getInventory(), newItem, amt)) return 4;
if (!canMove(outputContainer.getInventory(), newItem, amt)) return false;
ItemStack finalIt = it;
if (ovoid.stream().noneMatch(itemStack -> itemStack.isSimilar(finalIt))) {
outputContainer.getInventory().addItem(newItem);
@ -295,11 +302,11 @@ public class HopHandler {
hopperBlock.getInventory().setContents(isS);
}
}
return 4;
return true;
} catch (Exception e) {
Debugger.runReport(e);
}
return 0;
return false;
}
private boolean canMove(Inventory inventory, ItemStack item, int hop) {

View File

@ -69,10 +69,10 @@ public class TeleportHandler {
EpicHoppersPlugin instance = EpicHoppersPlugin.getInstance();
Block next = hopper.getLocation().getBlock();
int num = 1;
while (instance.getHopperManager().isHopper(next.getLocation()) && instance.getHopperManager().getHopper(next.getLocation()).getSyncedBlock() != null && num != 15) {
while (instance.getHopperManager().isHopper(next.getLocation()) && instance.getHopperManager().getHopper(next.getLocation()).getLinkedBlocks() != null && num != 15) {
Hopper nextHopper = instance.getHopperManager().getHopper(next);
if (nextHopper.getSyncedBlock() != null) {
next = nextHopper.getSyncedBlock();
if (nextHopper.getLinkedBlocks() != null && !nextHopper.getLinkedBlocks().isEmpty()) {
next = nextHopper.getLinkedBlocks().get(0);
}
if (!next.getType().equals(Material.HOPPER)) {

View File

@ -23,6 +23,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.RegisteredServiceProvider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
@ -35,16 +36,16 @@ public class EHopper implements Hopper {
private Level level;
private UUID lastPlayer;
private UUID placedBy;
private Block syncedBlock;
private List<Block> linkedBlocks;
private Filter filter;
private TeleportTrigger teleportTrigger;
private Material autoCrafting;
private org.bukkit.block.Hopper hopper;
public EHopper(Location location, Level level, UUID lastPlayer, UUID placedBy, Block syncedBlock, Filter filter, TeleportTrigger teleportTrigger, Material autoCrafting) {
public EHopper(Location location, Level level, UUID lastPlayer, UUID placedBy, List<Block> linkedBlocks, Filter filter, TeleportTrigger teleportTrigger, Material autoCrafting) {
this.location = location;
this.level = level;
this.syncedBlock = syncedBlock;
this.linkedBlocks = linkedBlocks;
this.filter = filter;
this.lastPlayer = lastPlayer;
this.placedBy = placedBy;
@ -54,8 +55,8 @@ public class EHopper implements Hopper {
this.syncName();
}
public EHopper(Block block, Level level, UUID lastPlayer, UUID placedBy, Block syncedBlock, Filter filter, TeleportTrigger teleportTrigger, Material autoCrafting) {
this(block.getLocation(), level, lastPlayer, placedBy, syncedBlock, filter, teleportTrigger, autoCrafting);
public EHopper(Block block, Level level, UUID lastPlayer, UUID placedBy, List<Block> linkedBlocks, Filter filter, TeleportTrigger teleportTrigger, Material autoCrafting) {
this(block.getLocation(), level, lastPlayer, placedBy, linkedBlocks, filter, teleportTrigger, autoCrafting);
}
public void overview(Player player) {
@ -537,25 +538,39 @@ public class EHopper implements Hopper {
}
@Override
public void sync(Block toSync, boolean filtered, Player player) {
public void link(Block toLink, boolean filtered, Player player) {
try {
EpicHoppersPlugin instance = EpicHoppersPlugin.getInstance();
if (location.getWorld().equals(toSync.getLocation().getWorld())
if (location.getWorld().equals(toLink.getLocation().getWorld())
&& !player.hasPermission("EpicHoppers.Override")
&& !player.hasPermission("EpicHoppers.Admin")
&& location.distance(toSync.getLocation()) > level.getRange()) {
player.sendMessage(instance.getLocale().getMessage("event.hopper.syncoutofrange"));
&& location.distance(toLink.getLocation()) > level.getRange()) {
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.syncoutofrange"));
return;
}
if (linkedBlocks.contains(toLink)) {
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.already"));
return;
}
player.sendMessage(instance.getLocale().getMessage("event.hopper.syncsuccess"));
if (!filtered)
this.syncedBlock = toSync;
this.linkedBlocks.add(toLink);
else
this.filter.setEndPoint(toSync);
this.filter.setEndPoint(toLink);
this.lastPlayer = player.getUniqueId();
if (level.getLinkAmount() > 1) {
if (getLinkedBlocks().size() == level.getLinkAmount()) {
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.syncdone"));
return;
}
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.syncsuccessmore", level.getLinkAmount() - getLinkedBlocks().size()));
return;
}
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.syncsuccess"));
} catch (Exception e) {
Debugger.runReport(e);
}
@ -622,13 +637,18 @@ public class EHopper implements Hopper {
}
@Override
public Block getSyncedBlock() {
return syncedBlock;
public List<Block> getLinkedBlocks() {
return Collections.unmodifiableList(linkedBlocks);
}
@Override
public void setSyncedBlock(Block syncedBlock) {
this.syncedBlock = syncedBlock;
public void addLinkedBlock(Block block) {
linkedBlocks.add(block);
}
@Override
public void clearLinkedBlocks() {
this.linkedBlocks.clear();
}
@Override

View File

@ -8,6 +8,7 @@ import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ -29,7 +30,7 @@ public class EHopperManager implements HopperManager {
@Override
public Hopper getHopper(Location location) {
if (!registeredHoppers.containsKey(roundLocation(location))) {
addHopper(location, new EHopper(location, EpicHoppersPlugin.getInstance().getLevelManager().getLowestLevel(), null, null, null, new EFilter(), TeleportTrigger.DISABLED, null));
addHopper(location, new EHopper(location, EpicHoppersPlugin.getInstance().getLevelManager().getLowestLevel(), null, null, new ArrayList<>(), new EFilter(), TeleportTrigger.DISABLED, null));
}
return registeredHoppers.get(roundLocation(location));
}

View File

@ -11,13 +11,13 @@ public class ELevel implements Level {
private final ArrayList<Module> registeredModules;
private int level, costExperience, costEconomy, range, amount;
private int level, costExperience, costEconomy, range, amount, linkAmount;
private boolean filter, teleport;
private final List<String> description = new ArrayList<>();
ELevel(int level, int costExperience, int costEconomy, int range, int amount, boolean filter, boolean teleport, ArrayList<Module> registeredModules) {
ELevel(int level, int costExperience, int costEconomy, int range, int amount, boolean filter, boolean teleport, int linkAmount, ArrayList<Module> registeredModules) {
this.level = level;
this.costExperience = costExperience;
this.costEconomy = costEconomy;
@ -25,12 +25,14 @@ public class ELevel implements Level {
this.amount = amount;
this.filter = filter;
this.teleport = teleport;
this.linkAmount = linkAmount;
this.registeredModules = registeredModules;
EpicHoppersPlugin instance = EpicHoppersPlugin.getInstance();
description.add(instance.getLocale().getMessage("interface.hopper.range", range));
description.add(instance.getLocale().getMessage("interface.hopper.amount", amount));
if (linkAmount != 1) description.add(instance.getLocale().getMessage("interface.hopper.linkamount", linkAmount));
if (filter) description.add(instance.getLocale().getMessage("interface.hopper.filter", true));
if (teleport) description.add(instance.getLocale().getMessage("interface.hopper.teleport", true));
@ -65,6 +67,11 @@ public class ELevel implements Level {
return teleport;
}
@Override
public int getLinkAmount() {
return linkAmount;
}
@Override
public int getCostExperience() {
return costExperience;

View File

@ -11,8 +11,8 @@ public class ELevelManager implements LevelManager {
private final NavigableMap<Integer, ELevel> registeredLevels = new TreeMap<>();
@Override
public void addLevel(int level, int costExperience, int costEconomy, int range, int amount, boolean filter, boolean teleport, ArrayList<Module> modules) {
registeredLevels.put(level, new ELevel(level, costExperience, costEconomy, range, amount, filter, teleport, modules));
public void addLevel(int level, int costExperience, int costEconomy, int range, int amount, boolean filter, boolean teleport, int linkAmount, ArrayList<Module> modules) {
registeredLevels.put(level, new ELevel(level, costExperience, costEconomy, range, amount, filter, teleport, linkAmount, modules));
}
@Override

View File

@ -25,6 +25,8 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.permissions.PermissionAttachmentInfo;
import java.util.ArrayList;
/**
* Created by songoda on 3/14/2017.
*/
@ -64,7 +66,7 @@ public class BlockListeners implements Listener {
ItemStack item = e.getItemInHand().clone();
instance.getHopperManager().addHopper(e.getBlock().getLocation(), new EHopper(e.getBlock(), instance.getLevelFromItem(item), player.getUniqueId(), player.getUniqueId(), null, new EFilter(), TeleportTrigger.DISABLED, null));
instance.getHopperManager().addHopper(e.getBlock().getLocation(), new EHopper(e.getBlock(), instance.getLevelFromItem(item), player.getUniqueId(), player.getUniqueId(), new ArrayList<>(), new EFilter(), TeleportTrigger.DISABLED, null));
} catch (Exception ee) {
Debugger.runReport(ee);

View File

@ -32,8 +32,9 @@ public class HopperListeners implements Listener {
return;
Hopper hopper = instance.getHopperManager().getHopper(source.getLocation());
if (hopper.getSyncedBlock() == null) {
hopper.setSyncedBlock(event.getDestination().getLocation().getBlock());
if (hopper.getLinkedBlocks() == null && !hopper.getLinkedBlocks().isEmpty()) {
hopper.clearLinkedBlocks();
hopper.addLinkedBlock(event.getDestination().getLocation().getBlock());
}
event.setCancelled(true);
} catch (Exception ee) {

View File

@ -124,13 +124,17 @@ public class InteractListeners implements Listener {
if (e.getClickedBlock().getType() == Material.BREWING_STAND) return;
if (e.getClickedBlock().getState() instanceof InventoryHolder || e.getClickedBlock().getType().equals(Material.ENDER_CHEST) && instance.getConfig().getBoolean("Main.Support Enderchests")) {
Hopper hopper = playerData.getLastHopper();
if (playerData.getSyncType() != null && e.getClickedBlock().getLocation().equals(playerData.getLastHopper().getLocation())) {
player.sendMessage(instance.getLocale().getMessage("event.hopper.syncself"));
} else if (playerData.getSyncType() != null) {
playerData.getLastHopper().sync(e.getClickedBlock(), playerData.getSyncType() == SyncType.FILTERED, player);
hopper.link(e.getClickedBlock(), playerData.getSyncType() == SyncType.FILTERED, player);
}
e.setCancelled(true);
playerData.setSyncType(null);
int amountLinked = hopper.getLevel().getLinkAmount();
if (hopper.getLinkedBlocks().size() >= amountLinked) {
playerData.setSyncType(null);
}
}
} catch (Exception ee) {
Debugger.runReport(ee);

View File

@ -85,7 +85,7 @@ public class InventoryListeners implements Listener {
&& event.getCurrentItem().getItemMeta().getDisplayName().equals(instance.getLocale().getMessage("interface.hopper.perltitle"))
&& (hopper.getLevel().isTeleport() || player.hasPermission("EpicHoppers.Teleport"))) {
if (event.isLeftClick()) {
if (hopper.getSyncedBlock() != null) {
if (hopper.getLinkedBlocks() != null) {
instance.getTeleportHandler().tpPlayer(player, hopper);
}
} else {
@ -119,7 +119,7 @@ public class InventoryListeners implements Listener {
} else if (event.getCurrentItem().getItemMeta().getDisplayName().equals(instance.getLocale().getMessage("interface.hopper.synchopper"))) {
if (event.isRightClick()) {
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.desync"));
hopper.setSyncedBlock(null);
hopper.clearLinkedBlocks();
} else {
boolean can = true;
if (hopper.getLastPlayer() != null) {
@ -130,6 +130,7 @@ public class InventoryListeners implements Listener {
}
if (can) {
playerData.setSyncType(SyncType.REGULAR);
hopper.clearLinkedBlocks();
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.syncnext"));
((EHopper) hopper).timeout(player);
}

View File

@ -1,7 +1,9 @@
package com.songoda.epichoppers.storage;
import com.songoda.arconix.plugin.Arconix;
import com.songoda.epichoppers.utils.Serializers;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import java.util.*;
@ -31,6 +33,16 @@ public class StorageItem {
this.object = object.toString();
}
public StorageItem(String key, boolean type, List<Block> blocks) {
StringBuilder object = new StringBuilder();
for (Block block : blocks) {
object.append(Arconix.pl().getApi().serialize().serializeLocation(block));
object.append(";;");
}
this.key = key;
this.object = object.toString();
}
public String getKey() {
return key;
}
@ -65,4 +77,15 @@ public class StorageItem {
}
return list;
}
public List<String> asStringList() {
List<String> list = new ArrayList<>();
if (object == null) return list;
String obj = (String) object;
if (!((String) object).contains(";;")) {
list.add(obj);
return list;
}
return new ArrayList<>(Arrays.asList(obj.split(";;")));
}
}

View File

@ -94,7 +94,7 @@ public class StorageMysql extends Storage {
public void doSave() {
try {
// Clear database
database.getConnection().createStatement().execute("TRUNCATE `" + instance.getConfig().getString("Database.Prefix") + "sync`");
database.getConnection().createStatement().execute("TRUNCATE `" + instance.getConfig().getString("Database.Prefix") + "link`");
database.getConnection().createStatement().execute("TRUNCATE `" + instance.getConfig().getString("Database.Prefix") + "boosts`");
Statement stmt = database.getConnection().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);

View File

@ -22,7 +22,7 @@ public class MySQLDatabase {
//ToDo: This is sloppy
connection.createStatement().execute(
"CREATE TABLE IF NOT EXISTS `" + instance.getConfig().getString("Database.Prefix") + "sync` (\n" +
"CREATE TABLE IF NOT EXISTS `" + instance.getConfig().getString("Database.Prefix") + "link` (\n" +
"\t`location` TEXT NULL,\n" +
"\t`level` INT NULL,\n" +
"\t`block` TEXT NULL,\n" +

View File

@ -6,7 +6,7 @@ Upgrade-with-xp: 'Setting this to true will allow users to use Experience to upg
On-upgrade-particles: 'Setting this to true will cause particles to emit when a hopper is upgraded.'
Teleport-hoppers: 'These are the default levels, the amount of levels can be expanded if you want, just add another level to the bottom of the list while keeping numeric order. Allows you to enable or disable teleporting with hoppers'
Hop-Tick: 'This is the tick speed for synced hoppers.'
Sync-Timeout: 'This is the timeout that if reached will cancel a sync.'
Sync-Timeout: 'This is the timeout that if reached will cancel a link.'
Glass-Type: 'This is the id of the glass used for the background in the guis.'
Rainbow-Glass: 'If this is enabled the glass background will be randomized colors. '
Limit-Hoppers-Per-Chunk: 'If enabled this will limit the amount hoppers per chunk'

View File

@ -21,6 +21,7 @@ interface.hopper.teleport = "&7Teleport: &6%enabled%"
interface.hopper.filter = "&7Filter: &6%enabled%"
interface.hopper.crafting = "&7AutoCrafting: &6%enabled%"
interface.hopper.suction = "&7Suction: &6%suction%"
interface.hopper.linkamount = "&7Link Amount: &6%amount%"
interface.hopper.blockbreak = "&7Block Break: &6Every %ticks% ticks"
interface.hopper.alreadymaxed = "&7This hopper is already maxed out!"
interface.hopper.synclore = "|&7Left-Click then click a another|&7hopper or chest to link!||&7Right-Click to unlink."
@ -50,9 +51,12 @@ event.upgrade.success = "&7You successfully upgraded this hopper to &6level %lev
event.upgrade.maxed = "&7You maxed out this hopper at &6level %level%&7."
event.inventory.noroom = "&7You do not have space in your inventory for this."
event.hopper.syncsuccess = "&aLink Successful."
event.hopper.syncsuccessmore = "&7You have &6%amount% &7more link(s) left."
event.hopper.desync = "&7You have unlinked this hopper."
event.hopper.syncnext = "&7Click another hopper or container to link."
event.hopper.syncself = "&cYou can't link a hopper to itself."
event.hopper.syncdone = "&aYou have maxed out your links."
event.hopper.already = "&cThis hopper is already linked."
event.hopper.synctimeout = "&cLinking timed out."
event.hopper.syncoutofrange = "&cThis block is out of your hoppers range."
event.hopper.syncdidnotplace = "&cSorry! You need to have placed this hopper to link things to it."