From 82b1bb3ec3ac066dfdb05c8f99e7d7815d530994 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 11 Jan 2024 15:44:32 +0000 Subject: [PATCH] Check for the correct BE type in the lookup API (#3510) The block lookup API's registerForBlockEntities method currently just registers the passed provider for each valid block for that block entity. However, in some situations (such as update suppression or a misbehaving mod), the wrong block entity will be present for one of these blocks. This means that the (incorrect) block entity will be passed off to the provider. Providers (especially those registered with registerForBlockEntity) will often blind-cast the supplied BE, leading to crashes. While the wrong BE being present is a bug, we should follow vanilla's lead and handle this more gracefully. In this case, we just check whether the correct BE type is present before forwarding it to the main provider. --- .../impl/lookup/block/BlockApiLookupImpl.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fabric-api-lookup-api-v1/src/main/java/net/fabricmc/fabric/impl/lookup/block/BlockApiLookupImpl.java b/fabric-api-lookup-api-v1/src/main/java/net/fabricmc/fabric/impl/lookup/block/BlockApiLookupImpl.java index c98dc9419..92909d175 100644 --- a/fabric-api-lookup-api-v1/src/main/java/net/fabricmc/fabric/impl/lookup/block/BlockApiLookupImpl.java +++ b/fabric-api-lookup-api-v1/src/main/java/net/fabricmc/fabric/impl/lookup/block/BlockApiLookupImpl.java @@ -153,17 +153,17 @@ public final class BlockApiLookupImpl implements BlockApiLookup { throw new IllegalArgumentException("Must register at least one BlockEntityType instance with a BlockEntityApiProvider."); } - BlockApiProvider nullCheckedProvider = (world, pos, state, blockEntity, context) -> { - if (blockEntity == null) { - return null; - } else { - return provider.find(blockEntity, context); - } - }; - for (BlockEntityType blockEntityType : blockEntityTypes) { Objects.requireNonNull(blockEntityType, "Encountered null block entity type while registering a block entity API provider mapping."); + BlockApiProvider nullCheckedProvider = (world, pos, state, blockEntity, context) -> { + if (blockEntity == null || blockEntity.getType() != blockEntityType) { + return null; + } else { + return provider.find(blockEntity, context); + } + }; + Block[] blocks = ((BlockEntityTypeAccessor) blockEntityType).getBlocks().toArray(new Block[0]); registerForBlocks(nullCheckedProvider, blocks); }