Merge branch 'development' into 'master'

Mega Bug Fixes

See merge request Songoda/epichoppers!40
This commit is contained in:
Esophose 2019-06-04 10:48:34 +00:00
commit 99b4cf8c83
26 changed files with 753 additions and 498 deletions

View File

@ -97,6 +97,11 @@
<version>72</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>epicfarming</artifactId>
<version>2.2.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -38,6 +38,7 @@ import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
@ -74,6 +75,7 @@ public class EpicHoppers extends JavaPlugin {
private Storage storage;
private boolean liquidtanks = false;
private boolean epicfarming = false;
public static EpicHoppers getInstance() {
return INSTANCE;
@ -135,6 +137,9 @@ public class EpicHoppers extends JavaPlugin {
// Check for liquid tanks
if (pluginManager.isPluginEnabled("LiquidTanks")) liquidtanks = true;
// Check for epicfarming
if (pluginManager.isPluginEnabled("EpicFarming")) epicfarming = true;
// Start auto save
int saveInterval = Setting.AUTOSAVE.getInt() * 60 * 20;
Bukkit.getScheduler().runTaskTimerAsynchronously(this, this::saveToFile, saveInterval, saveInterval);
@ -303,7 +308,8 @@ public class EpicHoppers extends JavaPlugin {
}
private void loadLevelManager() {
saveResource("levels.yml", false);
if (!new File(this.getDataFolder(), "levels.yml").exists())
this.saveResource("levels.yml", false);
// Load an instance of LevelManager
levelManager = new LevelManager();
@ -404,4 +410,8 @@ public class EpicHoppers extends JavaPlugin {
return liquidtanks;
}
public boolean isEpicFarming() {
return epicfarming;
}
}

View File

@ -60,7 +60,7 @@ public class GUICrafting extends AbstractGUI {
@Override
protected void registerOnCloses() {
registerOnClose(((player, inventory) ->
hopper.setAutoCrafting(inventory.getItem(13))));
hopper.setAutoCrafting(player, inventory.getItem(13))));
}
}

View File

@ -156,59 +156,59 @@ public class GUIFilter extends AbstractGUI {
private void compile(Player p) {
ItemStack[] items = p.getOpenInventory().getTopInventory().getContents();
ItemStack[] items = p.getOpenInventory().getTopInventory().getContents();
Filter filter = hopper.getFilter();
Filter filter = hopper.getFilter();
List<ItemStack> owhite = new ArrayList<>();
List<ItemStack> oblack = new ArrayList<>();
List<ItemStack> ovoid = new ArrayList<>();
List<ItemStack> owhite = new ArrayList<>();
List<ItemStack> oblack = new ArrayList<>();
List<ItemStack> ovoid = new ArrayList<>();
int[] awhite = {9, 10, 18, 19, 27, 28, 36, 37};
int[] ablack = {11, 12, 20, 21, 29, 30, 38, 39};
int[] avoid = {13, 14, 22, 23, 31, 32, 40, 41};
int[] awhite = {9, 10, 18, 19, 27, 28, 36, 37};
int[] ablack = {11, 12, 20, 21, 29, 30, 38, 39};
int[] avoid = {13, 14, 22, 23, 31, 32, 40, 41};
for (int i = 0; i < items.length; i++) {
for (int aa : awhite) {
if (aa != i) continue;
if (items[i] != null && items[i].getType() != Material.AIR) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayer()).getInventory().addItem(item);
item.setAmount(1);
}
owhite.add(item);
}
}
for (int aa : ablack) {
if (aa != i) continue;
if (items[i] != null && items[i].getType() != Material.AIR) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayer()).getInventory().addItem(item);
item.setAmount(1);
}
oblack.add(item);
}
}
for (int aa : avoid) {
if (aa != i) continue;
if (items[i] != null && items[i].getType() != Material.AIR) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayer()).getInventory().addItem(item);
item.setAmount(1);
}
ovoid.add(item);
for (int i = 0; i < items.length; i++) {
for (int aa : awhite) {
if (aa != i) continue;
if (items[i] != null && items[i].getType() != Material.AIR) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayer()).getInventory().addItem(item);
item.setAmount(1);
}
owhite.add(item);
}
}
filter.setWhiteList(owhite);
filter.setBlackList(oblack);
filter.setVoidList(ovoid);
for (int aa : ablack) {
if (aa != i) continue;
if (items[i] != null && items[i].getType() != Material.AIR) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayer()).getInventory().addItem(item);
item.setAmount(1);
}
oblack.add(item);
}
}
for (int aa : avoid) {
if (aa != i) continue;
if (items[i] != null && items[i].getType() != Material.AIR) {
ItemStack item = items[i];
if (item.getAmount() != 1) {
item.setAmount(item.getAmount() - 1);
Bukkit.getPlayer(hopper.getLastPlayer()).getInventory().addItem(item);
item.setAmount(1);
}
ovoid.add(item);
}
}
}
filter.setWhiteList(owhite);
filter.setBlackList(oblack);
filter.setVoidList(ovoid);
}
@Override

View File

