Added throttling for network devices that can request autocrafting. Fixes #2010

This commit is contained in:
raoulvdberge
2018-09-28 21:56:33 +02:00
parent fef4155f2c
commit 7b8960de94
7 changed files with 49 additions and 11 deletions

View File

@@ -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)

View File

@@ -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.

View File

@@ -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<UUID> tasksToCancel = new ArrayList<>();
private NBTTagList tasksToRead;
private Map<INetworkNode, Long> throttledRequesters = new HashMap<>();
private Set<ICraftingMonitorListener> 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()) {

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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));

View File

@@ -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));