mirror of
https://github.com/songoda/EpicHoppers.git
synced 2025-02-15 19:31:58 +01:00
Merge branch 'development'
This commit is contained in:
commit
33150134e6
@ -4,7 +4,7 @@ stages:
|
||||
variables:
|
||||
name: "EpicHoppers"
|
||||
path: "/builds/$CI_PROJECT_PATH"
|
||||
version: "4.2.6"
|
||||
version: "4.2.10"
|
||||
|
||||
build:
|
||||
stage: build
|
||||
|
12
pom.xml
12
pom.xml
@ -68,8 +68,8 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.14.4-R0.1-SNAPSHOT</version>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.14.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.songoda</groupId>
|
||||
@ -106,14 +106,14 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>fabledskyblock</artifactId>
|
||||
<version>78.5</version>
|
||||
<artifactId>abledskyblock</artifactId>
|
||||
<version>79.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.songoda</groupId>
|
||||
<artifactId>epicfarming</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<artifactId>EpicFarming</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -19,51 +19,36 @@ public class CommandBoost extends AbstractCommand {
|
||||
@Override
|
||||
protected ReturnType runCommand(EpicHoppers instance, CommandSender sender, String... args) {
|
||||
if (args.length < 3) {
|
||||
instance.getLocale().newMessage("&7Syntax error...").sendPrefixedMessage(sender);
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
if (Bukkit.getPlayer(args[1]) == null) {
|
||||
instance.getLocale().newMessage("&cThat player does not exist...").sendPrefixedMessage(sender);
|
||||
return ReturnType.FAILURE;
|
||||
} else if (!Methods.isInt(args[2])) {
|
||||
if (!Methods.isInt(args[2])) {
|
||||
instance.getLocale().newMessage("&6" + args[2] + " &7is not a number...").sendPrefixedMessage(sender);
|
||||
return ReturnType.FAILURE;
|
||||
} else {
|
||||
Calendar c = Calendar.getInstance();
|
||||
Date currentDate = new Date();
|
||||
c.setTime(currentDate);
|
||||
|
||||
String time = "&7.";
|
||||
|
||||
if (args.length > 3) {
|
||||
if (args[3].contains("m:")) {
|
||||
String[] arr2 = (args[3]).split(":");
|
||||
c.add(Calendar.MINUTE, Integer.parseInt(arr2[1]));
|
||||
time = " &7for &6" + arr2[1] + " minutes&7.";
|
||||
} else if (args[3].contains("h:")) {
|
||||
String[] arr2 = (args[3]).split(":");
|
||||
c.add(Calendar.HOUR, Integer.parseInt(arr2[1]));
|
||||
time = " &7for &6" + arr2[1] + " hours&7.";
|
||||
} else if (args[3].contains("d:")) {
|
||||
String[] arr2 = (args[3]).split(":");
|
||||
c.add(Calendar.HOUR, Integer.parseInt(arr2[1]) * 24);
|
||||
time = " &7for &6" + arr2[1] + " days&7.";
|
||||
} else if (args[3].contains("y:")) {
|
||||
String[] arr2 = (args[3]).split(":");
|
||||
c.add(Calendar.YEAR, Integer.parseInt(arr2[1]));
|
||||
time = " &7for &6" + arr2[1] + " years&7.";
|
||||
} else {
|
||||
instance.getLocale().newMessage("&7" + args[3] + " &7is invalid.").sendPrefixedMessage(sender);
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
} else {
|
||||
c.add(Calendar.YEAR, 10);
|
||||
}
|
||||
|
||||
BoostData boostData = new BoostData(Integer.parseInt(args[2]), c.getTime().getTime(), Bukkit.getPlayer(args[1]).getUniqueId());
|
||||
instance.getBoostManager().addBoostToPlayer(boostData);
|
||||
instance.getLocale().newMessage("&7Successfully boosted &6" + Bukkit.getPlayer(args[1]).getName() + "'s &7hoppers transfer rates by &6" + args[2] + "x" + time).sendPrefixedMessage(sender);
|
||||
return ReturnType.SYNTAX_ERROR;
|
||||
}
|
||||
return ReturnType.FAILURE;
|
||||
|
||||
long duration = 0L;
|
||||
|
||||
if (args.length > 3) {
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
String line = args[i];
|
||||
long time = Methods.parseTime(line);
|
||||
duration += time;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
if (player == null) {
|
||||
instance.getLocale().newMessage("&cThat player does not exist or is not online...").sendPrefixedMessage(sender);
|
||||
return ReturnType.FAILURE;
|
||||
}
|
||||
|
||||
BoostData boostData = new BoostData(Integer.parseInt(args[2]), duration == 0L ? Long.MAX_VALUE : System.currentTimeMillis() + duration, player.getUniqueId());
|
||||
instance.getBoostManager().addBoostToPlayer(boostData);
|
||||
instance.getLocale().newMessage("&7Successfully boosted &6" + Bukkit.getPlayer(args[1]).getName()
|
||||
+ "'s &7hopper transfer rates by &6" + args[2] + "x" + (duration == 0L ? "" : (" for " + Methods.makeReadable(duration))) + "&7.").sendPrefixedMessage(sender);
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -77,7 +62,7 @@ public class CommandBoost extends AbstractCommand {
|
||||
} else if (args.length == 3) {
|
||||
return Arrays.asList("1", "2", "3", "4", "5");
|
||||
} else if (args.length == 4) {
|
||||
return Arrays.asList("m:", "h:", "d:", "y:");
|
||||
return Arrays.asList("1m", "1h", "1d");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -89,7 +74,7 @@ public class CommandBoost extends AbstractCommand {
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "/eh boost <player> <multiplier> [m:minute, h:hour, d:day, y:year]";
|
||||
return "/eh boost <player> <amount> [duration]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,12 +1,15 @@
|
||||
package com.songoda.epichoppers.enchantment;
|
||||
|
||||
import com.songoda.epichoppers.utils.Methods;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by songoda on 3/22/2017.
|
||||
@ -15,10 +18,17 @@ public class Enchantment {
|
||||
|
||||
public ItemStack createSyncTouch(ItemStack item, Block block) {
|
||||
ItemMeta itemmeta = item.getItemMeta();
|
||||
ArrayList<String> lore = new ArrayList<>();
|
||||
List<String> lore = itemmeta.hasLore() ? itemmeta.getLore() : new ArrayList<>();
|
||||
|
||||
for (String str : lore) {
|
||||
if (!str.contains("Sync Touch")) continue;
|
||||
lore.remove(str);
|
||||
break;
|
||||
}
|
||||
|
||||
if (block != null) {
|
||||
lore.add(Methods.formatText("&aSync Touch"));
|
||||
lore.add(Methods.convertToInvisibleString(Methods.serializeLocation(block)));
|
||||
lore.add(Methods.convertToInvisibleString(Methods.serializeLocation(block) + "~")
|
||||
+ Methods.formatText("&aSync Touch"));
|
||||
} else {
|
||||
lore.add(Methods.formatText("&7Sync Touch"));
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ public class Hopper {
|
||||
EpicHoppers instance = EpicHoppers.getInstance();
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(instance, () -> {
|
||||
PlayerData playerData = instance.getPlayerDataManager().getPlayerData(player);
|
||||
if (playerData.getSyncType() != null) {
|
||||
if (playerData.getSyncType() != null && playerData.getLastHopper() == this) {
|
||||
instance.getLocale().getMessage("event.hopper.synctimeout").sendPrefixedMessage(player);
|
||||
playerData.setSyncType(null);
|
||||
}
|
||||
|
@ -11,16 +11,22 @@ import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class Module {
|
||||
|
||||
private static final Map<String, ConfigWrapper> configs = new HashMap<>();
|
||||
|
||||
protected final EpicHoppers plugin;
|
||||
private final ConfigWrapper config;
|
||||
|
||||
public Module(EpicHoppers plugin) {
|
||||
this.plugin = plugin;
|
||||
this.config = new ConfigWrapper(plugin, File.separator + "modules", getName() + ".yml");
|
||||
if (!configs.containsKey(getName()))
|
||||
configs.put(getName(), new ConfigWrapper(plugin, File.separator + "modules", getName() + ".yml"));
|
||||
this.config = configs.get(getName());
|
||||
}
|
||||
|
||||
public abstract String getName();
|
||||
|
@ -77,7 +77,7 @@ public class ModuleBlockBreak extends Module {
|
||||
Block above = hopper.getLocation().getBlock().getRelative(0, 1, 0);
|
||||
|
||||
// Don't break farm items from EpicFarming
|
||||
if (plugin.isEpicFarming() && com.songoda.epicfarming.EpicFarmingPlugin.getInstance().getFarmManager().getFarm(above) != null)
|
||||
if (plugin.isEpicFarming() && com.songoda.epicfarming.EpicFarming.getInstance().getFarmManager().getFarm(above) != null)
|
||||
return;
|
||||
|
||||
// don't break blacklisted blocks, fluids, or containers
|
||||
|
@ -6,8 +6,6 @@ import com.songoda.epichoppers.hopper.Hopper;
|
||||
import com.songoda.epichoppers.utils.Methods;
|
||||
import com.songoda.epichoppers.utils.ServerVersion;
|
||||
import com.songoda.epichoppers.utils.StorageContainerCache;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
@ -18,12 +16,11 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ModuleSuction extends Module {
|
||||
|
@ -6,6 +6,7 @@ import com.songoda.epichoppers.hopper.HopperBuilder;
|
||||
import com.songoda.epichoppers.hopper.levels.Level;
|
||||
import com.songoda.epichoppers.utils.Methods;
|
||||
import com.songoda.epichoppers.utils.ServerVersion;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -23,6 +24,10 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
/**
|
||||
* Created by songoda on 3/14/2017.
|
||||
@ -30,9 +35,11 @@ import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
public class BlockListeners implements Listener {
|
||||
|
||||
private final EpicHoppers instance;
|
||||
private final Random random;
|
||||
|
||||
public BlockListeners(EpicHoppers instance) {
|
||||
this.instance = instance;
|
||||
this.random = new Random();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
@ -68,7 +75,9 @@ public class BlockListeners implements Listener {
|
||||
int limit = -1;
|
||||
for (PermissionAttachmentInfo permissionAttachmentInfo : player.getEffectivePermissions()) {
|
||||
if (!permissionAttachmentInfo.getPermission().toLowerCase().startsWith("epichoppers.limit")) continue;
|
||||
limit = Integer.parseInt(permissionAttachmentInfo.getPermission().split("\\.")[2]);
|
||||
int num = Integer.parseInt(permissionAttachmentInfo.getPermission().split("\\.")[2]);
|
||||
if (num > limit)
|
||||
limit = num;
|
||||
}
|
||||
if (limit == -1) limit = instance.getConfig().getInt("Main.Max Hoppers Per Chunk");
|
||||
return limit;
|
||||
@ -130,9 +139,17 @@ public class BlockListeners implements Listener {
|
||||
|
||||
ItemStack tool = event.getPlayer().getInventory().getItemInHand();
|
||||
ItemMeta meta = tool.getItemMeta();
|
||||
if (tool.getItemMeta().getLore().size() != 2) return;
|
||||
Location location = null;
|
||||
|
||||
Location location = Methods.unserializeLocation(meta.getLore().get(1).replaceAll("§", ""));
|
||||
for (String lore : meta.getLore()) {
|
||||
if (!lore.contains(Methods.formatText("&aSync Touch"))) continue;
|
||||
String[] loreSplit = lore.split("~");
|
||||
location = Methods.unserializeLocation(loreSplit[0].replace(ChatColor.COLOR_CHAR + "", "")
|
||||
.replace("~", ""));
|
||||
break;
|
||||
}
|
||||
|
||||
if (location == null) return;
|
||||
|
||||
if (location.getBlock().getType() != Material.CHEST) return;
|
||||
|
||||
@ -147,9 +164,21 @@ public class BlockListeners implements Listener {
|
||||
if (event.getPlayer().getInventory().getItemInHand().getItemMeta().hasEnchant(Enchantment.SILK_TOUCH)) {
|
||||
ih.getInventory().addItem(new ItemStack(event.getBlock().getType(), 1, event.getBlock().getData()));
|
||||
} else {
|
||||
for (ItemStack is : event.getBlock().getDrops())
|
||||
ih.getInventory().addItem(is);
|
||||
if (event.getPlayer().getInventory().getItemInHand().getItemMeta().hasEnchant(Enchantment.LOOT_BONUS_BLOCKS)) {
|
||||
int level = event.getPlayer().getInventory().getItemInHand().getItemMeta().getEnchantLevel(Enchantment.LOOT_BONUS_BLOCKS);
|
||||
int dropAmount = calculateFortuneDrops(event.getBlock().getType(), level, random);
|
||||
for (int i = 0; i < dropAmount; i++) {
|
||||
for (ItemStack is : event.getBlock().getDrops()) ih.getInventory().addItem(is);
|
||||
}
|
||||
} else {
|
||||
for (ItemStack is : event.getBlock().getDrops()) {
|
||||
Map<Integer, ItemStack> notDropped = ih.getInventory().addItem(is);
|
||||
if (!notDropped.isEmpty())
|
||||
location.getWorld().dropItemNaturally(event.getBlock().getLocation(), new ArrayList<>(notDropped.values()).get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (instance.isServerVersionAtLeast(ServerVersion.V1_12)) {
|
||||
event.setDropItems(false);
|
||||
return;
|
||||
@ -165,4 +194,15 @@ public class BlockListeners implements Listener {
|
||||
event.getBlock().setType(Material.AIR);
|
||||
|
||||
}
|
||||
|
||||
private int calculateFortuneDrops(Material material, int level, Random random) {
|
||||
if (level <= 0) return 1;
|
||||
int drops = random.nextInt(level + 2) - 1;
|
||||
if (drops < 0) drops = 0;
|
||||
return applyLapisDrops(material, random) * (drops + 1);
|
||||
}
|
||||
|
||||
private int applyLapisDrops(Material material, Random random) {
|
||||
return material == Material.LAPIS_ORE ? 4 + random.nextInt(5) : 1;
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@ import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -52,7 +53,9 @@ public class EntityListeners implements Listener {
|
||||
if (location.getBlock().getType() != Material.CHEST) return;
|
||||
InventoryHolder ih = (InventoryHolder) location.getBlock().getState();
|
||||
for (ItemStack is : event.getDrops()) {
|
||||
ih.getInventory().addItem(is);
|
||||
Map<Integer, ItemStack> notDropped = ih.getInventory().addItem(is);
|
||||
if (!notDropped.isEmpty())
|
||||
location.getWorld().dropItemNaturally(event.getEntity().getLocation(), new ArrayList<>(notDropped.values()).get(0));
|
||||
}
|
||||
event.getDrops().clear();
|
||||
}
|
||||
|
@ -61,7 +61,15 @@ public class InteractListeners implements Listener {
|
||||
|
||||
if (e.getClickedBlock().getType() == Material.CHEST && Methods.isSync(player)) {
|
||||
ItemStack item = e.getPlayer().getInventory().getItemInHand();
|
||||
if (item.getItemMeta().getLore().size() == 2) {
|
||||
boolean isLinked = false;
|
||||
|
||||
for (String lore : item.getItemMeta().getLore()) {
|
||||
if (!lore.contains(Methods.formatText("&aSync Touch"))) continue;
|
||||
isLinked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isLinked) {
|
||||
instance.getLocale().getMessage("event.hopper.desyncchest")
|
||||
.processPlaceholder("name", item.getType().toString()).sendPrefixedMessage(player);
|
||||
instance.enchantmentHandler.createSyncTouch(item, null);
|
||||
|
@ -9,9 +9,6 @@ import com.songoda.epichoppers.utils.HopperDirection;
|
||||
import com.songoda.epichoppers.utils.Methods;
|
||||
import com.songoda.epichoppers.utils.StorageContainerCache;
|
||||
import com.songoda.epichoppers.utils.settings.Setting;
|
||||
import me.goodandevil.skyblock.SkyBlock;
|
||||
import me.goodandevil.skyblock.stackable.Stackable;
|
||||
import me.goodandevil.skyblock.stackable.StackableManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -25,13 +22,10 @@ import org.bukkit.entity.minecart.StorageMinecart;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
@ -47,12 +41,20 @@ public class HopTask extends BukkitRunnable {
|
||||
|
||||
private final int hopTicks;
|
||||
private final boolean hasFabledSkyBlock;
|
||||
private boolean legacyFabledSkyblock;
|
||||
private final Plugin fabledSkyblockPlugin;
|
||||
|
||||
public HopTask(EpicHoppers plug) {
|
||||
plugin = plug;
|
||||
this.hopTicks = Math.max(1, Setting.HOP_TICKS.getInt() / 2); // Purposeful integer division. Don't go below 1.
|
||||
this.runTaskTimer(plugin, 0, 2);
|
||||
this.hasFabledSkyBlock = Bukkit.getPluginManager().isPluginEnabled("FabledSkyBlock");
|
||||
if ((this.hasFabledSkyBlock = (fabledSkyblockPlugin = Bukkit.getPluginManager().getPlugin("FabledSkyBlock")) != null)) {
|
||||
try {
|
||||
Class.forName("me.goodandevil.skyblock.SkyBlock");
|
||||
legacyFabledSkyblock = true;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -128,11 +130,11 @@ public class HopTask extends BukkitRunnable {
|
||||
// Can we check this item?
|
||||
if ( // Ignore this one if the slot is empty
|
||||
item == null
|
||||
// Don't try to move items that we've added this round
|
||||
|| (hopperCache.cacheChanged[i] && item.getAmount() - hopperCache.cacheAdded[i] < maxToMove)
|
||||
// skip if blocked or voidlisted
|
||||
|| blockedMaterials.contains(item.getType())
|
||||
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item)))
|
||||
// Don't try to move items that we've added this round
|
||||
|| (hopperCache.cacheChanged[i] && item.getAmount() - hopperCache.cacheAdded[i] < maxToMove)
|
||||
// skip if blocked or voidlisted
|
||||
|| blockedMaterials.contains(item.getType())
|
||||
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item)))
|
||||
continue;
|
||||
|
||||
doProcess = true;
|
||||
@ -143,23 +145,53 @@ public class HopTask extends BukkitRunnable {
|
||||
|
||||
// Support for FabledSkyBlock stackables.
|
||||
if (this.hasFabledSkyBlock) {
|
||||
StackableManager stackableManager = SkyBlock.getInstance().getStackableManager();
|
||||
if (stackableManager != null && stackableManager.isStacked(pointingLocation)) {
|
||||
Stackable stackable = stackableManager.getStack(pointingLocation, pointingLocation.getBlock().getType());
|
||||
if (legacyFabledSkyblock) {
|
||||
Object stackableManager = fabledSkyblockPlugin.getClass().getMethod("getStackableManager").invoke(fabledSkyblockPlugin);
|
||||
boolean isStacked = stackableManager != null && (boolean) stackableManager.getClass().getMethod("isStacked", Location.class).invoke(stackableManager, pointingLocation);
|
||||
if (isStacked) {
|
||||
Material mat = pointingLocation.getBlock().getType();
|
||||
Object stackable = stackableManager.getClass().getMethod("getStack", Location.class, Material.class).invoke(stackableManager, pointingLocation, mat);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
final ItemStack item = hopperCache.cachedInventory[i];
|
||||
if (item == null) continue;
|
||||
|
||||
if (item.getType() == stackable.getMaterial()) {
|
||||
stackable.addOne();
|
||||
if (item.getAmount() == 1) {
|
||||
hopperCache.removeItem(i);
|
||||
} else {
|
||||
item.setAmount(item.getAmount() - 1);
|
||||
hopperCache.dirty = hopperCache.cacheChanged[i] = true;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
final ItemStack item = hopperCache.cachedInventory[i];
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.getType() == mat) {
|
||||
stackable.getClass().getMethod("addOne").invoke(stackable);
|
||||
if (item.getAmount() == 1) {
|
||||
hopperCache.removeItem(i);
|
||||
} else {
|
||||
item.setAmount(item.getAmount() - 1);
|
||||
hopperCache.dirty = hopperCache.cacheChanged[i] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
com.songoda.skyblock.stackable.StackableManager stackableManager = ((com.songoda.skyblock.SkyBlock) fabledSkyblockPlugin).getStackableManager();
|
||||
if (stackableManager != null && stackableManager.isStacked(pointingLocation)) {
|
||||
Material mat = pointingLocation.getBlock().getType();
|
||||
com.songoda.skyblock.stackable.Stackable stackable = stackableManager.getStack(pointingLocation, mat);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
final ItemStack item = hopperCache.cachedInventory[i];
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.getType() == mat) {
|
||||
stackable.addOne();
|
||||
if (item.getAmount() == 1) {
|
||||
hopperCache.removeItem(i);
|
||||
} else {
|
||||
item.setAmount(item.getAmount() - 1);
|
||||
hopperCache.dirty = hopperCache.cacheChanged[i] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -233,9 +265,9 @@ public class HopTask extends BukkitRunnable {
|
||||
contents = aboveCache.cachedInventory;
|
||||
aboveInvHolder = null;
|
||||
} else if (isFarmItem) {
|
||||
aboveInvHolder = this.getEpicFarmingItemWrapped(above);
|
||||
pullableSlots = IntStream.rangeClosed(27, 53).toArray();
|
||||
contents = aboveInvHolder.getInventory().getContents();
|
||||
aboveInvHolder = null;
|
||||
contents = getFarmContents(above);
|
||||
pullableSlots = IntStream.rangeClosed(0, contents.length - 1).toArray();
|
||||
} else {
|
||||
if ((aboveInvHolder = this.getRandomInventoryHolderFromEntities(nearbyEntities)) == null)
|
||||
return;
|
||||
@ -257,7 +289,7 @@ public class HopTask extends BukkitRunnable {
|
||||
final ItemStack toMove = contents[i];
|
||||
|
||||
// If item is invalid, try the next slot.
|
||||
if (toMove == null)
|
||||
if (toMove == null || toMove.getAmount() == 0)
|
||||
continue;
|
||||
|
||||
// if we're not moving the item that we're trying to craft, we need to verify that we're not trying to fill the last slot
|
||||
@ -267,12 +299,12 @@ public class HopTask extends BukkitRunnable {
|
||||
|
||||
// respect whitelist/blacklist filters
|
||||
if (toHopper.getFilter().getEndPoint() == null
|
||||
&& !(toHopper.getFilter().getWhiteList().isEmpty() && toHopper.getFilter().getBlackList().isEmpty())) {
|
||||
&& !(toHopper.getFilter().getWhiteList().isEmpty() && toHopper.getFilter().getBlackList().isEmpty())) {
|
||||
// this hopper has a filter with no rejection endpoint, so don't absorb disalowed items
|
||||
// whitelist has priority
|
||||
if (!toHopper.getFilter().getWhiteList().isEmpty()) {
|
||||
// is this item on the whitelist?
|
||||
if (!toHopper.getFilter().getWhiteList().stream().anyMatch(item -> Methods.isSimilarMaterial(toMove, item))) {
|
||||
if (toHopper.getFilter().getWhiteList().stream().noneMatch(item -> Methods.isSimilarMaterial(toMove, item))) {
|
||||
// nope!
|
||||
continue;
|
||||
}
|
||||
@ -286,7 +318,7 @@ public class HopTask extends BukkitRunnable {
|
||||
}
|
||||
|
||||
// Get amount to move.
|
||||
int amountToMove = toMove.getAmount() < maxToMove ? toMove.getAmount() : maxToMove;
|
||||
int amountToMove = Math.min(toMove.getAmount(), maxToMove);
|
||||
|
||||
// Create item that will be moved.
|
||||
ItemStack itemToMove = toMove.clone();
|
||||
@ -299,7 +331,10 @@ public class HopTask extends BukkitRunnable {
|
||||
if (aboveCache != null) {
|
||||
aboveCache.removeItems(itemToMove);
|
||||
} else {
|
||||
this.debt(itemToMove, amountToMove, aboveInvHolder);
|
||||
if (isFarmItem)
|
||||
com.songoda.epicfarming.EpicFarming.getInstance().getFarmManager().getFarm(above).removeMaterial(itemToMove.getType(), amountToMove);
|
||||
else
|
||||
this.debt(itemToMove, amountToMove, aboveInvHolder);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -352,7 +387,7 @@ public class HopTask extends BukkitRunnable {
|
||||
StorageContainerCache.Cache cache = new StorageContainerCache.Cache(targetBlock.getType(), destinationInventory.getContents());
|
||||
if (tryPush(hopper, hopperCache, cache, filterCache, maxToMove, blockedMaterials)) {
|
||||
// update inventory and exit
|
||||
if(cache.isDirty())
|
||||
if (cache.isDirty())
|
||||
destinationInventory.setContents(cache.cachedInventory);
|
||||
return;
|
||||
}
|
||||
@ -377,8 +412,8 @@ public class HopTask extends BukkitRunnable {
|
||||
// if we've gotten this far, check if we can push into a minecart
|
||||
if (checkForMinecarts) {
|
||||
for (InventoryHolder minecartInventory : hopper.getWorld().getNearbyEntities(pointingLocation.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())) {
|
||||
.stream().filter(e -> e.getType() == EntityType.MINECART_CHEST || e.getType() == EntityType.MINECART_HOPPER)
|
||||
.map(e -> (InventoryHolder) e).collect(Collectors.toSet())) {
|
||||
StorageContainerCache.Cache cache = new StorageContainerCache.Cache(Material.CHEST, minecartInventory.getInventory().getContents());
|
||||
if (tryPush(hopper, hopperCache, cache, filterCache, maxToMove, blockedMaterials)) {
|
||||
if (cache.isDirty())
|
||||
@ -390,10 +425,10 @@ public class HopTask extends BukkitRunnable {
|
||||
}
|
||||
|
||||
private boolean tryPush(com.songoda.epichoppers.hopper.Hopper hopper,
|
||||
StorageContainerCache.Cache hopperCache,
|
||||
StorageContainerCache.Cache targetCache,
|
||||
StorageContainerCache.Cache filterCache,
|
||||
int maxToMove, Collection<Material> blockedMaterials) {
|
||||
StorageContainerCache.Cache hopperCache,
|
||||
StorageContainerCache.Cache targetCache,
|
||||
StorageContainerCache.Cache filterCache,
|
||||
int maxToMove, Collection<Material> blockedMaterials) {
|
||||
|
||||
// Loop through all of our hopper's item slots.
|
||||
for (int i = 0; i < 5; i++) {
|
||||
@ -403,11 +438,11 @@ public class HopTask extends BukkitRunnable {
|
||||
// Can we check this item?
|
||||
if ( // Ignore this one if the slot is empty
|
||||
item == null
|
||||
// Don't try to move items that we've added this round
|
||||
|| (hopperCache.cacheChanged[i] && item.getAmount() - hopperCache.cacheAdded[i] < maxToMove)
|
||||
// skip if blocked or voidlisted
|
||||
|| blockedMaterials.contains(item.getType())
|
||||
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item)))
|
||||
// Don't try to move items that we've added this round
|
||||
|| (hopperCache.cacheChanged[i] && item.getAmount() - hopperCache.cacheAdded[i] < maxToMove)
|
||||
// skip if blocked or voidlisted
|
||||
|| blockedMaterials.contains(item.getType())
|
||||
|| hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item)))
|
||||
continue;
|
||||
|
||||
// Create item that will be moved.
|
||||
@ -444,7 +479,7 @@ public class HopTask extends BukkitRunnable {
|
||||
for (int i = 0; i < hopperContents.length; i++) {
|
||||
final ItemStack item = hopperContents[i];
|
||||
if (item != null && hopper.getFilter().getVoidList().stream().anyMatch(itemStack -> Methods.isSimilarMaterial(itemStack, item))) {
|
||||
int amt = Math.min(0, item.getAmount() - maxToMove);
|
||||
int amt = Math.max(0, item.getAmount() - maxToMove);
|
||||
if (amt == 0) {
|
||||
hopperCache.removeItem(i);
|
||||
} else {
|
||||
@ -456,8 +491,10 @@ public class HopTask extends BukkitRunnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ -490,6 +527,7 @@ public class HopTask extends BukkitRunnable {
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ -506,22 +544,17 @@ public class HopTask extends BukkitRunnable {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
return EpicHoppers.getInstance().isEpicFarming() && com.songoda.epicfarming.EpicFarming.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();
|
||||
private ItemStack[] getFarmContents(Block block) {
|
||||
return com.songoda.epicfarming.EpicFarming.getInstance().getFarmManager()
|
||||
.getFarm(block).getItems().toArray(new ItemStack[0]);
|
||||
}
|
||||
|
||||
}
|
@ -110,7 +110,7 @@ public class Methods {
|
||||
&& p.getItemInHand().getType() != Material.ENCHANTED_BOOK
|
||||
&& p.getItemInHand().getItemMeta().hasLore()) {
|
||||
for (String str : p.getItemInHand().getItemMeta().getLore()) {
|
||||
if (str.equals(Methods.formatText("&7Sync Touch")) || str.equals(Methods.formatText("&aSync Touch"))) {
|
||||
if (str.contains(Methods.formatText("&7Sync Touch")) || str.contains(Methods.formatText("&aSync Touch"))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -365,7 +365,52 @@ public class Methods {
|
||||
public static String makeReadable(Long time) {
|
||||
if (time == null)
|
||||
return "";
|
||||
return String.format("%d hour(s), %d min(s), %d sec(s)", TimeUnit.MILLISECONDS.toHours(time), TimeUnit.MILLISECONDS.toMinutes(time) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(time)), TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time)));
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
long days = TimeUnit.MILLISECONDS.toDays(time);
|
||||
long hours = TimeUnit.MILLISECONDS.toHours(time) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(time));
|
||||
long minutes = TimeUnit.MILLISECONDS.toMinutes(time) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(time));
|
||||
long seconds = TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time));
|
||||
|
||||
if (days != 0L)
|
||||
sb.append(" ").append(days).append("d");
|
||||
if (hours != 0L)
|
||||
sb.append(" ").append(hours).append("h");
|
||||
if (minutes != 0L)
|
||||
sb.append(" ").append(minutes).append("m");
|
||||
if (seconds != 0L)
|
||||
sb.append(" ").append(seconds).append("s");
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
public static long parseTime(String input) {
|
||||
long result = 0;
|
||||
StringBuilder number = new StringBuilder();
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
char c = input.charAt(i);
|
||||
if (Character.isDigit(c)) {
|
||||
number.append(c);
|
||||
} else if (Character.isLetter(c) && (number.length() > 0)) {
|
||||
result += convert(Integer.parseInt(number.toString()), c);
|
||||
number = new StringBuilder();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static long convert(long value, char unit) {
|
||||
switch (unit) {
|
||||
case 'd':
|
||||
return value * 1000 * 60 * 60 * 24;
|
||||
case 'h':
|
||||
return value * 1000 * 60 * 60;
|
||||
case 'm':
|
||||
return value * 1000 * 60;
|
||||
case 's':
|
||||
return value * 1000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,7 +33,7 @@ public class MySQLDatabase {
|
||||
"\t`whitelist` TEXT NULL,\n" +
|
||||
"\t`blacklist` TEXT NULL,\n" +
|
||||
"\t`void` TEXT NULL,\n" +
|
||||
"\t`black` TEXT NULL,\n" +
|
||||
"\t`black` TEXT NULL\n" +
|
||||
")");
|
||||
|
||||
connection.createStatement().execute("CREATE TABLE IF NOT EXISTS `" + instance.getConfig().getString("Database.Prefix") + "boosts` (\n" +
|
||||
|
@ -5,7 +5,10 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Chest;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -18,21 +21,80 @@ public class StorageContainerCache {
|
||||
|
||||
private final static Map<Block, Cache> inventoryCache = new HashMap<>();
|
||||
|
||||
// need to get the topmost inventory for a double chest, and save as that block
|
||||
public static Cache getCachedInventory(Block b) {
|
||||
Cache cache = inventoryCache.get(b);
|
||||
if (cache == null) {
|
||||
Material type = b.getType();
|
||||
if(type == Material.CHEST || type == Material.TRAPPED_CHEST) {
|
||||
Block b2 = findAdjacentDoubleChest(b);
|
||||
//System.out.println("Adjacent to " + b + " = " + b2);
|
||||
if(b2 != null && (cache = inventoryCache.get(b2)) != null) {
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
BlockState blockState = b.getState();
|
||||
if (blockState instanceof InventoryHolder) {
|
||||
//System.out.println("Load " + b.getLocation());
|
||||
inventoryCache.put(b, cache = new Cache(b, ((InventoryHolder) blockState).getInventory().getContents()));
|
||||
}
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for a double chest adjacent to a chest
|
||||
*
|
||||
* @param block
|
||||
* @return
|
||||
*/
|
||||
public static Block findAdjacentDoubleChest(Block block) {
|
||||
if(EpicHoppers.getInstance().isServerVersionAtLeast(ServerVersion.V1_13)) {
|
||||
final BlockData d = block.getBlockData();
|
||||
if (d instanceof Chest) {
|
||||
final Chest c = (Chest) d;
|
||||
if(c.getType() != Chest.Type.SINGLE) {
|
||||
// this is a double chest - check the other chest for registration data
|
||||
Block other = null;
|
||||
switch(c.getFacing()) {
|
||||
case SOUTH:
|
||||
other = block.getRelative(c.getType() != Chest.Type.RIGHT ? BlockFace.WEST : BlockFace.EAST);
|
||||
break;
|
||||
case NORTH:
|
||||
other = block.getRelative(c.getType() != Chest.Type.RIGHT ? BlockFace.EAST : BlockFace.WEST);
|
||||
break;
|
||||
case EAST:
|
||||
other = block.getRelative(c.getType() != Chest.Type.RIGHT ? BlockFace.SOUTH : BlockFace.NORTH);
|
||||
break;
|
||||
case WEST:
|
||||
other = block.getRelative(c.getType() != Chest.Type.RIGHT ? BlockFace.NORTH : BlockFace.SOUTH);
|
||||
}
|
||||
// double-check
|
||||
if (other != null && other.getType() == block.getType()) {
|
||||
return other;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// legacy check
|
||||
Material material = block.getType();
|
||||
BlockFace[] faces = new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST};
|
||||
for (BlockFace face : faces) {
|
||||
Block adjacentBlock = block.getRelative(face);
|
||||
|
||||
if (adjacentBlock.getType() == material) {
|
||||
return adjacentBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void update() {
|
||||
inventoryCache.entrySet().stream()
|
||||
.filter(e -> e.getValue().dirty)
|
||||
.forEach(e -> {
|
||||
//System.out.println("Update " + e.getKey().getLocation());
|
||||
// setContents makes a copy of every item whether it's needed or not
|
||||
//((InventoryHolder) e.getKey().getState()).getInventory().setContents(e.getValue().cachedInventory);
|
||||
// so let's only update what needs to be updated.
|
||||
@ -63,7 +125,9 @@ public class StorageContainerCache {
|
||||
this.type = type;
|
||||
this.cachedInventory = cachedInventory;
|
||||
this.cacheChanged = new boolean[cachedInventory.length];
|
||||
this.cacheAdded = new int[cachedInventory.length];
|
||||
}
|
||||
|
||||
public Cache(Block b, ItemStack[] cachedInventory) {
|
||||
this.block = b;
|
||||
this.type = b.getType();
|
||||
@ -208,6 +272,7 @@ public class StorageContainerCache {
|
||||
else
|
||||
check[3] = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case "SMOKER":
|
||||
case "BLAST_FURNACE":
|
||||
|
Loading…
Reference in New Issue
Block a user