@ -104,35 +104,13 @@ public class GUIOverview extends AbstractGUI {
ItemMeta hookmeta = hook.getItemMeta();
hookmeta.setDisplayName(plugin.getLocale().getMessage("interface.hopper.synchopper"));
ArrayList<String> lorehook = new ArrayList<>();
parts = plugin.getLocale().getMessage("interface.hopper.synclore", hopper.getLinkedBlocks().size()).split("\\|");
parts = plugin.getLocale().getMessage("interface.hopper.synclore", hopper.getLinkedBlocks().stream().distinct().count()).split("\\|");
for (String line : parts) {
lorehook.add(Methods.formatText(line));
}
hookmeta.setLore(lorehook);
hook.setItemMeta(hookmeta);
ItemStack itemXP = new ItemStack(Material.valueOf(plugin.getConfig().getString("Interfaces.XP Icon")), 1);
ItemMeta itemmetaXP = itemXP.getItemMeta();
itemmetaXP.setDisplayName(plugin.getLocale().getMessage("interface.hopper.upgradewithxp"));
ArrayList<String> loreXP = new ArrayList<>();
if (nextLevel != null)
loreXP.add(plugin.getLocale().getMessage("interface.hopper.upgradewithxplore", nextLevel.getCostExperience()));
else
loreXP.add(plugin.getLocale().getMessage("interface.hopper.alreadymaxed"));
itemmetaXP.setLore(loreXP);
itemXP.setItemMeta(itemmetaXP);
ItemStack itemECO = new ItemStack(Material.valueOf(plugin.getConfig().getString("Interfaces.Economy Icon")), 1);
ItemMeta itemmetaECO = itemECO.getItemMeta();
itemmetaECO.setDisplayName(plugin.getLocale().getMessage("interface.hopper.upgradewitheconomy"));
ArrayList<String> loreECO = new ArrayList<>();
if (nextLevel != null)
loreECO.add(plugin.getLocale().getMessage("interface.hopper.upgradewitheconomylore", Methods.formatEconomy(nextLevel.getCostEconomy())));
else
loreECO.add(plugin.getLocale().getMessage("interface.hopper.alreadymaxed"));
itemmetaECO.setLore(loreECO);
itemECO.setItemMeta(itemmetaECO);
int nu = 0;
while (nu != 27) {
inventory.setItem(nu, Methods.getGlass());
@ -182,30 +160,54 @@ public class GUIOverview extends AbstractGUI {
}
}
if (plugin.getConfig().getBoolean("Main.Upgrade With XP")
&& player.hasPermission("EpicHoppers.Upgrade.XP")
&& level.getCostExperience() != -1) {
inventory.setItem(11, itemXP);
if (plugin.getConfig().getBoolean("Main.Allow hopper Upgrading")) {
ItemStack itemXP = new ItemStack(Material.valueOf(plugin.getConfig().getString("Interfaces.XP Icon")), 1);
ItemMeta itemmetaXP = itemXP.getItemMeta();
itemmetaXP.setDisplayName(plugin.getLocale().getMessage("interface.hopper.upgradewithxp"));
ArrayList<String> loreXP = new ArrayList<>();
if (nextLevel != null)
loreXP.add(plugin.getLocale().getMessage("interface.hopper.upgradewithxplore", nextLevel.getCostExperience()));
else
loreXP.add(plugin.getLocale().getMessage("interface.hopper.alreadymaxed"));
itemmetaXP.setLore(loreXP);
itemXP.setItemMeta(itemmetaXP);
registerClickable(11, ((player, inventory, cursor, slot, type) -> {
hopper.upgrade(player, CostType.EXPERIENCE);
this.hopper.overview(player);
}));
ItemStack itemECO = new ItemStack(Material.valueOf(plugin.getConfig().getString("Interfaces.Economy Icon")), 1);
ItemMeta itemmetaECO = itemECO.getItemMeta();
itemmetaECO.setDisplayName(plugin.getLocale().getMessage("interface.hopper.upgradewitheconomy"));
ArrayList<String> loreECO = new ArrayList<>();
if (nextLevel != null)
loreECO.add(plugin.getLocale().getMessage("interface.hopper.upgradewitheconomylore", Methods.formatEconomy(nextLevel.getCostEconomy())));
else
loreECO.add(plugin.getLocale().getMessage("interface.hopper.alreadymaxed"));
itemmetaECO.setLore(loreECO);
itemECO.setItemMeta(itemmetaECO);
if (plugin.getConfig().getBoolean("Main.Upgrade With XP")
&& player.hasPermission("EpicHoppers.Upgrade.XP")
&& level.getCostExperience() != -1) {
inventory.setItem(11, itemXP);
registerClickable(11, ((player, inventory, cursor, slot, type) -> {
hopper.upgrade(player, CostType.EXPERIENCE);
this.hopper.overview(player);
}));
}
if (plugin.getConfig().getBoolean("Main.Upgrade With Economy")
&& player.hasPermission("EpicHoppers.Upgrade.ECO")
&& level.getCostEconomy() != -1) {
inventory.setItem(15, itemECO);
registerClickable(15, ((player, inventory, cursor, slot, type) -> {
hopper.upgrade(player, CostType.ECONOMY);
this.hopper.overview(player);
}));
}
}
inventory.setItem(13, item);
if (plugin.getConfig().getBoolean("Main.Upgrade With Economy")
&& player.hasPermission("EpicHoppers.Upgrade.ECO")
&& level.getCostEconomy() != -1) {
inventory.setItem(15, itemECO);
registerClickable(15, ((player, inventory, cursor, slot, type) -> {
hopper.upgrade(player, CostType.ECONOMY);
this.hopper.overview(player);
}));
}
inventory.setItem(0, Methods.getBackgroundGlass(true));
inventory.setItem(1, Methods.getBackgroundGlass(true));
inventory.setItem(2, Methods.getBackgroundGlass(false));

View File

@ -14,7 +14,6 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.InventoryHolder;
import java.util.Date;
import java.util.HashMap;
@ -23,71 +22,75 @@ import java.util.UUID;
public class TeleportHandler {
//Teleport from - teleport 2
private final Map<Location, Location> teleportFrom = new HashMap<>();
private final Map<UUID, Long> lastTeleports = new HashMap<>();
private EpicHoppers instance;
public TeleportHandler(EpicHoppers instance) {
this.instance = instance;
Bukkit.getScheduler().scheduleSyncRepeatingTask(instance, this::teleportRunner, 0, instance.getConfig().getLong("Main.Amount of Ticks Between Teleport"));
this.instance = instance;
Bukkit.getScheduler().scheduleSyncRepeatingTask(instance, this::teleportRunner, 0, instance.getConfig().getLong("Main.Amount of Ticks Between Teleport"));
}
private void teleportRunner() {
for (World world : Bukkit.getWorlds()) {
for (Entity entity : world.getEntities()) {
if (!(entity instanceof LivingEntity) ||entity.getType() == EntityType.ARMOR_STAND) continue;
if (!instance.getConfig().getBoolean("Main.Allow Players To Teleport Through Hoppers")
|| entity instanceof Player && !((Player)entity).hasPermission("EpicHoppers.Teleport")) {
if (!(entity instanceof LivingEntity) || entity.getType() == EntityType.ARMOR_STAND)
continue;
if (!this.instance.getConfig().getBoolean("Main.Allow Players To Teleport Through Hoppers")
|| (entity instanceof Player && !entity.hasPermission("EpicHoppers.Teleport")))
continue;
}
Location location = entity.getLocation().getBlock().getRelative(BlockFace.DOWN).getLocation();
if (!instance.getHopperManager().isHopper(location)) {
if (!this.instance.getHopperManager().isHopper(location))
continue;
}
Hopper hopper = instance.getHopperManager().getHopper(location);
Hopper hopper = this.instance.getHopperManager().getHopper(location);
if (hopper.getTeleportTrigger() != TeleportTrigger.WALK_ON) continue;
if (hopper.getTeleportTrigger() != TeleportTrigger.WALK_ON)
continue;
if (lastTeleports.containsKey(entity.getUniqueId())) {
long duration = (new Date()).getTime() - new Date(lastTeleports.get(entity.getUniqueId())).getTime();
if (duration <= 5 * 1000) {
if (this.lastTeleports.containsKey(entity.getUniqueId())) {
long duration = (new Date()).getTime() - new Date(this.lastTeleports.get(entity.getUniqueId())).getTime();
if (duration <= 5 * 1000)
continue;
}
}
tpEntity(entity, hopper);
lastTeleports.put(entity.getUniqueId(), System.currentTimeMillis());
this.tpEntity(entity, hopper);
this.lastTeleports.put(entity.getUniqueId(), System.currentTimeMillis());
}
}
}
public void tpEntity(Entity entity, Hopper hopper) {
if (hopper == null || !instance.getHopperManager().isHopper(hopper.getLocation())) return;
if (hopper == null || !this.instance.getHopperManager().isHopper(hopper.getLocation()))
return;
EpicHoppers instance = EpicHoppers.getInstance();
Hopper lastHopper = hopper;
for (int i = 0; i < 15; i++) {
boolean empty = lastHopper.getLinkedBlocks().isEmpty();
if (empty && i == 0) {
if (teleportFrom.containsKey(hopper.getLocation()))
doTeleport(entity, teleportFrom.get(hopper.getLocation()).clone());
return;
}
Hopper lastHopper = this.getChain(hopper, 1);
if (hopper != lastHopper)
this.doTeleport(entity, lastHopper.getLocation());
}
if (empty) break;
Location nextHopper = lastHopper.getLinkedBlocks().get(0);
if (!(nextHopper.getBlock().getState() instanceof InventoryHolder)) break;
lastHopper = instance.getHopperManager().getHopper(nextHopper);
/**
* Recursively gets the next hopper in the linked hopper chain
* @param lastHopper The previous hopper found in the chain
* @param currentChainLength The current length of the chain, used to cap the search length
* @return The hopper at the end of the chain (or up to 15 in depth)
*/
private Hopper getChain(Hopper lastHopper, int currentChainLength) {
if (currentChainLength > 15)
return lastHopper;
for (Location nextHopperLocation : lastHopper.getLinkedBlocks()) {
if (nextHopperLocation.getBlock().getState() instanceof org.bukkit.block.Hopper) {
Hopper hopper = this.instance.getHopperManager().getHopper(nextHopperLocation);
if (hopper != null)
return this.getChain(hopper, currentChainLength + 1);
}
}
teleportFrom.put(lastHopper.getLocation(), hopper.getLocation());
doTeleport(entity, lastHopper.getLocation());
return lastHopper;
}
private void doTeleport(Entity entity, Location location) {
@ -95,14 +98,14 @@ public class TeleportHandler {
location.setPitch(entity.getLocation().getPitch());
location.setDirection(entity.getLocation().getDirection());
if (instance.isServerVersionAtLeast(ServerVersion.V1_12)) {
if (this.instance.isServerVersionAtLeast(ServerVersion.V1_12)) {
Methods.doParticles(entity, location);
Methods.doParticles(entity, entity.getLocation().getBlock().getRelative(BlockFace.DOWN).getLocation());
}
entity.teleport(location);
if (instance.isServerVersionAtLeast(ServerVersion.V1_12))
if (this.instance.isServerVersionAtLeast(ServerVersion.V1_12))
entity.getWorld().playSound(entity.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 10, 10);
}
}

View File

@ -8,7 +8,11 @@ import com.songoda.epichoppers.utils.CostType;
import com.songoda.epichoppers.utils.Methods;
import com.songoda.epichoppers.utils.ServerVersion;
import com.songoda.epichoppers.utils.TeleportTrigger;
import org.bukkit.*;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@ -53,16 +57,16 @@ public class Hopper {
}
public void overview(Player player) {
if (lastPlayer != null
&& lastPlayer != player.getUniqueId()
&& Bukkit.getPlayer(lastPlayer) != null) {
Bukkit.getPlayer(lastPlayer).closeInventory();
}
if (placedBy == null) placedBy = player.getUniqueId();
if (lastPlayer != null
&& lastPlayer != player.getUniqueId()
&& Bukkit.getPlayer(lastPlayer) != null) {
Bukkit.getPlayer(lastPlayer).closeInventory();
}
if (placedBy == null) placedBy = player.getUniqueId();
EpicHoppers instance = EpicHoppers.getInstance();
if (!player.hasPermission("epichoppers.overview")) return;
new GUIOverview(instance, this, player);
if (!player.hasPermission("epichoppers.overview")) return;
new GUIOverview(instance, this, player);
}
public void upgrade(Player player, CostType type) {
@ -70,118 +74,119 @@ public class Hopper {
if (plugin.getLevelManager().getLevels().containsKey(this.level.getLevel() + 1)) {
Level level = plugin.getLevelManager().getLevel(this.level.getLevel() + 1);
int cost = type == CostType.ECONOMY ? level.getCostEconomy() : level.getCostExperience();
int cost = type == CostType.ECONOMY ? level.getCostEconomy() : level.getCostExperience();
if (type == CostType.ECONOMY) {
if (plugin.getEconomy() == null) {
player.sendMessage("Economy not enabled.");
return;
if (type == CostType.ECONOMY) {
if (plugin.getEconomy() == null) {
player.sendMessage("Economy not enabled.");
return;
}
if (!plugin.getEconomy().hasBalance(player, cost)) {
player.sendMessage(plugin.references.getPrefix() + plugin.getInstance().getLocale().getMessage("event.upgrade.cannotafford"));
return;
}
plugin.getEconomy().withdrawBalance(player, cost);
upgradeFinal(level, player);
} else if (type == CostType.EXPERIENCE) {
if (player.getLevel() >= cost || player.getGameMode() == GameMode.CREATIVE) {
if (player.getGameMode() != GameMode.CREATIVE) {
player.setLevel(player.getLevel() - cost);
}
if (!plugin.getEconomy().hasBalance(player, cost)) {
player.sendMessage(plugin.references.getPrefix() + plugin.getInstance().getLocale().getMessage("event.upgrade.cannotafford"));
return;
}
plugin.getEconomy().withdrawBalance(player, cost);
upgradeFinal(level, player);
} else if (type == CostType.EXPERIENCE) {
if (player.getLevel() >= cost || player.getGameMode() == GameMode.CREATIVE) {
if (player.getGameMode() != GameMode.CREATIVE) {
player.setLevel(player.getLevel() - cost);
}
upgradeFinal(level, player);
} else {
player.sendMessage(plugin.references.getPrefix() + plugin.getLocale().getMessage("event.upgrade.cannotafford"));
}
} else {
player.sendMessage(plugin.references.getPrefix() + plugin.getLocale().getMessage("event.upgrade.cannotafford"));
}
}
}
}
private void upgradeFinal(Level level, Player player) {
EpicHoppers instance = EpicHoppers.getInstance();
this.level = level;
syncName();
if (instance.getLevelManager().getHighestLevel() != level) {
player.sendMessage(instance.getLocale().getMessage("event.upgrade.success", level.getLevel()));
} else {
player.sendMessage(instance.getLocale().getMessage("event.upgrade.maxed", level.getLevel()));
}
Location loc = location.clone().add(.5, .5, .5);
this.level = level;
syncName();
if (instance.getLevelManager().getHighestLevel() != level) {
player.sendMessage(instance.getLocale().getMessage("event.upgrade.success", level.getLevel()));
} else {
player.sendMessage(instance.getLocale().getMessage("event.upgrade.maxed", level.getLevel()));
}
Location loc = location.clone().add(.5, .5, .5);
if (!instance.isServerVersionAtLeast(ServerVersion.V1_12)) return;
if (!instance.isServerVersionAtLeast(ServerVersion.V1_12)) return;
player.getWorld().spawnParticle(org.bukkit.Particle.valueOf(instance.getConfig().getString("Main.Upgrade Particle Type")), loc, 200, .5, .5, .5);
player.getWorld().spawnParticle(org.bukkit.Particle.valueOf(instance.getConfig().getString("Main.Upgrade Particle Type")), loc, 200, .5, .5, .5);
if (instance.getLevelManager().getHighestLevel() != level) {
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.6F, 15.0F);
} else {
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2F, 25.0F);
if (instance.getLevelManager().getHighestLevel() != level) {
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.6F, 15.0F);
} else {
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2F, 25.0F);
if (!instance.isServerVersionAtLeast(ServerVersion.V1_13)) return;
if (!instance.isServerVersionAtLeast(ServerVersion.V1_13)) return;
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 2F, 25.0F);
Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1.2F, 35.0F), 5L);
Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1.8F, 35.0F), 10L);
}
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 2F, 25.0F);
Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1.2F, 35.0F), 5L);
Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1.8F, 35.0F), 10L);
}
}
private void syncName() {
org.bukkit.block.Hopper hopper = (org.bukkit.block.Hopper)location.getBlock().getState();
org.bukkit.block.Hopper hopper = (org.bukkit.block.Hopper) location.getBlock().getState();
if (EpicHoppers.getInstance().isServerVersionAtLeast(ServerVersion.V1_10))
hopper.setCustomName(Methods.formatName(level.getLevel(), false));
hopper.update(true);
hopper.update(true);
}
public void timeout(Player player) {
EpicHoppers instance = EpicHoppers.getInstance();
Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> {
PlayerData playerData = instance.getPlayerDataManager().getPlayerData(player);
if (playerData.getSyncType() != null) {
player.sendMessage(instance.getLocale().getMessage("event.hopper.synctimeout"));
playerData.setSyncType(null);
}
}, instance.getConfig().getLong("Main.Timeout When Syncing Hoppers"));
Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> {
PlayerData playerData = instance.getPlayerDataManager().getPlayerData(player);
if (playerData.getSyncType() != null) {
player.sendMessage(instance.getLocale().getMessage("event.hopper.synctimeout"));
playerData.setSyncType(null);
}
}, instance.getConfig().getLong("Main.Timeout When Syncing Hoppers"));
}
public void link(Block toLink, boolean filtered, Player player) {
EpicHoppers instance = EpicHoppers.getInstance();
if (location.getWorld().equals(toLink.getLocation().getWorld())
&& !player.hasPermission("EpicHoppers.Override")
&& !player.hasPermission("EpicHoppers.Admin")
&& location.distance(toLink.getLocation()) > level.getRange()) {
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.syncoutofrange"));
return;
}
if (location.getWorld().equals(toLink.getLocation().getWorld())
&& !player.hasPermission("EpicHoppers.Override")
&& !player.hasPermission("EpicHoppers.Admin")
&& 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;
}
if (linkedBlocks.contains(toLink)) {
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.already"));
return;
}
if (!filtered)
this.linkedBlocks.add(toLink.getLocation());
else {
this.filter.setEndPoint(toLink.getLocation());
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.syncsuccess"));
instance.getPlayerDataManager().getPlayerData(player).setSyncType(null);
return;
}
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;
}
if (!filtered)
this.linkedBlocks.add(toLink.getLocation());
else {
this.filter.setEndPoint(toLink.getLocation());
player.sendMessage(instance.references.getPrefix() + instance.getLocale().getMessage("event.hopper.syncsuccess"));
instance.getPlayerDataManager().getPlayerData(player).setSyncType(null);
return;
}
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"));
instance.getPlayerDataManager().getPlayerData(player).setSyncType(null);
}
/**
* Ticks a hopper to determine when it can transfer items next
*
* @param maxTick The maximum amount the hopper can be ticked before next transferring items
* @param allowLooping If true, the hopper is allowed to transfer items if the tick is also valid
* @return true if the hopper should transfer an item, otherwise false
@ -239,10 +244,17 @@ public class Hopper {
return autoCrafting;
}
public void setAutoCrafting(ItemStack autoCrafting) {
public void setAutoCrafting(Player player, ItemStack autoCrafting) {
this.autoCrafting = autoCrafting;
if (autoCrafting != null)
if (autoCrafting != null) {
int excess = autoCrafting.getAmount() - 1;
autoCrafting.setAmount(1);
if (excess > 0 && player != null) {
ItemStack item = autoCrafting.clone();
item.setAmount(excess);
player.getInventory().addItem(item);
}
}
}
public TeleportTrigger getTeleportTrigger() {

View File

@ -20,9 +20,18 @@ public class HopperManager {
registeredHoppers.put(roundLocation(location), hopper);
}
/**
* Removes a hopper and unlinks it from any other hoppers
* @param location The location of the hopper to remove
* @return The removed hopper, or null if none was removed
*/
public Hopper removeHopper(Location location) {
return registeredHoppers.remove(location);
Hopper removed = this.registeredHoppers.remove(location);
for (Hopper hopper : this.registeredHoppers.values())
hopper.removeLinkedBlock(location);
return removed;
}

