Check for the correct BE type in the lookup API ()

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.

(cherry picked from commit 82b1bb3ec3)
This commit is contained in:
Jonathan Coates 2024-01-11 15:44:32 +00:00 committed by modmuss50
parent 65757c5d7a
commit bb43a8b9bf

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);
}