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.
This commit is contained in:
Jonathan Coates 2024-01-11 15:44:32 +00:00 committed by GitHub
parent e8434230ce
commit 82b1bb3ec3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -153,17 +153,17 @@ public final class BlockApiLookupImpl<A, C> implements BlockApiLookup<A, C> {
throw new IllegalArgumentException("Must register at least one BlockEntityType instance with a BlockEntityApiProvider.");
}
BlockApiProvider<A, C> 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<A, C> 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);
}