diff --git a/CHANGELOG.md b/CHANGELOG.md index e7e06f032..194a9e49d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### 1.6.6 - Added new Crafter modes: ignore redstone signal, redstone signal unlocks autocrafting, redstone signal locks autocrafting and redstone pulse inserts next set (replacement for blocking mode) (raoulvdberge) - Added a config option to configure the autocrafting calculation timeout in milliseconds (raoulvdberge) +- Added throttling for network devices that can request autocrafting (raoulvdberge) - Fixed an autocrafting bug where it crashed when external inventories couldn't be filled (raoulvdberge) - Fixed a duplication bug with a disconnected Crafting Grid (raoulvdberge) - Fixed oredict autocrafting sometimes reporting that a craftable item is missing (raoulvdberge) diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java index 2da0e3196..eb34b271c 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java @@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.api.autocrafting; import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorListener; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; +import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.fluids.FluidStack; @@ -79,22 +80,24 @@ public interface ICraftingManager { /** * Schedules a crafting task if the task isn't scheduled yet. * + * @param source the source * @param stack the stack * @param amount the amount of items to request * @return the crafting task created, or null if no task is created */ @Nullable - ICraftingTask request(ItemStack stack, int amount); + ICraftingTask request(INetworkNode source, ItemStack stack, int amount); /** * Schedules a crafting task if the task isn't scheduled yet. * + * @param source the source * @param stack the stack * @param amount the mB of the fluid to request * @return the crafting task created, or null if no task is created */ @Nullable - ICraftingTask request(FluidStack stack, int amount); + ICraftingTask request(INetworkNode source, FluidStack stack, int amount); /** * Tracks an incoming stack. diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java index de69ae95e..8a4767dd8 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java @@ -16,6 +16,7 @@ import com.raoulvdberge.refinedstorage.tile.TileController; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraft.server.MinecraftServer; import net.minecraftforge.common.util.Constants; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.items.IItemHandlerModifiable; @@ -25,6 +26,8 @@ import javax.annotation.Nullable; import java.util.*; public class CraftingManager implements ICraftingManager { + private static final int THROTTLE_DELAY_MS = 3000; + private static final String NBT_TASKS = "Tasks"; private static final String NBT_TASK_TYPE = "Type"; private static final String NBT_TASK_DATA = "Task"; @@ -40,6 +43,8 @@ public class CraftingManager implements ICraftingManager { private List tasksToCancel = new ArrayList<>(); private NBTTagList tasksToRead; + private Map throttledRequesters = new HashMap<>(); + private Set listeners = new HashSet<>(); public CraftingManager(TileController network) { @@ -222,7 +227,11 @@ public class CraftingManager implements ICraftingManager { @Override @Nullable - public ICraftingTask request(ItemStack stack, int amount) { + public ICraftingTask request(INetworkNode source, ItemStack stack, int amount) { + if (isThrottled(source)) { + return null; + } + for (ICraftingTask task : getTasks()) { if (task.getRequested().getItem() != null) { if (API.instance().getComparer().isEqualNoQuantity(task.getRequested().getItem(), stack)) { @@ -241,7 +250,11 @@ public class CraftingManager implements ICraftingManager { this.add(task); return task; + } else { + throttle(source); } + } else { + throttle(source); } } @@ -250,7 +263,11 @@ public class CraftingManager implements ICraftingManager { @Nullable @Override - public ICraftingTask request(FluidStack stack, int amount) { + public ICraftingTask request(INetworkNode source, FluidStack stack, int amount) { + if (isThrottled(source)) { + return null; + } + for (ICraftingTask task : getTasks()) { if (task.getRequested().getFluid() != null) { if (API.instance().getComparer().isEqual(task.getRequested().getFluid(), stack, IComparer.COMPARE_NBT)) { @@ -269,13 +286,30 @@ public class CraftingManager implements ICraftingManager { this.add(task); return task; + } else { + throttle(source); } + } else { + throttle(source); } } return null; } + private void throttle(INetworkNode node) { + throttledRequesters.put(node, MinecraftServer.getCurrentTimeMillis()); + } + + private boolean isThrottled(INetworkNode node) { + Long throttledSince = throttledRequesters.get(node); + if (throttledSince == null) { + return false; + } + + return MinecraftServer.getCurrentTimeMillis() - throttledSince < THROTTLE_DELAY_MS; + } + @Override public int track(ItemStack stack, int size) { for (ICraftingTask task : tasks.values()) { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeConstructor.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeConstructor.java index 95b1ff00d..0abb1ca89 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeConstructor.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeConstructor.java @@ -137,7 +137,7 @@ public class NetworkNodeConstructor extends NetworkNode implements IComparable, world.setBlockState(front, state, 1 | 2); } } else if (upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) { - network.getCraftingManager().request(stack, Fluid.BUCKET_VOLUME); + network.getCraftingManager().request(this, stack, Fluid.BUCKET_VOLUME); } } } @@ -227,7 +227,7 @@ public class NetworkNodeConstructor extends NetworkNode implements IComparable, } else if (upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) { ItemStack craft = itemFilters.getStackInSlot(0); - network.getCraftingManager().request(craft, 1); + network.getCraftingManager().request(this, craft, 1); } } @@ -239,7 +239,7 @@ public class NetworkNodeConstructor extends NetworkNode implements IComparable, } else if (upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) { ItemStack craft = itemFilters.getStackInSlot(0); - network.getCraftingManager().request(craft, 1); + network.getCraftingManager().request(this, craft, 1); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeExporter.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeExporter.java index 1836b1acc..5cc96d649 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeExporter.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeExporter.java @@ -89,7 +89,7 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy if (took == null) { if (upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) { - network.getCraftingManager().request(slot, stackSize); + network.getCraftingManager().request(this, slot, stackSize); } } else if (ItemHandlerHelper.insertItem(handler, took, true).isEmpty()) { took = network.extractItem(slot, Math.min(slot.getMaxStackSize(), stackSize), compare, Action.PERFORM); @@ -142,7 +142,7 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy } } } else if (upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) { - network.getCraftingManager().request(stack, toExtract); + network.getCraftingManager().request(this, stack, toExtract); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidInterface.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidInterface.java index 67ec65a50..881ae7637 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidInterface.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidInterface.java @@ -144,7 +144,7 @@ public class NetworkNodeFluidInterface extends NetworkNode { delta -= result == null ? 0 : result.amount; if (delta > 0 && upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) { - network.getCraftingManager().request(wanted, delta); + network.getCraftingManager().request(this, wanted, delta); } } else if (delta < 0) { FluidStack remainder = network.insertFluidTracked(got, Math.abs(delta)); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeInterface.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeInterface.java index 1472d162b..822d937ec 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeInterface.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeInterface.java @@ -119,7 +119,7 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable { delta -= result == null ? 0 : result.getCount(); if (delta > 0 && upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) { - network.getCraftingManager().request(wanted, delta); + network.getCraftingManager().request(this, wanted, delta); } } else if (delta < 0) { ItemStack remainder = network.insertItemTracked(got, Math.abs(delta));