Added throttling for network devices that can request autocrafting. Fixes #2010
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
### 1.6.6
|
### 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 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 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 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 a duplication bug with a disconnected Crafting Grid (raoulvdberge)
|
||||||
- Fixed oredict autocrafting sometimes reporting that a craftable item is missing (raoulvdberge)
|
- Fixed oredict autocrafting sometimes reporting that a craftable item is missing (raoulvdberge)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.api.autocrafting;
|
|||||||
|
|
||||||
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorListener;
|
import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorListener;
|
||||||
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask;
|
||||||
|
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
@@ -79,22 +80,24 @@ public interface ICraftingManager {
|
|||||||
/**
|
/**
|
||||||
* Schedules a crafting task if the task isn't scheduled yet.
|
* Schedules a crafting task if the task isn't scheduled yet.
|
||||||
*
|
*
|
||||||
|
* @param source the source
|
||||||
* @param stack the stack
|
* @param stack the stack
|
||||||
* @param amount the amount of items to request
|
* @param amount the amount of items to request
|
||||||
* @return the crafting task created, or null if no task is created
|
* @return the crafting task created, or null if no task is created
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@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.
|
* Schedules a crafting task if the task isn't scheduled yet.
|
||||||
*
|
*
|
||||||
|
* @param source the source
|
||||||
* @param stack the stack
|
* @param stack the stack
|
||||||
* @param amount the mB of the fluid to request
|
* @param amount the mB of the fluid to request
|
||||||
* @return the crafting task created, or null if no task is created
|
* @return the crafting task created, or null if no task is created
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
ICraftingTask request(FluidStack stack, int amount);
|
ICraftingTask request(INetworkNode source, FluidStack stack, int amount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks an incoming stack.
|
* Tracks an incoming stack.
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import com.raoulvdberge.refinedstorage.tile.TileController;
|
|||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraftforge.common.util.Constants;
|
import net.minecraftforge.common.util.Constants;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
@@ -25,6 +26,8 @@ import javax.annotation.Nullable;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class CraftingManager implements ICraftingManager {
|
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_TASKS = "Tasks";
|
||||||
private static final String NBT_TASK_TYPE = "Type";
|
private static final String NBT_TASK_TYPE = "Type";
|
||||||
private static final String NBT_TASK_DATA = "Task";
|
private static final String NBT_TASK_DATA = "Task";
|
||||||
@@ -40,6 +43,8 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
private List<UUID> tasksToCancel = new ArrayList<>();
|
private List<UUID> tasksToCancel = new ArrayList<>();
|
||||||
private NBTTagList tasksToRead;
|
private NBTTagList tasksToRead;
|
||||||
|
|
||||||
|
private Map<INetworkNode, Long> throttledRequesters = new HashMap<>();
|
||||||
|
|
||||||
private Set<ICraftingMonitorListener> listeners = new HashSet<>();
|
private Set<ICraftingMonitorListener> listeners = new HashSet<>();
|
||||||
|
|
||||||
public CraftingManager(TileController network) {
|
public CraftingManager(TileController network) {
|
||||||
@@ -222,7 +227,11 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@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()) {
|
for (ICraftingTask task : getTasks()) {
|
||||||
if (task.getRequested().getItem() != null) {
|
if (task.getRequested().getItem() != null) {
|
||||||
if (API.instance().getComparer().isEqualNoQuantity(task.getRequested().getItem(), stack)) {
|
if (API.instance().getComparer().isEqualNoQuantity(task.getRequested().getItem(), stack)) {
|
||||||
@@ -241,7 +250,11 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
this.add(task);
|
this.add(task);
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
|
} else {
|
||||||
|
throttle(source);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throttle(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +263,11 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@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()) {
|
for (ICraftingTask task : getTasks()) {
|
||||||
if (task.getRequested().getFluid() != null) {
|
if (task.getRequested().getFluid() != null) {
|
||||||
if (API.instance().getComparer().isEqual(task.getRequested().getFluid(), stack, IComparer.COMPARE_NBT)) {
|
if (API.instance().getComparer().isEqual(task.getRequested().getFluid(), stack, IComparer.COMPARE_NBT)) {
|
||||||
@@ -269,13 +286,30 @@ public class CraftingManager implements ICraftingManager {
|
|||||||
this.add(task);
|
this.add(task);
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
|
} else {
|
||||||
|
throttle(source);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throttle(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
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
|
@Override
|
||||||
public int track(ItemStack stack, int size) {
|
public int track(ItemStack stack, int size) {
|
||||||
for (ICraftingTask task : tasks.values()) {
|
for (ICraftingTask task : tasks.values()) {
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ public class NetworkNodeConstructor extends NetworkNode implements IComparable,
|
|||||||
world.setBlockState(front, state, 1 | 2);
|
world.setBlockState(front, state, 1 | 2);
|
||||||
}
|
}
|
||||||
} else if (upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) {
|
} 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)) {
|
} else if (upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) {
|
||||||
ItemStack craft = itemFilters.getStackInSlot(0);
|
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)) {
|
} else if (upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) {
|
||||||
ItemStack craft = itemFilters.getStackInSlot(0);
|
ItemStack craft = itemFilters.getStackInSlot(0);
|
||||||
|
|
||||||
network.getCraftingManager().request(craft, 1);
|
network.getCraftingManager().request(this, craft, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public class NetworkNodeExporter extends NetworkNode implements IComparable, ITy
|
|||||||
|
|
||||||
if (took == null) {
|
if (took == null) {
|
||||||
if (upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) {
|
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()) {
|
} else if (ItemHandlerHelper.insertItem(handler, took, true).isEmpty()) {
|
||||||
took = network.extractItem(slot, Math.min(slot.getMaxStackSize(), stackSize), compare, Action.PERFORM);
|
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)) {
|
} else if (upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) {
|
||||||
network.getCraftingManager().request(stack, toExtract);
|
network.getCraftingManager().request(this, stack, toExtract);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ public class NetworkNodeFluidInterface extends NetworkNode {
|
|||||||
delta -= result == null ? 0 : result.amount;
|
delta -= result == null ? 0 : result.amount;
|
||||||
|
|
||||||
if (delta > 0 && upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) {
|
if (delta > 0 && upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) {
|
||||||
network.getCraftingManager().request(wanted, delta);
|
network.getCraftingManager().request(this, wanted, delta);
|
||||||
}
|
}
|
||||||
} else if (delta < 0) {
|
} else if (delta < 0) {
|
||||||
FluidStack remainder = network.insertFluidTracked(got, Math.abs(delta));
|
FluidStack remainder = network.insertFluidTracked(got, Math.abs(delta));
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable {
|
|||||||
delta -= result == null ? 0 : result.getCount();
|
delta -= result == null ? 0 : result.getCount();
|
||||||
|
|
||||||
if (delta > 0 && upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) {
|
if (delta > 0 && upgrades.hasUpgrade(ItemUpgrade.TYPE_CRAFTING)) {
|
||||||
network.getCraftingManager().request(wanted, delta);
|
network.getCraftingManager().request(this, wanted, delta);
|
||||||
}
|
}
|
||||||
} else if (delta < 0) {
|
} else if (delta < 0) {
|
||||||
ItemStack remainder = network.insertItemTracked(got, Math.abs(delta));
|
ItemStack remainder = network.insertItemTracked(got, Math.abs(delta));
|
||||||
|
|||||||
Reference in New Issue
Block a user