View File

@ -21,7 +21,7 @@ public class LevelManager {
}
public Level getLevel(ItemStack item) {
if (item.getItemMeta().getDisplayName().contains(":")) {
if (item.hasItemMeta() && item.getItemMeta().getDisplayName().contains(":")) {
String arr[] = item.getItemMeta().getDisplayName().replace(String.valueOf(ChatColor.COLOR_CHAR), "").split(":");
return getLevel(Integer.parseInt(arr[0]));
} else {

View File

@ -8,7 +8,11 @@ import com.songoda.epichoppers.utils.ServerVersion;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.*;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
@ -19,22 +23,6 @@ import java.util.Map;
public class ModuleAutoCrafting implements Module {
private final Map<ItemStack, Recipes> cachedRecipes = new HashMap<>();
private final Map<Hopper, ItemStack> lastMaterial = new HashMap<>();
public static List<ItemStack> compressItemStack(List<ItemStack> target) {
HashMap<Material, ItemStack> sortingList = new HashMap<>();
for (ItemStack item : target) {
if (sortingList.containsKey(item.getType())) {
ItemStack existing = sortingList.get(item.getType());
existing.setAmount(existing.getAmount() + item.getAmount());
sortingList.put(existing.getType(), existing);
} else {
sortingList.put(item.getType(), item);
}
}
List<ItemStack> list = new ArrayList<>(sortingList.values());
return list;
}
@Override
public String getName() {
@ -42,61 +30,69 @@ public class ModuleAutoCrafting implements Module {
}
public void run(Hopper hopper, Inventory hopperInventory) {
if (hopper.getAutoCrafting() == null || hopperInventory == null) return;
if (hopper.getAutoCrafting() == null
|| hopperInventory == null
|| hopperInventory.getSize() == 0
|| !canMove(hopperInventory, new ItemStack(hopper.getAutoCrafting()))
|| cachedRecipes.get(hopper.getAutoCrafting()) == null)
return;
if (hopper.getAutoCrafting() != null && canMove(hopperInventory, new ItemStack(hopper.getAutoCrafting()))) {
if (cachedRecipes.get(hopper.getAutoCrafting()) == null) return;
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;
Map<Material, ItemStack> items = new HashMap<>();
for (ItemStack item : ingredientMap) {
if (item == null) continue;
if (!items.containsKey(item.getType())) {
items.put(item.getType(), item.clone());
} else {
items.get(item.getType()).setAmount(items.get(item.getType()).getAmount() + 1);
}
}
for (ItemStack item : items.values()) {
int amt = 0;
for (ItemStack i : hopperInventory.getContents()) {
if (i == null) continue;
if (!i.isSimilar(item)) continue;
amt += i.getAmount();
}
if (amt < item.getAmount()) {
continue top;
}
}
main2:
for (ItemStack toRemove : items.values()) {
int amtRemoved = 0;
for (ItemStack i : hopperInventory.getContents()) {
if (i == null || !i.isSimilar(toRemove)) 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());
top:
for (Recipe recipe : cachedRecipes.get(hopper.getAutoCrafting()).getRecipes()) {
if (!(recipe instanceof ShapedRecipe) && !(recipe instanceof ShapelessRecipe))
continue;
List<ItemStack> ingredientMap;
if (recipe instanceof ShapelessRecipe) {
ingredientMap = ((ShapelessRecipe) recipe).getIngredientList();
} else {
ingredientMap = new ArrayList<>(((ShapedRecipe) recipe).getIngredientMap().values());
}
Map<Material, ItemStack> items = new HashMap<>();
for (ItemStack item : ingredientMap) {
if (item == null)
continue;
if (!items.containsKey(item.getType())) {
items.put(item.getType(), item.clone());
} else {
items.get(item.getType()).setAmount(items.get(item.getType()).getAmount() + 1);
}
}
for (ItemStack item : items.values()) {
int amt = 0;
for (ItemStack i : hopperInventory.getContents()) {
if (i == null || !isSimilar(i, item))
continue;
amt += i.getAmount();
}
if (amt < item.getAmount()) {
continue top;
}
}
main2:
for (ItemStack toRemove : items.values()) {
int amtRemoved = 0;
for (ItemStack i : hopperInventory.getContents()) {
if (i == null || !isSimilar(i, toRemove))
continue;
amtRemoved += Math.min(toRemove.getAmount() - amtRemoved, i.getAmount());
if (amtRemoved == i.getAmount())
hopperInventory.removeItem(i);
else
i.setAmount(i.getAmount() - amtRemoved);
if (amtRemoved == toRemove.getAmount())
continue main2;
}
}
hopperInventory.addItem(recipe.getResult());
}
}
@ -126,30 +122,30 @@ public class ModuleAutoCrafting implements Module {
ItemStack itemStack = hopper.getAutoCrafting();
if (itemStack.getType() == Material.AIR) return materials;
if (itemStack.getType() == Material.AIR)
return materials;
if (lastMaterial.get(hopper) != null && !lastMaterial.get(hopper).isSimilar(itemStack)) {
lastMaterial.put(hopper, itemStack);
cachedRecipes.remove(hopper);
}
if (cachedRecipes.keySet().stream().noneMatch(itemStack1 -> itemStack1.isSimilar(itemStack))) {
if (cachedRecipes.get(itemStack) == null) {
Recipes recipes = new Recipes();
for (Recipe recipe : Bukkit.getServer().getRecipesFor(itemStack)) {
recipes.addRecipe(recipe);
}
cachedRecipes.put(itemStack, recipes);
} else {
}
if (cachedRecipes.get(itemStack) != null) {
Recipes recipes = cachedRecipes.get(itemStack);
for (Recipe recipe : recipes.getRecipes()) {
if (recipe instanceof ShapedRecipe) {
for (ItemStack itemStack1 : ((ShapedRecipe) recipe).getIngredientMap().values()) {
if (itemStack1 == null) continue;
if (itemStack1 == null)
continue;
materials.add(itemStack1.getType());
}
} else if (recipe instanceof ShapelessRecipe) {
for (ItemStack itemStack1 : ((ShapelessRecipe) recipe).getIngredientList()) {
if (itemStack1 == null) continue;
if (itemStack1 == null)
continue;
materials.add(itemStack1.getType());
}
}
@ -165,16 +161,24 @@ public class ModuleAutoCrafting implements Module {
}
private boolean canMove(Inventory inventory, ItemStack item) {
if (inventory.firstEmpty() != -1) return true;
if (inventory.firstEmpty() != -1) return true;
for (ItemStack stack : inventory.getContents()) {
if (stack.isSimilar(item) && (stack.getAmount() + item.getAmount()) < stack.getMaxStackSize()) {
return true;
}
for (ItemStack stack : inventory.getContents()) {
if (stack.isSimilar(item) && (stack.getAmount() + item.getAmount()) < stack.getMaxStackSize()) {
return true;
}
}
return false;
}
private boolean isSimilar(ItemStack is1, ItemStack is2) {
if (EpicHoppers.getInstance().isServerVersionAtLeast(ServerVersion.V1_13)) {
return is1.getType() == is2.getType();
} else {
return is1.getType() == is2.getType() && is1.getDurability() == is2.getDurability();
}
}
class Recipes {
private List<Recipe> recipes = new ArrayList<>();

View File

@ -2,6 +2,7 @@ package com.songoda.epichoppers.hopper.levels.modules;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.tasks.HopTask;
import com.songoda.epichoppers.utils.Methods;
import com.songoda.epichoppers.utils.ServerVersion;
import org.bukkit.Bukkit;
@ -41,6 +42,8 @@ public class ModuleAutoSell implements Module {
if (instance.getEconomy() == null) return;
boolean updateComparators = false;
List<String> list = instance.getConfig().getStringList("Main.AutoSell Prices");
for (String line : list) {
@ -55,11 +58,16 @@ public class ModuleAutoSell implements Module {
instance.getEconomy().deposit(Bukkit.getOfflinePlayer(hopper.getPlacedBy()), price * itemStack.getAmount());
hopperInventory.removeItem(itemStack);
updateComparators = true;
}
} catch (Exception ignored) {
}
}
hopper.setAutoSellTimer(timeOut);
if (updateComparators)
HopTask.updateAdjacentComparators(hopper.getLocation());
}
hopper.setAutoSellTimer(hopper.getAutoSellTimer() - hopperTickRate);
}

View File

@ -11,6 +11,7 @@ import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@ -37,7 +38,8 @@ public class ModuleBlockBreak implements Module {
public void run(Hopper hopper, Inventory hopperInventory) {
Block block = hopper.getLocation().getBlock();
if (!hopper.isAutoBreaking()) return;
if (!hopper.isAutoBreaking())
return;
if (!blockTick.containsKey(block)) {
blockTick.put(block, 1);
@ -46,11 +48,21 @@ public class ModuleBlockBreak implements Module {
int tick = blockTick.get(block);
int put = tick + 1;
blockTick.put(block, put);
if (tick < amount) return;
Block above = block.getRelative(0, 1, 0);
if (above.getType() == Material.WATER || above.getType() == Material.LAVA) return;
if (tick < amount)
return;
if (above.getType() != Material.AIR && above.getType() != Material.HOPPER && !EpicHoppers.getInstance().getConfig().getStringList("Main.BlockBreak Blacklisted Blocks").contains(above.getType().name())) {
Block above = block.getRelative(0, 1, 0);
if (above.getType() == Material.WATER
|| above.getType() == Material.LAVA
|| above.getType() == Material.AIR
|| above.getState() instanceof InventoryHolder)
return;
// Don't break farm items from EpicFarming
if (EpicHoppers.getInstance().isEpicFarming() && com.songoda.epicfarming.EpicFarmingPlugin.getInstance().getFarmManager().getFarm(above) != null)
return;
if (!EpicHoppers.getInstance().getConfig().getStringList("Main.BlockBreak Blacklisted Blocks").contains(above.getType().name())) {
if (EpicHoppers.getInstance().isServerVersionAtLeast(ServerVersion.V1_9))
above.getWorld().playSound(above.getLocation(), Sound.BLOCK_STONE_BREAK, 1F, 1F);
Location locationAbove = above.getLocation();
@ -62,7 +74,17 @@ public class ModuleBlockBreak implements Module {
if (EpicHoppers.getInstance().isServerVersionAtLeast(ServerVersion.V1_9))
above.getWorld().spawnParticle(Particle.valueOf(EpicHoppers.getInstance().getConfig().getString("Main.BlockBreak Particle Type")), locationAbove, 15, xx, yy, zz);
boolean waterlogged = false;
if (EpicHoppers.getInstance().isServerVersionAtLeast(ServerVersion.V1_13)
&& above.getBlockData() instanceof org.bukkit.block.data.Waterlogged
&& ((org.bukkit.block.data.Waterlogged)above.getBlockData()).isWaterlogged()) {
waterlogged = true;
}
above.breakNaturally();
if (waterlogged)
above.setType(Material.WATER);
}
blockTick.remove(block);
}

View File

@ -14,7 +14,6 @@ import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@ -29,6 +28,7 @@ public class ModuleSuction implements Module {
public static List<UUID> blacklist = new ArrayList<>();
private boolean wildStacker = Bukkit.getPluginManager().isPluginEnabled("WildStacker");
private boolean ultimateStacker = Bukkit.getPluginManager().isPluginEnabled("UltimateStacker");
private Class<?> clazzItemStack, clazzItem, clazzCraftItemStack;
private Method methodGetItem, methodAsNMSCopy;
@ -63,7 +63,7 @@ public class ModuleSuction implements Module {
hopper.getLocation().getWorld().getNearbyEntities(hopper.getLocation().add(0.5, 0.5, 0.5), radius, radius, radius).stream()
.filter(entity -> entity.getType() == EntityType.DROPPED_ITEM
&& entity.getTicksLived() > 10
&& entity.getTicksLived() >= ((Item)entity).getPickupDelay()
&& entity.getLocation().getBlock().getType() != Material.HOPPER).forEach(entity -> {
Item item = (Item) entity;
@ -80,6 +80,9 @@ public class ModuleSuction implements Module {
if (wildStacker)
itemStack.setAmount(WildStackerAPI.getItemAmount((Item) entity));
if (ultimateStacker && item.hasMetadata("US_AMT"))
itemStack.setAmount(item.getMetadata("US_AMT").get(0).asInt());
if (!canMove(hopperInventory, itemStack) || blacklist.contains(item.getUniqueId()))
return;
@ -90,7 +93,7 @@ public class ModuleSuction implements Module {
float zz = (float) (0 + (Math.random() * .1));
if (EpicHoppers.getInstance().isServerVersionAtLeast(ServerVersion.V1_9))
entity.getLocation().getWorld().spawnParticle(Particle.FLAME, entity.getLocation(), 5, xx, yy, zz, 0);
entity.getLocation().getWorld().spawnParticle(Particle.FLAME, entity.getLocation(), 5, xx, yy, zz, 0);
for (ItemStack is : hopperInventory.addItem(itemStack).values()) {
entity.getWorld().dropItemNaturally(entity.getLocation(), is);

View File

@ -39,28 +39,27 @@ public class BlockListeners implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent e) {
Player player = e.getPlayer();
Player player = e.getPlayer();
if (e.getBlock().getType() != Material.HOPPER) return;
if (e.getBlock().getType() != Material.HOPPER)
return;
if (instance.isLiquidtanks() && net.arcaniax.liquidtanks.object.LiquidTankAPI.isLiquidTank(e.getBlock().getLocation()))
return;
if (instance.isLiquidtanks() && net.arcaniax.liquidtanks.object.LiquidTankAPI.isLiquidTank(e.getBlock().getLocation()))
return;
int amt = count(e.getBlock().getChunk());
int amt = count(e.getBlock().getChunk());
int max = maxHoppers(player);
int max = maxHoppers(player);
if (max != -1 && amt > max) {
player.sendMessage(instance.getLocale().getMessage("event.hopper.toomany", max));
e.setCancelled(true);
return;
}
if (max != -1 && amt > max) {
player.sendMessage(instance.getLocale().getMessage("event.hopper.toomany", max));
e.setCancelled(true);
return;
}
if (!e.getItemInHand().getItemMeta().hasDisplayName()) return;
ItemStack item = e.getItemInHand().clone();
ItemStack item = e.getItemInHand().clone();
instance.getHopperManager().addHopper(e.getBlock().getLocation(), new Hopper(e.getBlock(), instance.getLevelManager().getLevel(item), player.getUniqueId(), player.getUniqueId(), new ArrayList<>(), new Filter(), TeleportTrigger.DISABLED, null));
instance.getHopperManager().addHopper(e.getBlock().getLocation(), new Hopper(e.getBlock(), instance.getLevelManager().getLevel(item), player.getUniqueId(), player.getUniqueId(), new ArrayList<>(), new Filter(), TeleportTrigger.DISABLED, null));
}
private int maxHoppers(Player player) {
@ -74,57 +73,57 @@ public class BlockListeners implements Listener {
}
private int count(Chunk c) {
int count = 0;
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = 0; y < c.getWorld().getMaxHeight(); y++) {
if (c.getBlock(x, y, z).getType() == Material.HOPPER) count++;
}
int count = 0;
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = 0; y < c.getWorld().getMaxHeight(); y++) {
if (c.getBlock(x, y, z).getType() == Material.HOPPER) count++;
}
}
return count;
}
return count;
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) {
Block block = event.getBlock();
Player player = event.getPlayer();
Block block = event.getBlock();
Player player = event.getPlayer();
handleSyncTouch(event);
handleSyncTouch(event);
if (event.getBlock().getType() != Material.HOPPER) return;
if (event.getBlock().getType() != Material.HOPPER) return;
if (instance.isLiquidtanks() && net.arcaniax.liquidtanks.object.LiquidTankAPI.isLiquidTank(block.getLocation()))
return;
if (instance.isLiquidtanks() && net.arcaniax.liquidtanks.object.LiquidTankAPI.isLiquidTank(block.getLocation()))
return;
Hopper hopper = instance.getHopperManager().getHopper(block);
Hopper hopper = instance.getHopperManager().getHopper(block);
Level level = hopper.getLevel();
Level level = hopper.getLevel();
if (level.getLevel() > 1) {
event.setCancelled(true);
ItemStack item = instance.newHopperItem(level);
if (level.getLevel() > 1) {
event.setCancelled(true);
ItemStack item = instance.newHopperItem(level);
event.getBlock().setType(Material.AIR);
event.getBlock().getLocation().getWorld().dropItemNaturally(event.getBlock().getLocation(), item);
}
event.getBlock().setType(Material.AIR);
event.getBlock().getLocation().getWorld().dropItemNaturally(event.getBlock().getLocation(), item);
}
for (ItemStack m : hopper.getFilter().getWhiteList()) {
if (m != null)
event.getBlock().getLocation().getWorld().dropItemNaturally(event.getBlock().getLocation(), m);
}
for (ItemStack m : hopper.getFilter().getWhiteList()) {
if (m != null)
event.getBlock().getLocation().getWorld().dropItemNaturally(event.getBlock().getLocation(), m);
}
for (ItemStack m : hopper.getFilter().getBlackList()) {
if (m != null)
event.getBlock().getLocation().getWorld().dropItemNaturally(event.getBlock().getLocation(), m);
}
for (ItemStack m : hopper.getFilter().getVoidList()) {
if (m != null)
event.getBlock().getLocation().getWorld().dropItemNaturally(event.getBlock().getLocation(), m);
}
instance.getHopperManager().removeHopper(block.getLocation());
for (ItemStack m : hopper.getFilter().getBlackList()) {
if (m != null)
event.getBlock().getLocation().getWorld().dropItemNaturally(event.getBlock().getLocation(), m);
}
for (ItemStack m : hopper.getFilter().getVoidList()) {
if (m != null)
event.getBlock().getLocation().getWorld().dropItemNaturally(event.getBlock().getLocation(), m);
}
instance.getHopperManager().removeHopper(block.getLocation());
instance.getPlayerDataManager().getPlayerData(player).setSyncType(null);
instance.getPlayerDataManager().getPlayerData(player).setSyncType(null);
}
private void handleSyncTouch(BlockBreakEvent event) {

View File

@ -2,11 +2,15 @@ package com.songoda.epichoppers.listeners;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.hopper.Hopper;
import com.songoda.epichoppers.utils.HopperDirection;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest;
import org.bukkit.block.ShulkerBox;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.minecart.HopperMinecart;
import org.bukkit.entity.minecart.StorageMinecart;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
@ -29,7 +33,17 @@ public class HopperListeners implements Listener {
Inventory source = event.getSource();
Inventory destination = event.getDestination();
if (!(source.getHolder() instanceof org.bukkit.block.Hopper)) return;
// Hopper minecarts should be able to take care of themselves
// Let EpicHoppers take over if the hopper is pointing down though
if (destination.getHolder() instanceof HopperMinecart && (!(source.getHolder() instanceof org.bukkit.block.Hopper)
|| HopperDirection.getDirection(((org.bukkit.block.Hopper)destination.getHolder()).getRawData()) != HopperDirection.DOWN))
return;
// Shulker boxes have a mind of their own and relentlessly steal items from hoppers
if (destination.getHolder() instanceof ShulkerBox || !(source.getHolder() instanceof org.bukkit.block.Hopper)) {
event.setCancelled(true);
return;
}
if (instance.isLiquidtanks() && net.arcaniax.liquidtanks.object.LiquidTankAPI.isLiquidTank(event.getDestination().getLocation()))
return;
@ -47,7 +61,8 @@ public class HopperListeners implements Listener {
return;
}
if (!(destinationLocation.getBlock().getState() instanceof InventoryHolder)) return;
if (!(destinationLocation.getBlock().getState() instanceof InventoryHolder))
return;
Hopper hopper = instance.getHopperManager().getHopper(sourceHopper.getLocation());
@ -55,6 +70,5 @@ public class HopperListeners implements Listener {
hopper.addLinkedBlock(destinationLocation);
event.setCancelled(true);
}
}

View File

@ -50,58 +50,57 @@ public class InteractListeners implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockInteract(PlayerInteractEvent e) {
Player player = e.getPlayer();
if (e.getAction() != Action.LEFT_CLICK_BLOCK
|| e.getClickedBlock() == null
|| player.isSneaking()
|| !player.hasPermission("EpicHoppers.overview")
|| !(e.getClickedBlock().getState() instanceof InventoryHolder || e.getClickedBlock().getType().equals(Material.ENDER_CHEST))) {
return;
Player player = e.getPlayer();
if (e.getAction() != Action.LEFT_CLICK_BLOCK
|| e.getClickedBlock() == null
|| player.isSneaking()
|| !player.hasPermission("EpicHoppers.overview")
|| !(e.getClickedBlock().getState() instanceof InventoryHolder || e.getClickedBlock().getType().equals(Material.ENDER_CHEST))) {
return;
}
if (e.getClickedBlock().getType() == Material.CHEST && Methods.isSync(player)) {
ItemStack item = e.getPlayer().getInventory().getItemInHand();
if (item.getItemMeta().getLore().size() == 2) {
player.sendMessage(instance.getLocale().getMessage("event.hopper.desyncchest", item.getType().toString()));
instance.enchantmentHandler.createSyncTouch(item, null);
} else {
player.sendMessage(instance.getLocale().getMessage("event.hopper.syncchest", item.getType().toString()));
instance.enchantmentHandler.createSyncTouch(item, e.getClickedBlock());
}
e.setCancelled(true);
return;
}
if (e.getClickedBlock().getType() == Material.CHEST && Methods.isSync(player)) {
ItemStack item = e.getPlayer().getInventory().getItemInHand();
if (item.getItemMeta().getLore().size() == 2) {
player.sendMessage(instance.getLocale().getMessage("event.hopper.desyncchest", item.getType().toString()));
instance.enchantmentHandler.createSyncTouch(item, null);
} else {
player.sendMessage(instance.getLocale().getMessage("event.hopper.syncchest", item.getType().toString()));
instance.enchantmentHandler.createSyncTouch(item, e.getClickedBlock());
}
e.setCancelled(true);
return;
}
PlayerData playerData = instance.getPlayerDataManager().getPlayerData(player);
PlayerData playerData = instance.getPlayerDataManager().getPlayerData(player);
if (playerData.getSyncType() == null) {
if (e.getClickedBlock().getType() == Material.HOPPER) {
if (instance.isLiquidtanks() && net.arcaniax.liquidtanks.object.LiquidTankAPI.isLiquidTank(e.getClickedBlock().getLocation()))
return;
Hopper hopper = instance.getHopperManager().getHopper(e.getClickedBlock());
playerData.setLastHopper(hopper);
if (instance.getConfig().getBoolean("Main.Allow hopper Upgrading")
&& !player.getInventory().getItemInHand().getType().name().contains("PICKAXE")) {
hopper.overview(player);
e.setCancelled(true);
return;
}
}
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) {
hopper.link(e.getClickedBlock(), playerData.getSyncType() == SyncType.FILTERED, player);
}
e.setCancelled(true);
int amountLinked = hopper.getLevel().getLinkAmount();
if (hopper.getLinkedBlocks().size() >= amountLinked) {
playerData.setSyncType(null);
if (playerData.getSyncType() == null) {
if (e.getClickedBlock().getType() == Material.HOPPER) {
if (instance.isLiquidtanks() && net.arcaniax.liquidtanks.object.LiquidTankAPI.isLiquidTank(e.getClickedBlock().getLocation()))
return;
Hopper hopper = instance.getHopperManager().getHopper(e.getClickedBlock());
playerData.setLastHopper(hopper);
if (!player.getInventory().getItemInHand().getType().name().contains("PICKAXE")) {
hopper.overview(player);
e.setCancelled(true);
return;
}
}
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) {
hopper.link(e.getClickedBlock(), playerData.getSyncType() == SyncType.FILTERED, player);
}
e.setCancelled(true);
int amountLinked = hopper.getLevel().getLinkAmount();
if (hopper.getLinkedBlocks().size() >= amountLinked) {
playerData.setSyncType(null);
}
}
}
}

View File

@ -54,6 +54,7 @@ public class StorageItem {
public boolean asBoolean() {
if (object == null) return false;
if (object instanceof Integer) return (Integer) object == 1;
return (boolean) object;
}
@ -63,6 +64,8 @@ public class StorageItem {
}
public Object asObject() {
if (object == null) return null;
if (object instanceof Boolean) return (Boolean) object ? 1 : 0;
return object;
}

View File

@ -105,8 +105,10 @@ public class StorageMysql extends Storage {
continue;
toSave.remove(to.getKey());
for (int i = 0; i < to.getValue().length; i ++) {
if (!to.getValue()[i].asObject().toString()
.equals(last.getValue()[i].asObject().toString())) {
if ((to.getValue()[i].asObject() != null && last.getValue()[i].asObject() == null)
|| (last.getValue()[i].asObject() == null && to.getValue()[i].asObject() != null)
|| (last.getValue()[i].asObject() != null && to.getValue()[i].asObject() != null
&& !to.getValue()[i].asObject().toString().equals(last.getValue()[i].asObject().toString()))) {
//Update
StorageItem[] items = to.getValue();
StringBuilder sql = new StringBuilder(String.format("UPDATE `" + instance.getConfig().getString("Database.Prefix") + "%s`", toKey));

View File

@ -2,6 +2,7 @@ package com.songoda.epichoppers.tasks;
import com.songoda.epichoppers.EpicHoppers;
import com.songoda.epichoppers.boost.BoostData;
import com.songoda.epichoppers.hopper.HopperManager;
import com.songoda.epichoppers.hopper.levels.modules.Module;
import com.songoda.epichoppers.utils.HopperDirection;
import com.songoda.epichoppers.utils.Methods;
@ -12,9 +13,14 @@ import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
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.StorageMinecart;
import org.bukkit.inventory.BrewerInventory;
import org.bukkit.inventory.DoubleChestInventory;
import org.bukkit.inventory.FurnaceInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
@ -25,9 +31,14 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Created by songoda on 3/14/2017.
@ -43,7 +54,7 @@ public class HopTask extends BukkitRunnable {
public HopTask(EpicHoppers plug) {
plugin = plug;
this.hopTicks = Setting.HOP_TICKS.getInt() / 2; // Purposeful integer division
this.hopTicks = Math.max(1, Setting.HOP_TICKS.getInt() / 2); // Purposeful integer division. Don't go below 1.
this.runTaskTimer(plugin, 0, 2);
}
@ -52,6 +63,8 @@ public class HopTask extends BukkitRunnable {
Collection<com.songoda.epichoppers.hopper.Hopper> hoppers = plugin.getHopperManager().getHoppers().values();
Iterator<com.songoda.epichoppers.hopper.Hopper> itr = hoppers.iterator();
Set<Location> toRemove = new HashSet<>();
main:
while (itr.hasNext()) {
com.songoda.epichoppers.hopper.Hopper hopper = itr.next();
@ -69,7 +82,7 @@ public class HopTask extends BukkitRunnable {
// If block is not a hopper remove and continue.
if (block.getType() != Material.HOPPER) {
plugin.getHopperManager().removeHopper(location);
toRemove.add(location);
continue;
}
@ -112,47 +125,46 @@ public class HopTask extends BukkitRunnable {
BoostData boostData = plugin.getBoostManager().getBoost(hopper.getPlacedBy());
int amount = hopper.getLevel().getAmount() * (boostData == null ? 1 : boostData.getMultiplier());
// Fetch all hopper contents.
ItemStack[] hopperContents = hopperState.getInventory().getContents();
// Grab items from the container above (includes storage/hopper minecarts and EpicFarming farm items)
// If the container above is a hopper, ignore it if it's pointing down
Block above = block.getRelative(BlockFace.UP);
boolean isFarmItem = false;
Collection<Entity> nearbyEntities = null;
outer:
if ((above.getState() instanceof InventoryHolder
&& (above.getType() != Material.HOPPER || HopperDirection.getDirection(above.getState().getRawData()) != HopperDirection.DOWN))
|| !(nearbyEntities = above.getWorld().getNearbyEntities(above.getLocation().clone().add(0.5, 0.5, 0.5), 0.5, 0.5, 0.5)).isEmpty()
|| (isFarmItem = this.isFarmItem(above))) {
// Get filter endpoint
InventoryHolder filterEndpoint = this.getFilterEndpoint(hopper);
// Loop through our container list.
for (Location destinationLocation : linkedContainers) {
// Make sure the destination chunk is loaded.
if (!destinationLocation.getWorld().isChunkLoaded(destinationLocation.getBlockX() >> 4,
destinationLocation.getBlockZ() >> 4))
continue;
// Get the destination block.
Block destinationBlock = destinationLocation.getBlock();
// Get the destination state.
BlockState blockState = destinationBlock.getState();
// Remove if destination is not a inventory holder.
if (!(blockState instanceof InventoryHolder)) {
hopper.removeLinkedBlock(destinationLocation);
continue;
// Get the inventory holder. Special check for EpicFarming.
// Get the slots that we can pull items from.
InventoryHolder aboveInvHolder;
int[] pullableSlots;
if (isFarmItem) {
aboveInvHolder = this.getEpicFarmingItemWrapped(above);
pullableSlots = IntStream.rangeClosed(27, 53).toArray();
} else if (nearbyEntities != null) {
if ((aboveInvHolder = this.getRandomInventoryHolderFromEntities(nearbyEntities)) == null)
break outer;
if (aboveInvHolder instanceof StorageMinecart) {
pullableSlots = IntStream.rangeClosed(0, 26).toArray();
} else {
pullableSlots = IntStream.rangeClosed(0, 4).toArray();
}
} else {
aboveInvHolder = (InventoryHolder) above.getState();
pullableSlots = this.getPullableSlots(aboveInvHolder, above.getType());
}
// Cast blockState to container
InventoryHolder destinationContainer = ((InventoryHolder) blockState);
ItemStack[] contents = aboveInvHolder.getInventory().getContents();
// Loop through all of our hoppers item slots.
for (int i = 0; i < 5; i++) {
// Loop over the pullable slots and try to pull something.
for (int i : pullableSlots) {
// Get the item
ItemStack item = contents[i];
// Skip if slot empty.
if (hopperContents[i] == null)
continue;
// Get potential item to move.
ItemStack item = hopperContents[i];
// Skip if item blacklisted.
if ((this.blacklist.containsKey(hopperState) && this.blacklist.get(hopperState).isSimilar(item)) || blockedMaterials.contains(item.getType()))
// If item is invalid, try the next slot.
if (item == null)
continue;
// Get amount to move.
@ -162,14 +174,92 @@ public class HopTask extends BukkitRunnable {
ItemStack itemToMove = item.clone();
itemToMove.setAmount(amountToMove);
// Process void.
if (hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> itemStack.isSimilar(item))) {
item.setAmount(item.getAmount() - amountToMove);
continue;
}
// Add item to container and break on success.
if (this.addItem(hopper, aboveInvHolder, hopperState, block.getType(), item, itemToMove, amountToMove))
break;
}
}
// Set current destination.
InventoryHolder currentDestination = destinationContainer;
// Fetch all hopper contents.
ItemStack[] hopperContents = hopperState.getInventory().getContents();
// Loop over hopper inventory to process void filtering.
if (!hopper.getFilter().getVoidList().isEmpty()) {
for (ItemStack item : hopperContents) {
// Skip if slot empty.
if (item == null)
continue;
// Try to void it out
int amountToVoid = item.getAmount() < amount ? item.getAmount() : amount;
if (hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> itemStack.isSimilar(item))) {
item.setAmount(item.getAmount() - amountToVoid);
break;
}
}
}
// Get filter endpoint
InventoryHolder filterEndpoint = this.getFilterEndpoint(hopper);
// Keep track of any destination containers
List<InventoryHolder> destinationContainers = new ArrayList<>();
// Add linked containers to the destinations
for (Location linkedContainerLocation : linkedContainers) {
// Make sure the destination chunk is loaded.
if (!linkedContainerLocation.getWorld().isChunkLoaded(linkedContainerLocation.getBlockX() >> 4,
linkedContainerLocation.getBlockZ() >> 4))
continue;
// Get the destination block.
Block destinationBlock = linkedContainerLocation.getBlock();
// Get the destination state.
BlockState blockState = destinationBlock.getState();
// Remove if destination is not a inventory holder.
if (!(blockState instanceof InventoryHolder)) {
hopper.removeLinkedBlock(linkedContainerLocation);
continue;
}
// Add to the destination containers list
destinationContainers.add((InventoryHolder) blockState);
}
// Add storage/hopper minecarts the hopper is pointing into to the list if there aren't any destinations
if (destinationContainers.size() < 2) {
destinationContainers.addAll(block.getWorld().getNearbyEntities(hopperDirection.getLocation(location).clone().add(0.5, 0.5, 0.5), 0.5, 0.5, 0.5)
.stream().filter(e -> e.getType() == EntityType.MINECART_CHEST || e.getType() == EntityType.MINECART_HOPPER)
.map(e -> (InventoryHolder) e).collect(Collectors.toSet()));
}
// Loop through our destination list.
for (InventoryHolder currentDestination : destinationContainers) {
// Loop through all of our hoppers item slots.
for (int i = 0; i < 5; i++) {
// Get potential item to move.
ItemStack item = hopperContents[i];
// Skip if slot empty.
if (item == null)
continue;
// Skip if item blacklisted or void.
if ((this.blacklist.containsKey(hopperState) && this.blacklist.get(hopperState).isSimilar(item))
|| blockedMaterials.contains(item.getType())
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> itemStack.isSimilar(item)))
continue;
// Get amount to move.
int amountToMove = item.getAmount() < amount ? item.getAmount() : amount;
// Create item that will be moved.
ItemStack itemToMove = item.clone();
itemToMove.setAmount(amountToMove);
// Process whitelist and blacklist.
boolean blocked = (!hopper.getFilter().getWhiteList().isEmpty() && hopper.getFilter().getWhiteList().stream().noneMatch(itemStack -> itemStack.isSimilar(item))
@ -179,12 +269,15 @@ public class HopTask extends BukkitRunnable {
// otherwise set the current destination to the endpoint.
if (blocked) {
if (filterEndpoint == null || !this.canMove(filterEndpoint.getInventory(), itemToMove))
break;
continue;
currentDestination = filterEndpoint;
}
// Get the material of the destination
Material destinationMaterial = currentDestination instanceof BlockState ? ((BlockState) currentDestination).getType() : Material.AIR;
// Add item to container and continue on success.
if (this.addItem(hopper, hopperState, currentDestination, destinationBlock.getType(), item, itemToMove, amountToMove))
if (this.addItem(hopper, hopperState, currentDestination, destinationMaterial, item, itemToMove, amountToMove))
continue main;
}
}
@ -193,6 +286,10 @@ public class HopTask extends BukkitRunnable {
}
}
// Clear out invalid hoppers
HopperManager hopperManager = plugin.getHopperManager();
toRemove.forEach(hopperManager::removeHopper);
// Empty blacklist in preparation for next cycle.
this.blacklist.clear();
}
@ -202,6 +299,10 @@ public class HopTask extends BukkitRunnable {
Inventory destinationInventory = currentDestination.getInventory();
// Don't transfer shulker boxes into other shulker boxes, that's a bad idea.
if (destinationType.name().contains("SHULKER_BOX") && item.getType().name().contains("SHULKER_BOX"))
return false;
switch (destinationType.name()) {
case "ENDER_CHEST":
OfflinePlayer op = Bukkit.getOfflinePlayer(hopper.getPlacedBy());
@ -209,24 +310,6 @@ public class HopTask extends BukkitRunnable {
if (op.isOnline())
destinationInventory = op.getPlayer().getEnderChest();
break;
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;
@ -264,6 +347,7 @@ public class HopTask extends BukkitRunnable {
this.debt(item, amountToMove, currentHolder);
return true;
}
case "SMOKER":
case "BLAST_FURNACE":
case "BURNING_FURNACE":
case "FURNACE": {
@ -298,7 +382,8 @@ public class HopTask extends BukkitRunnable {
// Prevent item from being moved again during this cycle.
// Only block if the hopper being transfered into doesn't already contain the same item.
if (!destinationInventory.contains(itemToMove))
// Don't blacklist if the block is transfering items into itself
if (!destinationInventory.contains(itemToMove) && currentDestination != currentHolder && currentHolder instanceof Hopper)
this.blacklist.put(currentDestination, itemToMove);
// Move item to destination.
@ -307,8 +392,9 @@ public class HopTask extends BukkitRunnable {
// Debt hopper
this.debt(item, amountToMove, currentHolder);
// Update comparators for destination hopper.
updateAdjacentComparators(((BlockState) currentDestination).getLocation());
// Update comparators for destination block.
if (currentDestination instanceof BlockState)
updateAdjacentComparators(((BlockState) currentDestination).getLocation());
// Update comparators for current hopper.
updateAdjacentComparators(hopper.getLocation());
@ -394,4 +480,74 @@ public class HopTask extends BukkitRunnable {
return false;
}
/**
* Gets a set of slots that can be pulled from based on the given material
* @param material The material to get pullable slots for
* @return A set of valid pullable slots
*/
private int[] getPullableSlots(InventoryHolder inventoryHolder, Material material) {
if (material.name().contains("SHULKER_BOX"))
return IntStream.rangeClosed(0, 26).toArray();
switch (material.name()) {
case "BARREL":
case "CHEST":
case "TRAPPED_CHEST":
if (inventoryHolder.getInventory() instanceof DoubleChestInventory)
return IntStream.rangeClosed(0, 53).toArray();
return IntStream.rangeClosed(0, 26).toArray();
case "BREWING_STAND":
return IntStream.rangeClosed(0, 2).toArray();
case "HOPPER":
return IntStream.rangeClosed(0, 4).toArray();
case "DISPENSER":
case "DROPPER":
return IntStream.rangeClosed(0, 8).toArray();
case "SMOKER":
case "BLAST_FURNACE":
case "BURNING_FURNACE":
case "FURNACE":
return IntStream.of(2).toArray();
default:
return IntStream.empty().toArray();
}
}
/**
* Gets a random InventoryHolder from a collection of entities
* Only grabs InventoryHolders from StorageMinecarts and HopperMinecarts
* @param entities The collection of entities
* @return A random InventoryHolder if one exists, otherwise null
*/
private InventoryHolder getRandomInventoryHolderFromEntities(Collection<Entity> entities) {
List<InventoryHolder> inventoryHolders = new ArrayList<>();
entities.stream().filter(e -> e.getType() == EntityType.MINECART_CHEST || e.getType() == EntityType.MINECART_HOPPER)
.forEach(e -> inventoryHolders.add((InventoryHolder) e));
if (inventoryHolders.isEmpty())
return null;
if (inventoryHolders.size() == 1)
return inventoryHolders.get(0);
return inventoryHolders.get(ThreadLocalRandom.current().nextInt(inventoryHolders.size()));
}
/**
* Checks if a given block is an EpicFarming farm item
* @param block The block to check
* @return true if the block is a farm item, otherwise false
*/
private boolean isFarmItem(Block block) {
return EpicHoppers.getInstance().isEpicFarming() && com.songoda.epicfarming.EpicFarmingPlugin.getInstance().getFarmManager().getFarm(block) != null;
}
/**
* Gets an EpicFarming block as an InventoryHolder
* Needed because EpicFarming doesn't natively support having an InventoryHolder for the farm item
*
* @param block The block to effectively attach an InventoryHolder to
* @return An InventoryHolder wrapping the EpicFarming inventory
*/
private InventoryHolder getEpicFarmingItemWrapped(Block block) {
return () -> com.songoda.epicfarming.EpicFarmingPlugin.getInstance().getFarmManager().getFarm(block).getInventory();
}
}

View File

@ -35,7 +35,7 @@ public enum HopperDirection {
}
public Location getLocation(Location location) {
return location.add(getX(), getY(), getZ());
return location.clone().add(getX(), getY(), getZ());
}
public int getX() {

View File

@ -1,6 +1,7 @@
package com.songoda.epichoppers.utils;
import com.songoda.epichoppers.EpicHoppers;
import org.bukkit.Bukkit;
import java.sql.Connection;
import java.sql.DriverManager;
@ -33,8 +34,8 @@ public class MySQLDatabase {
"\t`whitelist` TEXT NULL,\n" +
"\t`blacklist` TEXT NULL,\n" +
"\t`void` TEXT NULL,\n" +
"\t`black` TEXT NULL\n" +
"\t`autobreak` TEXT NULL\n" +
"\t`black` TEXT NULL,\n" +
"\t`autobreak` TINYINT(1) NULL\n" +
")");
connection.createStatement().execute("CREATE TABLE IF NOT EXISTS `" + instance.getConfig().getString("Database.Prefix") + "boosts` (\n" +
@ -44,7 +45,8 @@ public class MySQLDatabase {
")");
} catch (ClassNotFoundException | SQLException e) {
System.out.println("Database connection failed.");
Bukkit.getLogger().severe("Database connection failed.");
Bukkit.getLogger().severe(e.getMessage());
}
}

View File

@ -36,7 +36,7 @@ public class Serializers {
public static ItemStack deserialize(String serializedItem) {
String[] strings = serializedItem.split(" ");
Map<Enchantment, Integer> enchants = new HashMap<Enchantment, Integer>();
Map<Enchantment, Integer> enchants = new HashMap<>();
String[] args;
ItemStack item = new ItemStack(Material.AIR);
for (String str : strings) {
@ -53,21 +53,22 @@ public class Serializers {
}
for (String str : strings) {
args = str.split(":", 2);
Bukkit.broadcastMessage(Arrays.toString(args));
if (isNumber(args[0])) item.setAmount(Integer.parseInt(args[0]));
if (args.length == 1) continue;
if (args[0].equalsIgnoreCase("name:")) {
if (args[0].equalsIgnoreCase("name")) {
setName(item, ChatColor.translateAlternateColorCodes('&', args[1]));
continue;
}
if (args[0].equalsIgnoreCase("lore:")) {
if (args[0].equalsIgnoreCase("lore")) {
setLore(item, ChatColor.translateAlternateColorCodes('&', args[1]));
continue;
}
if (args[0].equalsIgnoreCase("rgb:")) {
if (args[0].equalsIgnoreCase("rgb")) {
setArmorColor(item, args[1]);
continue;
}
if (args[0].equalsIgnoreCase("owner:")) {
if (args[0].equalsIgnoreCase("owner")) {
setOwner(item, args[1]);
continue;
}
@ -102,7 +103,7 @@ public class Serializers {
}
private static void setName(ItemStack item, String name) {
name = name.replace("_", " ");
name = name.replace("_", " ").replace('&', ChatColor.COLOR_CHAR);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(name);
item.setItemMeta(meta);
@ -120,7 +121,7 @@ public class Serializers {
}
private static void setLore(ItemStack item, String lore) {
lore = lore.replace("_", " ");
lore = lore.replace("_", " ").replace('&', ChatColor.COLOR_CHAR);
ItemMeta meta = item.getItemMeta();
meta.setLore(Arrays.asList(lore.split("\\|")));
item.setItemMeta(meta);

View File

@ -50,7 +50,8 @@ public enum Setting {
BLOCKBREAK_PARTICLE("Main.BlockBreak Particle Type", "LAVA",
"The particle shown when the block break module performs a block break."),
BLACKLIST("Main.BlockBreak Blacklisted Blocks", Arrays.asList("BEDROCK"), "" +
BLACKLIST("Main.BlockBreak Blacklisted Blocks",
Arrays.asList("BEDROCK", "END_PORTAL", "ENDER_PORTAL", "END_PORTAL_FRAME", "ENDER_PORTAL_FRAME", "PISTON_HEAD", "PISTON_EXTENSION", "RAIL", "RAILS", "ACTIVATOR_RAIL", "DETECTOR_RAIL", "POWERED_RAIL"),
"Anything listed here will not be broken by the block break module."),
AUTOSELL_PRICES("Main.AutoSell Prices",

View File

@ -27,7 +27,7 @@ interface.hopper.autosell = "&7AutoSell: Every &6%seconds%s"
interface.hopper.linkamount = "&7Link Overflow: &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.|&7Currently linked to &6%amount% hopper(s)&7."
interface.hopper.synclore = "|&7Left-Click then click a another|&7hopper or chest to link!||&7Right-Click to unlink.|&7Currently linked to &6%amount% container(s)&7."
interface.hopper.perltitle = "&6Click to Teleport"
interface.hopper.perllore2 = "|&7Left-Click to teleport to|&7the end of the chain.||&7Right-Click to switch the|&7teleport trigger mode.|&7Currently set to: &a%type%&7."
interface.hopper.filtertitle = "&cClick to Filter"

View File

@ -1,7 +1,7 @@
name: EpicHoppers
description: EpicHoppers
main: com.songoda.epichoppers.EpicHoppers
softdepend: [LiquidTanks, WildStacker, Towny, RedProtect, Kingdoms, PlotsSquared, GriefPrevention, USkyBlock, ASkyBlock, WorldGuard, Factions, Vault]
softdepend: [LiquidTanks, WildStacker, Towny, RedProtect, Kingdoms, PlotsSquared, GriefPrevention, USkyBlock, ASkyBlock, WorldGuard, Factions, Vault, EpicFarming]
version: maven-version-number
author: Songoda
api-version: 1.13