diff --git a/src/api/java/appeng/api/crafting/ICraftingHelper.java b/src/api/java/appeng/api/crafting/ICraftingHelper.java index 909f26353..b55c5caf8 100644 --- a/src/api/java/appeng/api/crafting/ICraftingHelper.java +++ b/src/api/java/appeng/api/crafting/ICraftingHelper.java @@ -53,6 +53,8 @@ public interface ICraftingHelper { * @param stack If null, a new item will be created to hold the encoded pattern. * Otherwise the given item must already contains an encoded * pattern that will be overwritten. + * @throws IllegalArgumentException If either in or out contain only empty + * ItemStacks. * @return A new encoded pattern, or the given stack with the pattern encoded in * it. */ @@ -73,6 +75,8 @@ public interface ICraftingHelper { * operation by the ME system. * @param allowSubstitutes Controls whether the ME system will allow the use of * equivalent items to craft this recipe. + * @throws IllegalArgumentException If either in or out contain only empty + * ItemStacks. */ ItemStack encodeCraftingPattern(@Nullable ItemStack stack, ICraftingRecipe recipe, ItemStack[] in, ItemStack out, boolean allowSubstitutes); diff --git a/src/main/java/appeng/container/implementations/PatternTermContainer.java b/src/main/java/appeng/container/implementations/PatternTermContainer.java index 23f8d579b..0898e52bc 100644 --- a/src/main/java/appeng/container/implementations/PatternTermContainer.java +++ b/src/main/java/appeng/container/implementations/PatternTermContainer.java @@ -261,13 +261,19 @@ public class PatternTermContainer extends MEMonitorableContainer return new ItemStack[] { out }; } } else { + boolean hasValue = false; final ItemStack[] list = new ItemStack[3]; for (int i = 0; i < this.outputSlots.length; i++) { final ItemStack out = this.outputSlots[i].getStack(); list[i] = out; + if (!out.isEmpty()) { + hasValue = true; + } + } + if (hasValue) { + return list; } - return list; } return null; diff --git a/src/main/java/appeng/core/api/ApiCrafting.java b/src/main/java/appeng/core/api/ApiCrafting.java index e4f710bc2..b91888998 100644 --- a/src/main/java/appeng/core/api/ApiCrafting.java +++ b/src/main/java/appeng/core/api/ApiCrafting.java @@ -115,7 +115,12 @@ public class ApiCrafting implements ICraftingHelper { // We use the shared itemstack for an identity lookup. IAEItemStack ais = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(is); - return new CraftingPatternDetails(ais, world); + try { + return new CraftingPatternDetails(ais, world); + } catch (IllegalStateException e) { + AELog.warn("Could not decode an invalid pattern %s: %s", is, e); + return null; + } } private boolean attemptRecovery(EncodedPatternItem patternItem, ItemStack itemStack, World world) { diff --git a/src/main/java/appeng/items/misc/EncodedPatternItem.java b/src/main/java/appeng/items/misc/EncodedPatternItem.java index d3e1e504e..e4734d8de 100644 --- a/src/main/java/appeng/items/misc/EncodedPatternItem.java +++ b/src/main/java/appeng/items/misc/EncodedPatternItem.java @@ -307,14 +307,27 @@ public class EncodedPatternItem extends AEBaseItem { final ListNBT tagIn = new ListNBT(); final ListNBT tagOut = new ListNBT(); + boolean hasInput = false; for (final ItemStack i : in) { tagIn.add(createItemTag(i)); + if (!i.isEmpty()) { + hasInput = true; + } } + Preconditions.checkArgument(hasInput, "cannot encode a pattern that has no inputs."); + + boolean hasNonEmptyOutput = false; for (final ItemStack i : out) { tagOut.add(createItemTag(i)); + if (!i.isEmpty()) { + hasNonEmptyOutput = true; + } } + // Patterns without any outputs are corrupt! Never encode such a pattern. + Preconditions.checkArgument(hasNonEmptyOutput, "cannot encode a pattern that has no output."); + encodedValue.put(EncodedPatternItem.NBT_INGREDIENTS, tagIn); encodedValue.put(EncodedPatternItem.NBT_PRODUCTS, tagOut); return encodedValue;