From 0c8e75731405c8354af68114d9bd7c37b51258fd Mon Sep 17 00:00:00 2001
From: Jonathan Coates <git@squiddev.cc>
Date: Fri, 15 Nov 2024 07:31:49 +0000
Subject: [PATCH] Several cleanup to turtle crafting upgrade

 - Don't construct a fake player when crafting: vanilla now has its own
   automated crafting, so no longer requires the presence of a player.

 - Fix remainder stack not being set in some situations. Closes #2007.
---
 .../shared/platform/PlatformHelper.java       | 22 -------------------
 .../turtle/core/TurtleCraftCommand.java       |  1 +
 .../upgrades/TurtleInventoryCrafting.java     | 14 ++++--------
 .../computercraft/TestPlatformHelper.java     | 12 ----------
 .../shared/platform/PlatformHelperImpl.java   | 11 ----------
 .../shared/platform/PlatformHelperImpl.java   | 16 --------------
 6 files changed, 5 insertions(+), 71 deletions(-)

diff --git a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java
index 2892a8c8e..c80f3f1fc 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java
@@ -33,8 +33,6 @@
 import net.minecraft.world.item.DyeColor;
 import net.minecraft.world.item.Item;
 import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.CraftingInput;
-import net.minecraft.world.item.crafting.Recipe;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.entity.BlockEntity;
 import net.minecraft.world.level.block.state.BlockState;
