diff --git a/src/main/java/fi/dy/masa/itemscroller/config/Configs.java b/src/main/java/fi/dy/masa/itemscroller/config/Configs.java index 3d7440329..65b878409 100644 --- a/src/main/java/fi/dy/masa/itemscroller/config/Configs.java +++ b/src/main/java/fi/dy/masa/itemscroller/config/Configs.java @@ -35,6 +35,7 @@ public static class Generic public static final ConfigInteger MASS_CRAFT_INTERVAL = new ConfigInteger("massCraftInterval", 2, 1, 60, "itemscroller.config.generic.comment.massCraftInterval").translatedName("itemscroller.config.generic.name.massCraftInterval"); public static final ConfigInteger MASS_CRAFT_ITERATIONS = new ConfigInteger("massCraftIterations", 36, 1, 256, "itemscroller.config.generic.comment.massCraftIterations").translatedName("itemscroller.config.generic.name.massCraftIterations"); public static final ConfigBoolean MASS_CRAFT_SWAPS = new ConfigBoolean("massCraftSwapsOnly", false, "itemscroller.config.generic.comment.massCraftSwapsOnly").translatedName("itemscroller.config.generic.name.massCraftSwapsOnly"); + public static final ConfigBoolean MASS_CRAFT_RECIPE_BOOK = new ConfigBoolean("massCraftUseRecipeBook", false, "itemscroller.config.generic.comment.massCraftUseRecipeBook").translatedName("itemscroller.config.generic.name.massCraftUseRecipeBook"); public static final ConfigInteger PACKET_RATE_LIMIT = new ConfigInteger("packetRateLimit", 4, 1, 1024, "itemscroller.config.generic.comment.packetRateLimit").translatedName("itemscroller.config.generic.name.packetRateLimit"); public static final ConfigBoolean SCROLL_CRAFT_STORE_RECIPES_TO_FILE = new ConfigBoolean("craftingRecipesSaveToFile", true, "itemscroller.config.generic.comment.craftingRecipesSaveToFile").translatedName("itemscroller.config.generic.name.craftingRecipesSaveToFile"); public static final ConfigBoolean SCROLL_CRAFT_RECIPE_FILE_GLOBAL = new ConfigBoolean("craftingRecipesSaveFileIsGlobal", false, "itemscroller.config.generic.comment.craftingRecipesSaveFileIsGlobal").translatedName("itemscroller.config.generic.name.craftingRecipesSaveFileIsGlobal"); @@ -57,6 +58,7 @@ public static class Generic MASS_CRAFT_INTERVAL, MASS_CRAFT_ITERATIONS, MASS_CRAFT_SWAPS, + MASS_CRAFT_RECIPE_BOOK, MOD_MAIN_TOGGLE, PACKET_RATE_LIMIT, RATE_LIMIT_CLICK_PACKETS, diff --git a/src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java b/src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java index 0d30feab8..7b3c4e038 100644 --- a/src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java +++ b/src/main/java/fi/dy/masa/itemscroller/event/KeybindCallbacks.java @@ -5,6 +5,8 @@ import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.inventory.RecipeInputInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import net.minecraft.screen.slot.Slot; import fi.dy.masa.malilib.config.options.ConfigHotkey; import fi.dy.masa.malilib.gui.GuiBase; @@ -30,6 +32,8 @@ public class KeybindCallbacks implements IHotkeyCallback, IClientTickHandler protected int massCraftTicker; + private boolean recipeBookClicks = false; + public static KeybindCallbacks getInstance() { return INSTANCE; @@ -223,9 +227,58 @@ public void onClientTick(MinecraftClient mc) } RecipePattern recipe = RecipeStorage.getInstance().getSelectedRecipe(); + if (recipe.getVanillaRecipe() == null) { + recipe.lookupVanillaRecipe(mc.world); + } + int limit = Configs.Generic.MASS_CRAFT_ITERATIONS.getIntegerValue(); - if (Configs.Generic.MASS_CRAFT_SWAPS.getBooleanValue()) + if (Configs.Generic.MASS_CRAFT_RECIPE_BOOK.getBooleanValue() && recipe.getVanillaRecipe() != null) + { + InventoryUtils.dontUpdateRecipeBook = true; + for (int i = 0; i < limit; ++i) + { + // todo +// InventoryUtils.tryClearCursor(gui); +// InventoryUtils.setInhibitCraftingOutputUpdate(true); + InventoryUtils.throwAllCraftingResultsToGround(recipe, gui); + + RecipeInputInventory craftingInv = ((IMixinCraftingResultSlot) outputSlot).itemscroller_getCraftingInventory(); + if (!recipe.getVanillaRecipe().matches(craftingInv.createRecipeInput(), mc.world)) + { + CraftingHandler.SlotRange range = CraftingHandler.getCraftingGridSlots(gui, outputSlot); + final int invSlots = gui.getScreenHandler().slots.size(); + final int rangeSlots = range.getSlotCount(); + + for (int j = 0, slotNum = range.getFirst(); j < rangeSlots && slotNum < invSlots; j++, slotNum++) + { + InventoryUtils.shiftClickSlot(gui, slotNum); + + Slot slotTmp = gui.getScreenHandler().getSlot(slotNum); + ItemStack stack = slotTmp.getStack(); + if (!stack.isEmpty()) + { + InventoryUtils.dropStack(gui, slotNum); + } + } + } + + mc.interactionManager.clickRecipe(gui.getScreenHandler().syncId, recipe.getVanillaRecipeEntry(), true); +// InventoryUtils.setInhibitCraftingOutputUpdate(false); +// InventoryUtils.updateCraftingOutputSlot(outputSlot); + + craftingInv = ((IMixinCraftingResultSlot) outputSlot).itemscroller_getCraftingInventory(); + if (recipe.getVanillaRecipe().matches(craftingInv.createRecipeInput(), mc.world)) + { + break; + } + + InventoryUtils.shiftClickSlot(gui, outputSlot.id); + recipeBookClicks = true; + } + InventoryUtils.dontUpdateRecipeBook = false; + } + else if (Configs.Generic.MASS_CRAFT_SWAPS.getBooleanValue()) { for (int i = 0; i < limit; ++i) { @@ -301,4 +354,9 @@ public void onClientTick(MinecraftClient mc) }); } } + + public void onPacket(ScreenHandlerSlotUpdateS2CPacket packet) + { + var mc = MinecraftClient.getInstance(); + } } diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java index 81d1cf368..c059be551 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinClientPlayNetworkHandler.java @@ -1,7 +1,12 @@ package fi.dy.masa.itemscroller.mixin; +import fi.dy.masa.itemscroller.config.Configs; +import fi.dy.masa.itemscroller.config.Hotkeys; +import fi.dy.masa.itemscroller.event.KeybindCallbacks; import fi.dy.masa.itemscroller.util.InventoryUtils; import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.network.packet.s2c.play.CraftFailedResponseS2CPacket; +import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.InventoryS2CPacket; import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.StatisticsS2CPacket; @@ -22,6 +27,26 @@ private void onPong(StatisticsS2CPacket packet, CallbackInfo ci) } } + @Inject(method = "onScreenHandlerSlotUpdate", at = @At("RETURN")) + private void onScreenHandlerSlotUpdate(ScreenHandlerSlotUpdateS2CPacket packet, CallbackInfo ci) + { + KeybindCallbacks.getInstance().onPacket(packet); + } + + @Inject( + method = "onCraftFailedResponse", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", + shift = At.Shift.AFTER + ), + cancellable = true + ) + private void onCraftFailedResponse(CraftFailedResponseS2CPacket packet, CallbackInfo ci) + { + // todo + } + @Inject( method = "onInventory", at = @At( @@ -48,7 +73,7 @@ private void onInventory(InventoryS2CPacket packet, CallbackInfo ci) ), cancellable = true ) - private void onScreenHandlerSlotUpdate(ScreenHandlerSlotUpdateS2CPacket packet, CallbackInfo ci) + private void onScreenHandlerSlotUpdateInvokeMainThread(ScreenHandlerSlotUpdateS2CPacket packet, CallbackInfo ci) { if (InventoryUtils.bufferInvUpdates) { diff --git a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java index d5a98e459..2f8a33d0c 100644 --- a/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java +++ b/src/main/java/fi/dy/masa/itemscroller/mixin/MixinRecipeBookWidget.java @@ -1,9 +1,22 @@ package fi.dy.masa.itemscroller.mixin; +import fi.dy.masa.itemscroller.util.InventoryUtils; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import net.minecraft.screen.slot.Slot; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(RecipeBookWidget.class) public class MixinRecipeBookWidget { + @Inject(method = "slotClicked", at = @At("HEAD"), cancellable = true) + private void onSlotClicked(Slot slot, CallbackInfo ci) + { + if (InventoryUtils.dontUpdateRecipeBook) + { + ci.cancel(); + } + } } diff --git a/src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java b/src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java index 61db62e66..5480b7e32 100644 --- a/src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java +++ b/src/main/java/fi/dy/masa/itemscroller/recipes/RecipePattern.java @@ -55,7 +55,7 @@ public void ensureRecipeSizeAndClearRecipe(int size) this.clearRecipe(); } - private void lookupVanillaRecipe(World world) { + public void lookupVanillaRecipe(World world) { this.vanillaRecipe = null; var mc = MinecraftClient.getInstance(); int recipeSize; @@ -152,7 +152,6 @@ public void readFromNBT(@Nonnull NbtCompound nbt, @Nonnull DynamicRegistryManage } this.result = ItemStack.fromNbtOrEmpty(registryManager, nbt.getCompound("Result")); - this.lookupVanillaRecipe(MinecraftClient.getInstance().world); } } diff --git a/src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java b/src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java index ea2df13da..799454a32 100644 --- a/src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java +++ b/src/main/java/fi/dy/masa/itemscroller/util/InventoryUtils.java @@ -64,6 +64,7 @@ public class InventoryUtils { private static final Set DRAGGED_SLOTS = new HashSet<>(); private static final int SERVER_SYNC_MAGIC = 45510; + public static boolean dontUpdateRecipeBook; private static WeakReference sourceSlotCandidate = null; private static WeakReference sourceSlot = null;