diff --git a/CHANGELOG.md b/CHANGELOG.md index 61a20aaed..43ba1da21 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ - Removed Storage Drawers integration (you can still attach an External Storage to drawers, though) (raoulvdberge) - Removed blocking mode in autocrafting (raoulvdberge) - Removed the Wrench (raoulvdberge) +- Rewrote autocrafting (raoulvdberge) +- Autocrafting tasks that take longer than 5 seconds to calculate are automatically stopped to avoid server strain (raoulvdberge) - Added new storage disk system where the storage disk data (items, fluids) are stored off the disk itself, in another file (refinedstorage_disks.dat). The disk itself only stores its ID (raoulvdberge) - Changed fluid storage progression to be 64k - 256k - 1024k - 4096k (raoulvdberge) - You can no longer put a Filter in filter slots to gain additional filter slots (raoulvdberge) diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/CraftingTaskErrorType.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/CraftingTaskErrorType.java new file mode 100644 index 000000000..29f3ae705 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/CraftingTaskErrorType.java @@ -0,0 +1,15 @@ +package com.raoulvdberge.refinedstorage.api.autocrafting.task; + +/** + * The error type. + */ +public enum CraftingTaskErrorType { + /** + * When the crafting task would cause too much server strain or is too complex. + */ + TOO_COMPLEX, + /** + * When one of the used patterns during the calculation reuses itself again and would cause an infinite loop. + */ + RECURSIVE +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java index dbf61fd41..5aa43aed8 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java @@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.api.util.IStackList; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import javax.annotation.Nullable; import java.util.List; /** @@ -15,8 +16,11 @@ import java.util.List; public interface ICraftingTask { /** * Calculates what this task will do, but doesn't run the task yet. + * + * @return the error, or null if there was no error */ - void calculate(); + @Nullable + ICraftingTaskError calculate(); /** * Updates this task. diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTaskError.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTaskError.java new file mode 100644 index 000000000..d9e35f9da --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTaskError.java @@ -0,0 +1,23 @@ +package com.raoulvdberge.refinedstorage.api.autocrafting.task; + +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; + +import javax.annotation.Nullable; + +/** + * Returned from {@link ICraftingTask#calculate()} when an error occurs during the calculation. + */ +public interface ICraftingTaskError { + /** + * @return the type + */ + CraftingTaskErrorType getType(); + + /** + * If this error type is a {@link CraftingTaskErrorType#RECURSIVE}, the recursed pattern will be returned here. + * + * @return the recursed pattern, or null if this error is not {@link CraftingTaskErrorType#RECURSIVE} + */ + @Nullable + ICraftingPattern getRecursedPattern(); +} 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 f05daf89b..9f1b16550 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java @@ -6,6 +6,7 @@ import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContaine import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorListener; import com.raoulvdberge.refinedstorage.api.autocrafting.registry.ICraftingTaskFactory; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; +import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.apiimpl.API; @@ -138,12 +139,13 @@ public class CraftingManager implements ICraftingManager { ICraftingTask task = create(stack, toSchedule); if (task != null) { - task.calculate(); + ICraftingTaskError error = task.calculate(); - this.add(task); - this.onTaskChanged(); + if (error == null) { + this.add(task); - return task; + return task; + } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/preview/CraftingPreviewElementError.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/preview/CraftingPreviewElementError.java index f9266e70e..d6697c418 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/preview/CraftingPreviewElementError.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/preview/CraftingPreviewElementError.java @@ -1,6 +1,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview; import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement; +import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskErrorType; import com.raoulvdberge.refinedstorage.api.render.IElementDrawers; import io.netty.buffer.ByteBuf; import net.minecraft.item.Item; @@ -11,9 +12,11 @@ import net.minecraftforge.fml.common.network.ByteBufUtils; public class CraftingPreviewElementError implements ICraftingPreviewElement { public static final String ID = "error"; + private CraftingTaskErrorType type; private ItemStack stack; - public CraftingPreviewElementError(ItemStack stack) { + public CraftingPreviewElementError(CraftingTaskErrorType type, ItemStack stack) { + this.type = type; this.stack = stack; } @@ -39,17 +42,25 @@ public class CraftingPreviewElementError implements ICraftingPreviewElement= 0 && errorIdx < CraftingTaskErrorType.values().length ? CraftingTaskErrorType.values()[errorIdx] : CraftingTaskErrorType.TOO_COMPLEX; + Item item = Item.getItemById(buf.readInt()); int meta = buf.readInt(); NBTTagCompound tag = ByteBufUtils.readTag(buf); @@ -57,7 +68,7 @@ public class CraftingPreviewElementError implements ICraftingPreviewElement steps = new LinkedList<>(); private CraftingInserter inserter; + private Set patternsUsed = new HashSet<>(); private int ticks = 0; + private long calculationStarted; private IStackList toTake = API.instance().createItemStackList(); private IStackList missing = API.instance().createItemStackList(); @@ -49,7 +57,10 @@ public class CraftingTask implements ICraftingTask { } @Override - public void calculate() { + @Nullable + public ICraftingTaskError calculate() { + this.calculationStarted = System.currentTimeMillis(); + int qty = this.quantity; int qtyPerCraft = getQuantityPerCraft(pattern, requested); int crafted = 0; @@ -58,7 +69,13 @@ public class CraftingTask implements ICraftingTask { IStackList storage = network.getItemStorageCache().getList().copy(); while (qty > 0) { - this.steps.add(calculateInternal(storage, results, pattern)); + Pair result = calculateInternal(storage, results, pattern); + + if (result.getRight() != null) { + return result.getRight(); + } + + this.steps.add(result.getLeft()); qty -= qtyPerCraft; @@ -66,9 +83,19 @@ public class CraftingTask implements ICraftingTask { } this.toCraft.add(requested, crafted); + + return null; } - private CraftingStep calculateInternal(IStackList mutatedStorage, IStackList results, ICraftingPattern pattern) { + private Pair calculateInternal(IStackList mutatedStorage, IStackList results, ICraftingPattern pattern) { + if (System.currentTimeMillis() - calculationStarted > CALCULATION_TIMEOUT_MS) { + return Pair.of(null, new CraftingTaskError(CraftingTaskErrorType.TOO_COMPLEX)); + } + + if (!patternsUsed.add(pattern)) { + return Pair.of(null, new CraftingTaskError(CraftingTaskErrorType.RECURSIVE, pattern)); + } + IStackList itemsToExtract = API.instance().createItemStackList(); NonNullList took = NonNullList.create(); @@ -140,7 +167,13 @@ public class CraftingTask implements ICraftingTask { if (subPattern != null) { while ((fromSelf == null ? 0 : fromSelf.getCount()) < remaining) { - this.steps.add(calculateInternal(mutatedStorage, results, subPattern)); + Pair result = calculateInternal(mutatedStorage, results, subPattern); + + if (result.getRight() != null) { + return Pair.of(null, result.getRight()); + } + + this.steps.add(result.getLeft()); fromSelf = results.get(possibleInput); if (fromSelf == null) { @@ -161,12 +194,14 @@ public class CraftingTask implements ICraftingTask { } } + patternsUsed.remove(pattern); + if (pattern.isProcessing()) { for (ItemStack output : pattern.getOutputs()) { results.add(output); } - return new CraftingStepProcess(pattern, network, new ArrayList<>(itemsToExtract.getStacks())); + return Pair.of(new CraftingStepProcess(pattern, network, new ArrayList<>(itemsToExtract.getStacks())), null); } else { results.add(pattern.getOutput(took)); @@ -174,7 +209,7 @@ public class CraftingTask implements ICraftingTask { results.add(byproduct); } - return new CraftingStepCraft(pattern, inserter, network, new ArrayList<>(itemsToExtract.getStacks()), took); + return Pair.of(new CraftingStepCraft(pattern, inserter, network, new ArrayList<>(itemsToExtract.getStacks()), took), null); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTaskError.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTaskError.java new file mode 100644 index 000000000..73fa4e063 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTaskError.java @@ -0,0 +1,32 @@ +package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task; + +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; +import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskErrorType; +import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError; + +import javax.annotation.Nullable; + +public class CraftingTaskError implements ICraftingTaskError { + private CraftingTaskErrorType type; + private ICraftingPattern recursedPattern; + + public CraftingTaskError(CraftingTaskErrorType type) { + this.type = type; + } + + public CraftingTaskError(CraftingTaskErrorType type, ICraftingPattern recursedPattern) { + this.type = type; + this.recursedPattern = recursedPattern; + } + + @Override + public CraftingTaskErrorType getType() { + return type; + } + + @Override + @Nullable + public ICraftingPattern getRecursedPattern() { + return recursedPattern; + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandler.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandler.java index 2bcf0b951..887853acf 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandler.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/grid/handler/ItemGridHandler.java @@ -4,6 +4,7 @@ import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; +import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError; import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler; import com.raoulvdberge.refinedstorage.api.network.item.INetworkItem; @@ -11,6 +12,7 @@ import com.raoulvdberge.refinedstorage.api.network.item.NetworkItemAction; import com.raoulvdberge.refinedstorage.api.network.security.Permission; import com.raoulvdberge.refinedstorage.api.util.IStackList; import com.raoulvdberge.refinedstorage.apiimpl.API; +import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementError; import com.raoulvdberge.refinedstorage.network.MessageGridCraftingPreviewResponse; import com.raoulvdberge.refinedstorage.network.MessageGridCraftingStartResponse; import com.raoulvdberge.refinedstorage.util.StackUtils; @@ -21,6 +23,8 @@ import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemHandlerHelper; +import java.util.Collections; + public class ItemGridHandler implements IItemGridHandler { private INetwork network; @@ -187,9 +191,11 @@ public class ItemGridHandler implements IItemGridHandler { return; } - task.calculate(); + ICraftingTaskError error = task.calculate(); - if (noPreview && task.getMissing().isEmpty()) { + if (error != null) { + RS.INSTANCE.network.sendTo(new MessageGridCraftingPreviewResponse(Collections.singletonList(new CraftingPreviewElementError(error.getType(), error.getRecursedPattern() == null ? ItemStack.EMPTY : error.getRecursedPattern().getStack())), hash, quantity), player); + } else if (noPreview && task.getMissing().isEmpty()) { network.getCraftingManager().add(task); RS.INSTANCE.network.sendTo(new MessageGridCraftingStartResponse(), player); @@ -230,9 +236,10 @@ public class ItemGridHandler implements IItemGridHandler { return; } - task.calculate(); - - network.getCraftingManager().add(task); + ICraftingTaskError error = task.calculate(); + if (error == null) { + network.getCraftingManager().add(task); + } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingPreview.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingPreview.java index a097ccaed..48055f205 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingPreview.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiCraftingPreview.java @@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.gui; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement; +import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskErrorType; import com.raoulvdberge.refinedstorage.api.render.IElementDrawer; import com.raoulvdberge.refinedstorage.api.render.IElementDrawers; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementError; @@ -25,6 +26,7 @@ import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.client.FMLClientHandler; import org.lwjgl.input.Keyboard; +import javax.annotation.Nullable; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -77,7 +79,7 @@ public class GuiCraftingPreview extends GuiBase { public void init(int x, int y) { cancelButton = addButton(x + 16, y + 144, 50, 20, t("gui.cancel")); startButton = addButton(x + 85, y + 144, 50, 20, t("misc.refinedstorage:start")); - startButton.enabled = stacks.stream().noneMatch(ICraftingPreviewElement::hasMissing); + startButton.enabled = stacks.stream().noneMatch(ICraftingPreviewElement::hasMissing) && getErrorType() == null; } @Override @@ -87,13 +89,18 @@ public class GuiCraftingPreview extends GuiBase { scrollbar.setMaxOffset(getRows() - VISIBLE_ROWS); } - if (startButton != null && !startButton.enabled && isCtrlKeyDown() && isShiftKeyDown()) { + if (startButton != null && !startButton.enabled && isCtrlKeyDown() && isShiftKeyDown() && getErrorType() == null) { startButton.enabled = true; } } - private boolean hasErrored() { - return stacks.size() == 1 && stacks.get(0) instanceof CraftingPreviewElementError; + @Nullable + private CraftingTaskErrorType getErrorType() { + if (stacks.size() == 1 && stacks.get(0) instanceof CraftingPreviewElementError) { + return ((CraftingPreviewElementError) stacks.get(0)).getType(); + } + + return null; } @Override @@ -102,7 +109,7 @@ public class GuiCraftingPreview extends GuiBase { drawTexture(x, y, 0, 0, screenWidth, screenHeight); - if (hasErrored()) { + if (getErrorType() != null) { drawRect(x + 7, y + 20, x + 142, y + 139, 0xFFDBDBDB); } } @@ -116,36 +123,51 @@ public class GuiCraftingPreview extends GuiBase { float scale = fontRenderer.getUnicodeFlag() ? 1F : 0.5F; - if (hasErrored()) { + if (getErrorType() != null) { GlStateManager.pushMatrix(); GlStateManager.scale(scale, scale, 1); - drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 10, scale), t("gui.refinedstorage:crafting_preview.error.0")); - drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 20, scale), t("gui.refinedstorage:crafting_preview.error.1")); - drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 30, scale), t("gui.refinedstorage:crafting_preview.error.2")); - drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 40, scale), t("gui.refinedstorage:crafting_preview.error.3")); - drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 50, scale), t("gui.refinedstorage:crafting_preview.error.4")); + drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 11, scale), t("gui.refinedstorage:crafting_preview.error")); - drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 60, scale), t("gui.refinedstorage:crafting_preview.error.5")); + switch (getErrorType()) { + case RECURSIVE: { + drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 21, scale), t("gui.refinedstorage:crafting_preview.error.recursive.0")); + drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 31, scale), t("gui.refinedstorage:crafting_preview.error.recursive.1")); + drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 41, scale), t("gui.refinedstorage:crafting_preview.error.recursive.2")); + drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 51, scale), t("gui.refinedstorage:crafting_preview.error.recursive.3")); - GlStateManager.popMatrix(); + drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 61, scale), t("gui.refinedstorage:crafting_preview.error.recursive.4")); - ICraftingPattern pattern = ItemPattern.getPatternFromCache(parent.mc.world, (ItemStack) stacks.get(0).getElement()); - - int yy = 80; - for (ItemStack output : pattern.getOutputs()) { - if (output != null) { - GlStateManager.pushMatrix(); - GlStateManager.scale(scale, scale, 1); - drawString(RenderUtils.getOffsetOnScale(x + 25, scale), RenderUtils.getOffsetOnScale(yy + 7, scale), output.getDisplayName()); GlStateManager.popMatrix(); - RenderHelper.enableGUIStandardItemLighting(); - GlStateManager.enableDepth(); - drawItem(x + 5, yy, output); - RenderHelper.disableStandardItemLighting(); + ICraftingPattern pattern = ItemPattern.getPatternFromCache(parent.mc.world, (ItemStack) stacks.get(0).getElement()); - yy += 17; + int yy = 83; + for (ItemStack output : pattern.getOutputs()) { + if (output != null) { + GlStateManager.pushMatrix(); + GlStateManager.scale(scale, scale, 1); + drawString(RenderUtils.getOffsetOnScale(x + 25, scale), RenderUtils.getOffsetOnScale(yy + 6, scale), output.getDisplayName()); + GlStateManager.popMatrix(); + + RenderHelper.enableGUIStandardItemLighting(); + GlStateManager.enableDepth(); + drawItem(x + 5, yy, output); + RenderHelper.disableStandardItemLighting(); + + yy += 17; + } + } + + break; + } + case TOO_COMPLEX: { + drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 21, scale), t("gui.refinedstorage:crafting_preview.error.too_complex.0")); + drawString(RenderUtils.getOffsetOnScale(x + 5, scale), RenderUtils.getOffsetOnScale(y + 31, scale), t("gui.refinedstorage:crafting_preview.error.too_complex.1")); + + GlStateManager.popMatrix(); + + break; } } } else { diff --git a/src/main/java/com/raoulvdberge/refinedstorage/integration/oc/EnvironmentNetwork.java b/src/main/java/com/raoulvdberge/refinedstorage/integration/oc/EnvironmentNetwork.java index 04564bcb7..e2020bc67 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/integration/oc/EnvironmentNetwork.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/integration/oc/EnvironmentNetwork.java @@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.integration.oc; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; +import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.apiimpl.API; @@ -129,9 +130,11 @@ public class EnvironmentNetwork extends AbstractManagedEnvironment { throw new IllegalArgumentException("Could not create crafting task"); } - task.calculate(); + ICraftingTaskError error = task.calculate(); - node.getNetwork().getCraftingManager().add(task); + if (error == null) { + node.getNetwork().getCraftingManager().add(task); + } return new Object[]{}; } diff --git a/src/main/resources/assets/refinedstorage/lang/en_us.lang b/src/main/resources/assets/refinedstorage/lang/en_us.lang index 003e1cd3c..f0faa364d 100644 --- a/src/main/resources/assets/refinedstorage/lang/en_us.lang +++ b/src/main/resources/assets/refinedstorage/lang/en_us.lang @@ -55,12 +55,14 @@ gui.refinedstorage:crafting_preview=Crafting Preview gui.refinedstorage:crafting_preview.to_craft=To craft: %d gui.refinedstorage:crafting_preview.available=Available: %d gui.refinedstorage:crafting_preview.missing=Missing: %d -gui.refinedstorage:crafting_preview.error.0=Cannot craft -gui.refinedstorage:crafting_preview.error.1=One of the crafting ingredients ended up needing -gui.refinedstorage:crafting_preview.error.2=itself. -gui.refinedstorage:crafting_preview.error.3=You need to remove the pattern or make sure -gui.refinedstorage:crafting_preview.error.4=the pattern is not used during crafting. -gui.refinedstorage:crafting_preview.error.5=Offending pattern: +gui.refinedstorage:crafting_preview.error=Request failed +gui.refinedstorage:crafting_preview.error.recursive.0=One of the crafting ingredients ended up needing +gui.refinedstorage:crafting_preview.error.recursive.1=itself. +gui.refinedstorage:crafting_preview.error.recursive.2=You need to remove the pattern or make sure +gui.refinedstorage:crafting_preview.error.recursive.3=the pattern is not used during crafting. +gui.refinedstorage:crafting_preview.error.recursive.4=Offending pattern: +gui.refinedstorage:crafting_preview.error.too_complex.0=The crafting task calculation was too complex +gui.refinedstorage:crafting_preview.error.too_complex.1=and was stopped to avoid server strain. gui.refinedstorage:crafting_preview.force_start=Press CTRL + SHIFT to ignore gui.refinedstorage:reader=Reader gui.refinedstorage:writer=Writer diff --git a/src/main/resources/assets/refinedstorage/lang/es_es.lang b/src/main/resources/assets/refinedstorage/lang/es_es.lang index 55013c8d1..54bfe9732 100644 --- a/src/main/resources/assets/refinedstorage/lang/es_es.lang +++ b/src/main/resources/assets/refinedstorage/lang/es_es.lang @@ -52,12 +52,12 @@ gui.refinedstorage:crafting_preview=Avance de Fabricación gui.refinedstorage:crafting_preview.to_craft=Para fabricar: %d gui.refinedstorage:crafting_preview.available=Disponible: %d gui.refinedstorage:crafting_preview.missing=Falta: %d -gui.refinedstorage:crafting_preview.error.0=No puede fabricar -gui.refinedstorage:crafting_preview.error.1=Uno de los objetos de creación termino faltando -gui.refinedstorage:crafting_preview.error.2=sí mismo. -gui.refinedstorage:crafting_preview.error.3=Necesita remover el patrón o revisarlo -gui.refinedstorage:crafting_preview.error.4=el patrón no se usa para la fabricación. -gui.refinedstorage:crafting_preview.error.5=Patrón ofensivo: +gui.refinedstorage:crafting_preview.error=No puede fabricar +gui.refinedstorage:crafting_preview.error.recursive.0=Uno de los objetos de creación termino faltando +gui.refinedstorage:crafting_preview.error.recursive.1=sí mismo. +gui.refinedstorage:crafting_preview.error.recursive.2=Necesita remover el patrón o revisarlo +gui.refinedstorage:crafting_preview.error.recursive.3=el patrón no se usa para la fabricación. +gui.refinedstorage:crafting_preview.error.recursive.4=Patrón ofensivo: gui.refinedstorage:crafting_preview.force_start=Presiona CTRL + SHIFT para forzar el inicio gui.refinedstorage:reader=Lector gui.refinedstorage:writer=Escritor diff --git a/src/main/resources/assets/refinedstorage/lang/ru_ru.lang b/src/main/resources/assets/refinedstorage/lang/ru_ru.lang index 768a01488..5892c0921 100755 --- a/src/main/resources/assets/refinedstorage/lang/ru_ru.lang +++ b/src/main/resources/assets/refinedstorage/lang/ru_ru.lang @@ -52,12 +52,12 @@ gui.refinedstorage:crafting_preview=Предварительный просмо gui.refinedstorage:crafting_preview.to_craft=Создать: %d gui.refinedstorage:crafting_preview.available=Доступно: %d gui.refinedstorage:crafting_preview.missing=Отсутствует: %d -gui.refinedstorage:crafting_preview.error.0=Не удается создать -gui.refinedstorage:crafting_preview.error.1=Один из ингредиентов для крафта оказался нуждающимся -gui.refinedstorage:crafting_preview.error.2=в себе. -gui.refinedstorage:crafting_preview.error.3=Вам нужно удалить шаблон или убедиться, что -gui.refinedstorage:crafting_preview.error.4=шаблон не используется во время обработки. -gui.refinedstorage:crafting_preview.error.5=Нарушение шаблона: +gui.refinedstorage:crafting_preview.error=Не удается создать +gui.refinedstorage:crafting_preview.error.recursive.0=Один из ингредиентов для крафта оказался нуждающимся +gui.refinedstorage:crafting_preview.error.recursive.1=в себе. +gui.refinedstorage:crafting_preview.error.recursive.2=Вам нужно удалить шаблон или убедиться, что +gui.refinedstorage:crafting_preview.error.recursive.3=шаблон не используется во время обработки. +gui.refinedstorage:crafting_preview.error.recursive.4=Нарушение шаблона: gui.refinedstorage:crafting_preview.force_start=Нажмите CTRL + SHIFT, чтобы все равно начать gui.refinedstorage:reader=Устройство чтения gui.refinedstorage:writer=Устройство записи