@@ -216,26 +214,6 @@ default void invalidateComponent(BlockEntity owner) {
      */
     ItemStack getCraftingRemainingItem(ItemStack stack);
 
-    /**
-     * A more general version of {@link #getCraftingRemainingItem(ItemStack)} which gets all remaining items for a
-     * recipe.
-     *
-     * @param player    The player performing the crafting.
-     * @param recipe    The recipe currently doing the crafting.
-     * @param container The crafting container.
-     * @return A list of items to return to the player after crafting.
-     */
-    List<ItemStack> getRecipeRemainingItems(ServerPlayer player, Recipe<CraftingInput> recipe, CraftingInput container);
-
-    /**
-     * Fire an event after crafting has occurred.
-     *
-     * @param player    The player performing the crafting.
-     * @param container The current crafting container.
-     * @param stack     The resulting stack from crafting.
-     */
-    void onItemCrafted(ServerPlayer player, CraftingInput container, ItemStack stack);
-
     /**
      * Check whether we should notify neighbours in a particular direction.
      *
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java
index 015c74168..67e6a4a15 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java
@@ -26,6 +26,7 @@ public TurtleCommandResult execute(ITurtleAccess turtle) {
 
         // Store or drop any remainders
         for (var stack : results) TurtleUtil.storeItemOrDrop(turtle, stack);
+        turtle.getInventory().setChanged();
 
         if (!results.isEmpty()) turtle.playAnimation(TurtleAnimation.WAIT);
         return TurtleCommandResult.success();
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java
index 1e66b71af..594bef573 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java
@@ -5,9 +5,7 @@
 package dan200.computercraft.shared.turtle.upgrades;
 
 import dan200.computercraft.api.turtle.ITurtleAccess;
-import dan200.computercraft.shared.platform.PlatformHelper;
 import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity;
-import dan200.computercraft.shared.turtle.core.TurtlePlayer;
 import net.minecraft.server.level.ServerLevel;
 import net.minecraft.world.Container;
 import net.minecraft.world.item.ItemStack;
@@ -82,18 +80,15 @@ public static List<ItemStack> craft(ITurtleAccess turtle, int maxCount) {
         var xStart = candidate.xStart();
         var yStart = candidate.yStart();
 
-        var player = TurtlePlayer.get(turtle).player();
-
         var results = new ArrayList<ItemStack>();
         for (var i = 0; i < maxCount && recipe.matches(input, level); i++) {
             var result = recipe.assemble(input, level.registryAccess());
             if (result.isEmpty()) break;
             results.add(result);
 
-            result.onCraftedBy(level, player, result.getCount());
-            PlatformHelper.get().onItemCrafted(player, input, result);
+            result.onCraftedBySystem(level);
 
-            var remainders = PlatformHelper.get().getRecipeRemainingItems(player, recipe, input);
+            var remainders = recipe.getRemainingItems(input);
             for (var y = 0; y < input.height(); y++) {
                 for (var x = 0; x < input.width(); x++) {
                     var slot = xStart + x + (y + yStart) * TurtleBlockEntity.INVENTORY_WIDTH;
@@ -110,10 +105,9 @@ public static List<ItemStack> craft(ITurtleAccess turtle, int maxCount) {
                     // Either update the current stack or add it to the remainder list (to be inserted into the inventory
                     // afterwards).
                     if (existing.isEmpty()) {
-                        inventory.setItem(slot, existing);
-                    } else if (ItemStack.isSameItemSameComponents(existing, remainder)) {
-                        remainder.grow(existing.getCount());
                         inventory.setItem(slot, remainder);
+                    } else if (ItemStack.isSameItemSameComponents(existing, remainder)) {
+                        existing.grow(remainder.getCount());
                     } else {
                         results.add(remainder);
                     }
diff --git a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java
index fae335b78..6636304bc 100644
--- a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java
+++ b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java
@@ -34,8 +34,6 @@
 import net.minecraft.world.item.CreativeModeTab;
 import net.minecraft.world.item.Item;
 import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.CraftingInput;
-import net.minecraft.world.item.crafting.Recipe;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.entity.BlockEntity;
 import net.minecraft.world.level.block.state.BlockState;
@@ -160,16 +158,6 @@ public ContainerTransfer getContainer(ServerLevel level, BlockPos pos, Direction
         throw new UnsupportedOperationException("Cannot interact with the world inside tests");
     }
 
-    @Override
-    public List<ItemStack> getRecipeRemainingItems(ServerPlayer player, Recipe<CraftingInput> recipe, CraftingInput container) {
-        throw new UnsupportedOperationException("Cannot query recipes inside tests");
-    }
-
-    @Override
-    public void onItemCrafted(ServerPlayer player, CraftingInput container, ItemStack stack) {
-        throw new UnsupportedOperationException("Cannot interact with the world inside tests");
-    }
-
     @Override
     public String getInstalledVersion() {
         return "1.0";
diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
index 35568523d..0c770ea5e 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
@@ -55,9 +55,7 @@
 import net.minecraft.world.inventory.MenuType;
 import net.minecraft.world.item.*;
 import net.minecraft.world.item.context.UseOnContext;
-import net.minecraft.world.item.crafting.CraftingInput;
 import net.minecraft.world.item.crafting.Ingredient;
-import net.minecraft.world.item.crafting.Recipe;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.entity.BlockEntity;
 import net.minecraft.world.level.block.state.BlockState;
@@ -197,15 +195,6 @@ public ItemStack getCraftingRemainingItem(ItemStack stack) {
         return stack.getRecipeRemainder();
     }
 
-    @Override
-    public List<ItemStack> getRecipeRemainingItems(ServerPlayer player, Recipe<CraftingInput> recipe, CraftingInput container) {
-        return recipe.getRemainingItems(container);
-    }
-
-    @Override
-    public void onItemCrafted(ServerPlayer player, CraftingInput container, ItemStack stack) {
-    }
-
     @Override
     public boolean onNotifyNeighbour(Level level, BlockPos pos, BlockState block, Direction direction) {
         return true;
diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
index d0698b576..c6d5bc27f 100644
--- a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
+++ b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
@@ -15,7 +15,6 @@
 import dan200.computercraft.api.peripheral.PeripheralCapability;
 import dan200.computercraft.impl.Peripherals;
 import dan200.computercraft.shared.config.ConfigFile;
-import dan200.computercraft.shared.container.ListContainer;
 import dan200.computercraft.shared.network.container.ContainerData;
 import dan200.computercraft.shared.util.InventoryUtil;
 import net.minecraft.commands.synchronization.ArgumentTypeInfo;
@@ -42,9 +41,7 @@
 import net.minecraft.world.item.Item;
 import net.minecraft.world.item.ItemStack;
 import net.minecraft.world.item.context.UseOnContext;
-import net.minecraft.world.item.crafting.CraftingInput;
 import net.minecraft.world.item.crafting.Ingredient;
-import net.minecraft.world.item.crafting.Recipe;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.entity.BlockEntity;
 import net.minecraft.world.level.block.state.BlockState;
@@ -192,19 +189,6 @@ public ItemStack getCraftingRemainingItem(ItemStack stack) {
         return stack.getCraftingRemainingItem();
     }
 
-    @Override
-    public List<ItemStack> getRecipeRemainingItems(ServerPlayer player, Recipe<CraftingInput> recipe, CraftingInput container) {
-        CommonHooks.setCraftingPlayer(player);
-        var result = recipe.getRemainingItems(container);
-        CommonHooks.setCraftingPlayer(null);
-        return result;
-    }
-
-    @Override
-    public void onItemCrafted(ServerPlayer player, CraftingInput container, ItemStack stack) {
-        EventHooks.firePlayerCraftingEvent(player, stack, new ListContainer(container.items()));
-    }
-
     @Override
     public boolean onNotifyNeighbour(Level level, BlockPos pos, BlockState block, Direction direction) {
         return !EventHooks.onNeighborNotify(level, pos, block, EnumSet.of(direction), false).isCanceled();