From 248df81c7ebf3617bdd5511a7f7e881617400feb Mon Sep 17 00:00:00 2001 From: Salandora Date: Mon, 30 Dec 2024 14:11:34 +0100 Subject: [PATCH] [1.21.1-1.21.4] Custom Ingredients sync fix (#4322) * Fix customIngredients sync (#4225) * Add client side test for custom ingredients sync * Fixed styling issues and missing license header * Applied requested changes and styling fixes --- fabric-recipe-api-v1/build.gradle | 6 ++- .../ingredient/CustomIngredientSync.java | 9 +--- ...SupportedIngredientsClientConnection.java} | 8 ++-- .../ingredient/ClientConnectionMixin.java | 43 +++++++++++++++++ .../ingredient/EncoderHandlerMixin.java | 23 ++++----- .../fabric-recipe-api-v1.mixins.json | 3 +- .../recipe/test_customingredients_sync.json | 18 +++++++ .../src/testmod/resources/fabric.mod.json | 3 ++ .../ClientCustomIngredientSyncTests.java | 47 +++++++++++++++++++ 9 files changed, 132 insertions(+), 28 deletions(-) rename fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/{SupportedIngredientsPacketEncoder.java => SupportedIngredientsClientConnection.java} (76%) create mode 100644 fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/ClientConnectionMixin.java create mode 100644 fabric-recipe-api-v1/src/testmod/resources/data/fabric-recipe-api-v1-testmod/recipe/test_customingredients_sync.json create mode 100644 fabric-recipe-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/recipe/ingredient/client/ClientCustomIngredientSyncTests.java diff --git a/fabric-recipe-api-v1/build.gradle b/fabric-recipe-api-v1/build.gradle index db1d1901ac..6203ee6669 100644 --- a/fabric-recipe-api-v1/build.gradle +++ b/fabric-recipe-api-v1/build.gradle @@ -5,5 +5,9 @@ loom { } moduleDependencies(project, [ - "fabric-networking-api-v1", + 'fabric-networking-api-v1', +]) + +testDependencies(project, [ + ':fabric-lifecycle-events-v1', ]) diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/CustomIngredientSync.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/CustomIngredientSync.java index 92245cc343..d2bea35faa 100644 --- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/CustomIngredientSync.java +++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/CustomIngredientSync.java @@ -19,8 +19,6 @@ import java.util.Set; import java.util.function.Consumer; -import io.netty.channel.ChannelHandler; - import net.minecraft.network.handler.EncoderHandler; import net.minecraft.network.packet.Packet; import net.minecraft.server.network.ServerPlayerConfigurationTask; @@ -90,12 +88,7 @@ public void onInitialize() { ServerConfigurationNetworking.registerGlobalReceiver(CustomIngredientPayloadC2S.ID, (payload, context) -> { Set supportedCustomIngredients = decodeResponsePayload(payload); - ChannelHandler packetEncoder = ((ServerCommonNetworkHandlerAccessor) context.networkHandler()).getConnection().channel.pipeline().get("encoder"); - - if (packetEncoder != null) { // Null in singleplayer - ((SupportedIngredientsPacketEncoder) packetEncoder).fabric_setSupportedCustomIngredients(supportedCustomIngredients); - } - + ((SupportedIngredientsClientConnection) ((ServerCommonNetworkHandlerAccessor) context.networkHandler()).getConnection()).fabric_setSupportedCustomIngredients(supportedCustomIngredients); context.networkHandler().completeTask(IngredientSyncTask.KEY); }); } diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/SupportedIngredientsPacketEncoder.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/SupportedIngredientsClientConnection.java similarity index 76% rename from fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/SupportedIngredientsPacketEncoder.java rename to fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/SupportedIngredientsClientConnection.java index d260439a59..635357d94d 100644 --- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/SupportedIngredientsPacketEncoder.java +++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/impl/recipe/ingredient/SupportedIngredientsClientConnection.java @@ -18,12 +18,14 @@ import java.util.Set; -import net.minecraft.network.handler.EncoderHandler; +import net.minecraft.network.ClientConnection; import net.minecraft.util.Identifier; /** - * Implemented on {@link EncoderHandler} to store which custom ingredients the client supports. + * Implemented on {@link ClientConnection} to store which custom ingredients the client supports. */ -public interface SupportedIngredientsPacketEncoder { +public interface SupportedIngredientsClientConnection { void fabric_setSupportedCustomIngredients(Set supportedCustomIngredients); + + Set fabric_getSupportedCustomIngredients(); } diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/ClientConnectionMixin.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/ClientConnectionMixin.java new file mode 100644 index 0000000000..0c485dc6ee --- /dev/null +++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/ClientConnectionMixin.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.recipe.ingredient; + +import java.util.Set; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +import net.minecraft.network.ClientConnection; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.impl.recipe.ingredient.SupportedIngredientsClientConnection; + +@Mixin(ClientConnection.class) +public abstract class ClientConnectionMixin implements SupportedIngredientsClientConnection { + @Unique + private Set fabric_supportedCustomIngredients = Set.of(); + + @Override + public void fabric_setSupportedCustomIngredients(Set supportedCustomIngredients) { + fabric_supportedCustomIngredients = supportedCustomIngredients; + } + + @Override + public Set fabric_getSupportedCustomIngredients() { + return fabric_supportedCustomIngredients; + } +} diff --git a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/EncoderHandlerMixin.java b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/EncoderHandlerMixin.java index d2a0331051..c1a42cc250 100644 --- a/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/EncoderHandlerMixin.java +++ b/fabric-recipe-api-v1/src/main/java/net/fabricmc/fabric/mixin/recipe/ingredient/EncoderHandlerMixin.java @@ -16,33 +16,22 @@ package net.fabricmc.fabric.mixin.recipe.ingredient; -import java.util.Set; - import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.network.handler.EncoderHandler; import net.minecraft.network.packet.Packet; -import net.minecraft.util.Identifier; import net.fabricmc.fabric.impl.recipe.ingredient.CustomIngredientSync; -import net.fabricmc.fabric.impl.recipe.ingredient.SupportedIngredientsPacketEncoder; +import net.fabricmc.fabric.impl.recipe.ingredient.SupportedIngredientsClientConnection; @Mixin(EncoderHandler.class) -public class EncoderHandlerMixin implements SupportedIngredientsPacketEncoder { - @Unique - private Set fabric_supportedCustomIngredients = Set.of(); - - @Override - public void fabric_setSupportedCustomIngredients(Set supportedCustomIngredients) { - fabric_supportedCustomIngredients = supportedCustomIngredients; - } - +public class EncoderHandlerMixin { @Inject( at = @At( value = "INVOKE", @@ -51,7 +40,11 @@ public void fabric_setSupportedCustomIngredients(Set supportedCustom method = "encode(Lio/netty/channel/ChannelHandlerContext;Lnet/minecraft/network/packet/Packet;Lio/netty/buffer/ByteBuf;)V" ) private void capturePacketEncoder(ChannelHandlerContext channelHandlerContext, Packet packet, ByteBuf byteBuf, CallbackInfo ci) { - CustomIngredientSync.CURRENT_SUPPORTED_INGREDIENTS.set(fabric_supportedCustomIngredients); + ChannelHandler channelHandler = channelHandlerContext.pipeline().get("packet_handler"); + + if (channelHandler instanceof SupportedIngredientsClientConnection) { + CustomIngredientSync.CURRENT_SUPPORTED_INGREDIENTS.set(((SupportedIngredientsClientConnection) channelHandler).fabric_getSupportedCustomIngredients()); + } } @Inject( diff --git a/fabric-recipe-api-v1/src/main/resources/fabric-recipe-api-v1.mixins.json b/fabric-recipe-api-v1/src/main/resources/fabric-recipe-api-v1.mixins.json index 5b7bd40303..c718a5df67 100644 --- a/fabric-recipe-api-v1/src/main/resources/fabric-recipe-api-v1.mixins.json +++ b/fabric-recipe-api-v1/src/main/resources/fabric-recipe-api-v1.mixins.json @@ -3,8 +3,9 @@ "package": "net.fabricmc.fabric.mixin.recipe", "compatibilityLevel": "JAVA_17", "mixins": [ - "ingredient.IngredientMixin", + "ingredient.ClientConnectionMixin", "ingredient.EncoderHandlerMixin", + "ingredient.IngredientMixin", "ingredient.ShapelessRecipeMixin" ], "injectors": { diff --git a/fabric-recipe-api-v1/src/testmod/resources/data/fabric-recipe-api-v1-testmod/recipe/test_customingredients_sync.json b/fabric-recipe-api-v1/src/testmod/resources/data/fabric-recipe-api-v1-testmod/recipe/test_customingredients_sync.json new file mode 100644 index 0000000000..28579e4d94 --- /dev/null +++ b/fabric-recipe-api-v1/src/testmod/resources/data/fabric-recipe-api-v1-testmod/recipe/test_customingredients_sync.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "fabric:type": "fabric:components", + "base": { + "item": "minecraft:diamond_pickaxe" + }, + "components": { + "minecraft:damage": 0 + }, + "strict": false + } + ], + "result": { + "id": "minecraft:diamond_block" + } +} diff --git a/fabric-recipe-api-v1/src/testmod/resources/fabric.mod.json b/fabric-recipe-api-v1/src/testmod/resources/fabric.mod.json index 04fcaf6644..b784c44f36 100644 --- a/fabric-recipe-api-v1/src/testmod/resources/fabric.mod.json +++ b/fabric-recipe-api-v1/src/testmod/resources/fabric.mod.json @@ -13,6 +13,9 @@ "net.fabricmc.fabric.test.recipe.ingredient.IngredientMatchTests", "net.fabricmc.fabric.test.recipe.ingredient.SerializationTests", "net.fabricmc.fabric.test.recipe.ingredient.ShapelessRecipeMatchTests" + ], + "client": [ + "net.fabricmc.fabric.test.recipe.ingredient.client.ClientCustomIngredientSyncTests" ] } } diff --git a/fabric-recipe-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/recipe/ingredient/client/ClientCustomIngredientSyncTests.java b/fabric-recipe-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/recipe/ingredient/client/ClientCustomIngredientSyncTests.java new file mode 100644 index 0000000000..4d6fb2bcd2 --- /dev/null +++ b/fabric-recipe-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/recipe/ingredient/client/ClientCustomIngredientSyncTests.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.test.recipe.ingredient.client; + +import net.minecraft.recipe.ShapelessRecipe; +import net.minecraft.test.GameTestException; +import net.minecraft.util.Identifier; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.impl.recipe.ingredient.CustomIngredientImpl; +import net.fabricmc.fabric.impl.recipe.ingredient.builtin.ComponentsIngredient; + +public class ClientCustomIngredientSyncTests implements ClientModInitializer { + /** + * The recipe requires a custom ingredient. + */ + @Override + public void onInitializeClient() { + ClientTickEvents.END_WORLD_TICK.register(world -> { + Identifier recipeId = Identifier.of("fabric-recipe-api-v1-testmod", "test_customingredients_sync"); + ShapelessRecipe recipe = (ShapelessRecipe) world.getRecipeManager().get(recipeId).get().value(); + + if (!(recipe.getIngredients().getFirst() instanceof CustomIngredientImpl customIngredient)) { + throw new GameTestException("Expected the first ingredient to be a CustomIngredientImpl"); + } + + if (!(customIngredient.getCustomIngredient() instanceof ComponentsIngredient)) { + throw new GameTestException("Expected the custom ingredient to be a ComponentsIngredient"); + } + }); + } +}