Actual fix for #2051

This commit is contained in:
raoulvdberge
2018-11-21 19:12:10 +01:00
parent 7988b0f789
commit 5851bde41f
2 changed files with 65 additions and 91 deletions

View File

@@ -32,12 +32,15 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class CraftingTask implements ICraftingTask {
private static final String NBT_REQUESTED = "Requested";
@@ -515,7 +518,7 @@ public class CraftingTask implements ICraftingTask {
fluidsToReceive.add(output);
}
processing.add(new Processing(pattern, itemsToReceive, fluidsToReceive, new ArrayList<>(itemsToExtract.getStacks()), new ArrayList<>(fluidsToExtract.getStacks()), root));
processing.add(new Processing(pattern, itemsToReceive, fluidsToReceive, itemsToExtract, fluidsToExtract, root));
} else {
if (!fluidsToExtract.isEmpty()) {
throw new IllegalStateException("Cannot extract fluids in normal pattern!");
@@ -678,7 +681,7 @@ public class CraftingTask implements ICraftingTask {
} else {
boolean hasAll = true;
for (ItemStack need : p.getItemsToPut()) {
for (ItemStack need : p.getItemsToPut().getStacks()) {
if (p.getPattern().getContainer().getConnectedInventory() == null) {
p.setState(ProcessingState.MACHINE_NONE);
} else {
@@ -698,7 +701,11 @@ public class CraftingTask implements ICraftingTask {
}
}
for (FluidStack need : p.getFluidsToPut()) {
if (hasAll && p.getState() == ProcessingState.READY && !insertIntoInventory(p.getPattern().getContainer().getConnectedInventory(), new ArrayDeque<>(p.getItemsToPut().getStacks()), Action.SIMULATE)) {
p.setState(ProcessingState.MACHINE_DOES_NOT_ACCEPT);
}
for (FluidStack need : p.getFluidsToPut().getStacks()) {
if (p.getPattern().getContainer().getConnectedFluidInventory() == null) {
p.setState(ProcessingState.MACHINE_NONE);
} else {
@@ -719,37 +726,22 @@ public class CraftingTask implements ICraftingTask {
}
if (p.getState() == ProcessingState.READY && hasAll) {
boolean abort = false;
for (int i = 0; i < p.getItemsToPut().size(); ++i) {
ItemStack need = p.getItemsToPut().get(i);
Deque<ItemStack> toInsert = new ArrayDeque<>();
for (ItemStack need : p.getItemsToPut().getStacks()) {
ItemStack result = this.internalStorage.extract(need, need.getCount(), DEFAULT_EXTRACT_FLAGS, Action.PERFORM);
if (result == null || result.getCount() != need.getCount()) {
throw new IllegalStateException("The internal crafting inventory reported that " + need + " was available but we got " + result);
}
ItemStack remainder = ItemHandlerHelper.insertItem(p.getPattern().getContainer().getConnectedInventory(), result, false);
if (!remainder.isEmpty()) {
LOGGER.warn("In a simulation, " + p.getPattern().getContainer().getConnectedInventory() + " reported that we could insert " + result + " but we got " + remainder + " as a remainder");
this.internalStorage.insert(remainder, remainder.getCount(), Action.PERFORM);
p.getItemsToPut().set(i, remainder);
abort = true;
break;
}
toInsert.add(need);
}
if (abort) {
continue;
if (!insertIntoInventory(p.getPattern().getContainer().getConnectedInventory(), toInsert, Action.PERFORM)) {
LOGGER.warn(p.getPattern().getContainer().getConnectedInventory() + " unexpectedly didn't accept items, the remainder has been voided!");
}
for (int i = 0; i < p.getFluidsToPut().size(); ++i) {
FluidStack need = p.getFluidsToPut().get(i);
for (FluidStack need : p.getFluidsToPut().getStacks()) {
FluidStack result = this.internalFluidStorage.extract(need, need.amount, IComparer.COMPARE_NBT, Action.PERFORM);
if (result == null || result.amount != need.amount) {
throw new IllegalStateException("The internal crafting inventory reported that " + need + " was available but we got " + result);
@@ -757,22 +749,10 @@ public class CraftingTask implements ICraftingTask {
int filled = p.getPattern().getContainer().getConnectedFluidInventory().fill(result, true);
if (filled != result.amount) {
LOGGER.warn("In a simulation, " + p.getPattern().getContainer().getConnectedFluidInventory() + " reported that we could fill " + result + " but we only filled " + filled);
this.internalFluidStorage.insert(result, result.amount - filled, Action.PERFORM);
p.getFluidsToPut().set(i, StackUtils.copy(result, result.amount - filled));
abort = true;
break;
LOGGER.warn(p.getPattern().getContainer().getConnectedFluidInventory() + " unexpectedly didn't accept fluids, the remainder has been voided!");
}
}
if (abort) {
continue;
}
p.setState(ProcessingState.EXTRACTED_ALL);
p.getPattern().getContainer().onUsedForProcessing();
@@ -786,6 +766,43 @@ public class CraftingTask implements ICraftingTask {
}
}
private static boolean insertIntoInventory(@Nullable IItemHandler dest, Deque<ItemStack> stacks, Action action) {
if (dest == null) {
return false;
}
ItemStack current = stacks.poll();
List<Integer> availableSlots = IntStream.range(0, dest.getSlots()).boxed().collect(Collectors.toList());
while (current != null && !availableSlots.isEmpty()) {
ItemStack remainder = ItemStack.EMPTY;
for (int i = 0; i < availableSlots.size(); ++i) {
int slot = availableSlots.get(i);
// .copy() is mandatory!
remainder = dest.insertItem(slot, current.copy(), action == Action.SIMULATE);
// If we inserted *something*
if (remainder.isEmpty() || current.getCount() != remainder.getCount()) {
availableSlots.remove(i);
break;
}
}
if (remainder.isEmpty()) { // If we inserted successfully, get a next stack.
current = stacks.poll();
} else if (current.getCount() == remainder.getCount()) { // If we didn't insert anything over ALL these slots, stop here.
break;
} else { // If we didn't insert all, continue with other slots and use our remainder.
current = remainder;
}
}
return current == null && stacks.isEmpty();
}
@Override
public boolean update() {
if (hasMissing()) {
@@ -1024,7 +1041,7 @@ public class CraftingTask implements ICraftingTask {
}
if (processing.getState() == ProcessingState.EXTRACTED_ALL) {
for (ItemStack put : processing.getItemsToPut()) {
for (ItemStack put : processing.getItemsToPut().getStacks()) {
elements.add(new CraftingMonitorElementItemRender(put, 0, 0, put.getCount(), 0, 0));
}
} else if (processing.getState() == ProcessingState.READY || processing.getState() == ProcessingState.MACHINE_DOES_NOT_ACCEPT || processing.getState() == ProcessingState.MACHINE_NONE || processing.getState() == ProcessingState.LOCKED) {
@@ -1060,7 +1077,7 @@ public class CraftingTask implements ICraftingTask {
}
if (processing.getState() == ProcessingState.EXTRACTED_ALL) {
for (FluidStack put : processing.getFluidsToPut()) {
for (FluidStack put : processing.getFluidsToPut().getStacks()) {
elements.add(new CraftingMonitorElementFluidRender(put, 0, 0, put.amount, 0, 0));
}
} else if (processing.getState() == ProcessingState.READY || processing.getState() == ProcessingState.MACHINE_DOES_NOT_ACCEPT || processing.getState() == ProcessingState.MACHINE_NONE) {

View File

@@ -4,16 +4,11 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern;
import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import com.raoulvdberge.refinedstorage.util.StackUtils;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fluids.FluidStack;
import java.util.ArrayList;
import java.util.List;
class Processing {
private static final String NBT_PATTERN = "Pattern";
private static final String NBT_ITEMS_TO_RECEIVE = "ItemsToReceive";
@@ -26,12 +21,12 @@ class Processing {
private ICraftingPattern pattern;
private IStackList<ItemStack> itemsToReceive;
private IStackList<FluidStack> fluidsToReceive;
private ArrayList<ItemStack> itemsToPut;
private ArrayList<FluidStack> fluidsToPut;
private IStackList<ItemStack> itemsToPut;
private IStackList<FluidStack> fluidsToPut;
private ProcessingState state = ProcessingState.READY;
private boolean root;
public Processing(ICraftingPattern pattern, IStackList<ItemStack> itemsToReceive, IStackList<FluidStack> fluidsToReceive, ArrayList<ItemStack> itemsToPut, ArrayList<FluidStack> fluidsToPut, boolean root) {
public Processing(ICraftingPattern pattern, IStackList<ItemStack> itemsToReceive, IStackList<FluidStack> fluidsToReceive, IStackList<ItemStack> itemsToPut, IStackList<FluidStack> fluidsToPut, boolean root) {
this.pattern = pattern;
this.itemsToReceive = itemsToReceive;
this.fluidsToReceive = fluidsToReceive;
@@ -45,33 +40,8 @@ class Processing {
this.itemsToReceive = CraftingTask.readItemStackList(tag.getTagList(NBT_ITEMS_TO_RECEIVE, Constants.NBT.TAG_COMPOUND));
this.fluidsToReceive = CraftingTask.readFluidStackList(tag.getTagList(NBT_FLUIDS_TO_RECEIVE, Constants.NBT.TAG_COMPOUND));
this.root = tag.getBoolean(NBT_ROOT);
this.itemsToPut = new ArrayList<>();
NBTTagList itemsToPutList = tag.getTagList(NBT_ITEMS_TO_PUT, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < itemsToPutList.tagCount(); ++i) {
ItemStack stack = StackUtils.deserializeStackFromNbt(itemsToPutList.getCompoundTagAt(i));
if (stack.isEmpty()) {
throw new CraftingTaskReadException("Stack is empty!");
}
itemsToPut.add(stack);
}
this.fluidsToPut = new ArrayList<>();
NBTTagList fluidsToPutList = tag.getTagList(NBT_FLUIDS_TO_PUT, Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < fluidsToPutList.tagCount(); ++i) {
FluidStack stack = FluidStack.loadFluidStackFromNBT(fluidsToPutList.getCompoundTagAt(i));
if (stack == null) {
throw new CraftingTaskReadException("Stack is empty!");
}
fluidsToPut.add(stack);
}
this.itemsToPut = CraftingTask.readItemStackList(tag.getTagList(NBT_ITEMS_TO_PUT, Constants.NBT.TAG_COMPOUND));
this.fluidsToPut = CraftingTask.readFluidStackList(tag.getTagList(NBT_FLUIDS_TO_PUT, Constants.NBT.TAG_COMPOUND));
this.state = ProcessingState.values()[tag.getInteger(NBT_STATE)];
}
@@ -87,11 +57,11 @@ class Processing {
return fluidsToReceive;
}
public List<ItemStack> getItemsToPut() {
public IStackList<ItemStack> getItemsToPut() {
return itemsToPut;
}
public List<FluidStack> getFluidsToPut() {
public IStackList<FluidStack> getFluidsToPut() {
return fluidsToPut;
}
@@ -114,21 +84,8 @@ class Processing {
tag.setTag(NBT_ITEMS_TO_RECEIVE, CraftingTask.writeItemStackList(itemsToReceive));
tag.setTag(NBT_FLUIDS_TO_RECEIVE, CraftingTask.writeFluidStackList(fluidsToReceive));
tag.setBoolean(NBT_ROOT, root);
NBTTagList itemsToPutList = new NBTTagList();
for (ItemStack stack : this.itemsToPut) {
itemsToPutList.appendTag(StackUtils.serializeStackToNbt(stack));
}
tag.setTag(NBT_ITEMS_TO_PUT, itemsToPutList);
NBTTagList fluidsToPutList = new NBTTagList();
for (FluidStack stack : this.fluidsToPut) {
fluidsToPutList.appendTag(stack.writeToNBT(new NBTTagCompound()));
}
tag.setTag(NBT_FLUIDS_TO_PUT, fluidsToPutList);
tag.setTag(NBT_ITEMS_TO_PUT, CraftingTask.writeItemStackList(itemsToPut));
tag.setTag(NBT_FLUIDS_TO_PUT, CraftingTask.writeFluidStackList(fluidsToPut));
tag.setInteger(NBT_STATE, state.ordinal());
return tag;