From b1247df4dc5ae43be44c7c7b81a02d58fc8504f5 Mon Sep 17 00:00:00 2001 From: Nightenom <17338378+Nightenom@users.noreply.github.com> Date: Tue, 22 Sep 2020 20:58:19 +0200 Subject: [PATCH] [1.16] Fix possible crash when using rendering regionCache (#7207) --- .../client/MinecraftForgeClient.java | 18 +++++++++++++----- .../animation/TileEntityRendererAnimation.java | 3 ++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/minecraftforge/client/MinecraftForgeClient.java b/src/main/java/net/minecraftforge/client/MinecraftForgeClient.java index de7d3cbce..7f6a39387 100644 --- a/src/main/java/net/minecraftforge/client/MinecraftForgeClient.java +++ b/src/main/java/net/minecraftforge/client/MinecraftForgeClient.java @@ -23,10 +23,12 @@ import java.io.IOException; import java.util.BitSet; import java.util.HashMap; import java.util.Locale; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import net.minecraft.client.renderer.RenderType; import org.apache.commons.lang3.tuple.Pair; @@ -97,16 +99,16 @@ public class MinecraftForgeClient } } - private static final LoadingCache, ChunkRenderCache> regionCache = CacheBuilder.newBuilder() + private static final LoadingCache, Optional> regionCache = CacheBuilder.newBuilder() .maximumSize(500) .concurrencyLevel(5) .expireAfterAccess(1, TimeUnit.SECONDS) - .build(new CacheLoader, ChunkRenderCache>() + .build(new CacheLoader, Optional>() { @Override - public ChunkRenderCache load(Pair key) + public Optional load(Pair key) { - return ChunkRenderCache.generateCache(key.getLeft(), key.getRight().add(-1, -1, -1), key.getRight().add(16, 16, 16), 1); + return Optional.ofNullable(ChunkRenderCache.generateCache(key.getLeft(), key.getRight().add(-1, -1, -1), key.getRight().add(16, 16, 16), 1)); } }); @@ -115,10 +117,16 @@ public class MinecraftForgeClient if (cache == null) regionCache.invalidate(Pair.of(world, position)); else - regionCache.put(Pair.of(world, position), cache); + regionCache.put(Pair.of(world, position), Optional.of(cache)); } + @Nullable public static ChunkRenderCache getRegionRenderCache(World world, BlockPos pos) + { + return getRegionRenderCacheOptional(world, pos).orElse(null); + } + + public static Optional getRegionRenderCacheOptional(World world, BlockPos pos) { int x = pos.getX() & ~0xF; int y = pos.getY() & ~0xF; diff --git a/src/main/java/net/minecraftforge/client/model/animation/TileEntityRendererAnimation.java b/src/main/java/net/minecraftforge/client/model/animation/TileEntityRendererAnimation.java index 16f746e2f..288de4e4d 100644 --- a/src/main/java/net/minecraftforge/client/model/animation/TileEntityRendererAnimation.java +++ b/src/main/java/net/minecraftforge/client/model/animation/TileEntityRendererAnimation.java @@ -66,7 +66,8 @@ public class TileEntityRendererAnimation extends TileEntit } if(blockRenderer == null) blockRenderer = Minecraft.getInstance().getBlockRendererDispatcher(); BlockPos pos = te.getPos(); - IBlockDisplayReader world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos); + IBlockDisplayReader world = MinecraftForgeClient.getRegionRenderCacheOptional(te.getWorld(), pos) + .map(IBlockDisplayReader.class::cast).orElseGet(() -> te.getWorld()); BlockState state = world.getBlockState(pos); IBakedModel model = blockRenderer.getBlockModelShapes().getModel(state); IModelData data = model.getModelData(world, pos, state, ModelDataManager.getModelData(te.getWorld(), pos));