Fix empty/null chunk section check in LevelChunk#getBlockData, rename… (#7039)

… patch and methods to make more sense with Mojang mappings
This commit is contained in:
Jason Penilla 2021-12-05 15:32:02 -08:00
parent a271feefae
commit 77bed7ff51
21 changed files with 94 additions and 91 deletions

View File

@ -23,31 +23,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
}
@Override
- public FluidState getFluidIfLoaded(BlockPos blockposition) {
+ public final FluidState getFluidIfLoaded(BlockPos blockposition) {
ChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4);
return chunk == null ? null : chunk.getFluidState(blockposition);
}
+
+ public final boolean isLoadedAndInBounds(BlockPos blockposition) { // Paper - final for inline
+ return getWorldBorder().isWithinBounds(blockposition) && getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null;
+ }
+
+ public LevelChunk getChunkIfLoaded(int x, int z) { // Overridden in WorldServer for ABI compat which has final
+ public @Nullable LevelChunk getChunkIfLoaded(int x, int z) { // Overridden in WorldServer for ABI compat which has final
+ return ((ServerLevel) this).getChunkSource().getChunkAtIfLoadedImmediately(x, z);
+ }
+ public final LevelChunk getChunkIfLoaded(BlockPos blockposition) {
+ public final @Nullable LevelChunk getChunkIfLoaded(BlockPos blockposition) {
+ return ((ServerLevel) this).getChunkSource().getChunkAtIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+ }
+
+ // reduces need to do isLoaded before getType
+ public final BlockState getTypeIfLoadedAndInBounds(BlockPos blockposition) {
+ return getWorldBorder().isWithinBounds(blockposition) ? getTypeIfLoaded(blockposition) : null;
+ public final @Nullable BlockState getBlockStateIfLoadedAndInBounds(BlockPos blockposition) {
+ return getWorldBorder().isWithinBounds(blockposition) ? getBlockStateIfLoaded(blockposition) : null;
+ }
// Paper end
+
@Override
public final ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { // Paper - final for inline
// Paper end

View File

@ -882,7 +882,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ private void updateBlock(Level level, BlockPos blockPos) {
+ BlockState blockState = level.getTypeIfLoaded(blockPos);
+ BlockState blockState = level.getBlockStateIfLoaded(blockPos);
+
+ if (blockState != null && obfuscateGlobal[GLOBAL_BLOCKSTATE_PALETTE.idFor(blockState)]) {
+ ((ServerLevel) level).getChunkSource().blockChanged(blockPos);

View File

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
pos.set(i + l, j + m, k + n);
- BlockState blockState = world.getBlockState(pos);
+ // Paper start
+ BlockState blockState = world.getTypeIfLoaded(pos);
+ BlockState blockState = world.getBlockStateIfLoaded(pos);
+ if (blockState == null) {
+ return BlockPathTypes.BLOCKED;
+ } else {
@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected static BlockPathTypes getBlockPathTypeRaw(BlockGetter world, BlockPos pos) {
- BlockState blockState = world.getBlockState(pos);
+ BlockState blockState = world.getTypeIfLoaded(pos); // Paper
+ BlockState blockState = world.getBlockStateIfLoaded(pos); // Paper
+ if (blockState == null) return BlockPathTypes.BLOCKED; // Paper
Block block = blockState.getBlock();
Material material = blockState.getMaterial();

View File

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (this.hasDelayedDestroy) {
- iblockdata = this.level.getBlockState(this.delayedDestroyPos);
- if (iblockdata.isAir()) {
+ iblockdata = this.level.getTypeIfLoaded(this.delayedDestroyPos); // Paper
+ iblockdata = this.level.getBlockStateIfLoaded(this.delayedDestroyPos); // Paper
+ if (iblockdata == null || iblockdata.isAir()) { // Paper
this.hasDelayedDestroy = false;
} else {
@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} else if (this.isDestroyingBlock) {
- iblockdata = this.level.getBlockState(this.destroyPos);
+ // Paper start - don't want to do same logic as above, return instead
+ iblockdata = this.level.getTypeIfLoaded(this.destroyPos);
+ iblockdata = this.level.getBlockStateIfLoaded(this.destroyPos);
+ if (iblockdata == null) {
+ this.isDestroyingBlock = false;
+ return;
@ -51,7 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
ServerPlayerGameMode.LOGGER.debug("Mismatch in destroy block pos: {} {}", this.destroyPos, pos); // CraftBukkit - SPIGOT-5457 sent by client when interact event cancelled
- this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1);
- this.player.connection.send(new ClientboundBlockBreakAckPacket(this.destroyPos, this.level.getBlockState(this.destroyPos), action, true, "aborted mismatched destroying"));
+ BlockState type = this.level.getTypeIfLoaded(this.destroyPos); // Paper - don't load unloaded chunks for stale records here
+ BlockState type = this.level.getBlockStateIfLoaded(this.destroyPos); // Paper - don't load unloaded chunks for stale records here
+ if (type != null) this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1); // Paper
+ if (type != null) this.player.connection.send(new ClientboundBlockBreakAckPacket(this.destroyPos, type, action, true, "aborted mismatched destroying")); // Paper
+ this.destroyPos = BlockPos.ZERO; // Paper

View File

@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
BlockPos blockPos = pos.relative(function.apply(state));
- BlockState blockState = world.getBlockState(blockPos);
+ // Paper start
+ BlockState blockState = world.getTypeIfLoaded(blockPos);
+ BlockState blockState = world.getBlockStateIfLoaded(blockPos);
+ if (blockState == null) {
+ return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity);
+ }

View File

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public void blockChanged(BlockPos pos) {
+ if (!pos.isValidLocation(levelHeightAccessor)) return; // Paper - SPIGOT-6086 for all invalid locations; avoid acquiring locks
+ if (!pos.isInsideBuildHeightAndWorldBoundsHorizontal(levelHeightAccessor)) return; // Paper - SPIGOT-6086 for all invalid locations; avoid acquiring locks
LevelChunk chunk = this.getTickingChunk();
if (chunk != null) {

View File

@ -992,7 +992,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ continue;
+ }
+
+ BlockState type = chunk.getType(fx, fy, fz);
+ BlockState type = chunk.getBlockStateFinal(fx, fy, fz);
+ if (type.is((Tag) BlockTags.FIRE) || type.is(Blocks.LAVA)) {
+ noneMatch = false;
+ // can't break, we need to retain vanilla behavior by ensuring ALL chunks are loaded

View File

@ -6041,13 +6041,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ @Override
+ public BlockState getTypeIfLoaded(BlockPos blockposition) {
+ public final BlockState getBlockStateIfLoaded(BlockPos blockposition) {
+ ChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+ return chunk == null ? null : chunk.getBlockState(blockposition);
+ }
+
+ @Override
+ public FluidState getFluidIfLoaded(BlockPos blockposition) {
+ public final FluidState getFluidIfLoaded(BlockPos blockposition) {
+ ChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+ return chunk == null ? null : chunk.getFluidState(blockposition);
+ }
@ -6216,17 +6216,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
BlockState getBlockState(BlockPos pos);
+ // Paper start - if loaded util
+ @Nullable BlockState getTypeIfLoaded(BlockPos blockposition);
+ default Material getMaterialIfLoaded(BlockPos blockposition) {
+ BlockState type = this.getTypeIfLoaded(blockposition);
+ @Nullable BlockState getBlockStateIfLoaded(BlockPos blockposition);
+ default @Nullable Material getMaterialIfLoaded(BlockPos blockposition) {
+ BlockState type = this.getBlockStateIfLoaded(blockposition);
+ return type == null ? null : type.getMaterial();
+ }
+
+ default Block getBlockIfLoaded(BlockPos blockposition) {
+ BlockState type = this.getTypeIfLoaded(blockposition);
+ default @Nullable Block getBlockIfLoaded(BlockPos blockposition) {
+ BlockState type = this.getBlockStateIfLoaded(blockposition);
+ return type == null ? null : type.getBlock();
+ }
+ FluidState getFluidIfLoaded(BlockPos blockposition);
+ @Nullable FluidState getFluidIfLoaded(BlockPos blockposition);
+ // Paper end
FluidState getFluidState(BlockPos pos);
@ -6282,13 +6282,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - If loaded util
+ @Override
+ public FluidState getFluidIfLoaded(BlockPos blockposition) {
+ return this.getFluidState(blockposition);
+ public final FluidState getFluidIfLoaded(BlockPos blockposition) {
+ return Fluids.EMPTY.defaultFluidState();
+ }
+
+ @Override
+ public BlockState getTypeIfLoaded(BlockPos blockposition) {
+ return this.getBlockState(blockposition);
+ public final BlockState getBlockStateIfLoaded(BlockPos blockposition) {
+ return Blocks.AIR.defaultBlockState();
+ }
+ // Paper end
+
@ -6333,7 +6333,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ @Override
+ @Nullable
+ public final BlockState getTypeIfLoaded(BlockPos blockposition) {
+ public final BlockState getBlockStateIfLoaded(BlockPos blockposition) {
+ // CraftBukkit start - tree generation
+ if (captureTreeGeneration) {
+ CraftBlockState previous = capturedBlockStates.get(blockposition);
@ -6351,15 +6351,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ @Override
+ public FluidState getFluidIfLoaded(BlockPos blockposition) {
+ public final FluidState getFluidIfLoaded(BlockPos blockposition) {
+ ChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+
+ return chunk == null ? null : chunk.getFluidState(blockposition);
+ }
+ // Paper end
+
+ @Override
+ public final ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { // Paper - final for inline
+ // Paper end
ChunkAccess ichunkaccess = this.getChunkSource().getChunk(chunkX, chunkZ, leastStatus, create);
if (ichunkaccess == null && create) {
@ -6406,35 +6406,45 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
@@ -0,0 +0,0 @@ public class PathNavigationRegion implements BlockGetter, CollisionGetter {
return List.of();
private ChunkAccess getChunk(int chunkX, int chunkZ) {
int i = chunkX - this.centerX;
int j = chunkZ - this.centerZ;
- if (i >= 0 && i < this.chunks.length && j >= 0 && j < this.chunks[i].length) {
+ if (i >= 0 && i < this.chunks.length && j >= 0 && j < this.chunks[i].length) { // Paper - if this changes, update getChunkIfLoaded below
ChunkAccess chunkAccess = this.chunks[i][j];
return (ChunkAccess)(chunkAccess != null ? chunkAccess : new EmptyLevelChunk(this.level, new ChunkPos(chunkX, chunkZ)));
} else {
@@ -0,0 +0,0 @@ public class PathNavigationRegion implements BlockGetter, CollisionGetter {
}
}
+ // Paper start - if loaded util
+ private ChunkAccess getChunkIfLoaded(int x, int z) {
+ int k = x - this.centerX;
+ int l = z - this.centerZ;
+ private @Nullable ChunkAccess getChunkIfLoaded(int x, int z) {
+ // Based on getChunk(int, int)
+ int xx = x - this.centerX;
+ int zz = z - this.centerZ;
+
+ if (k >= 0 && k < this.chunks.length && l >= 0 && l < this.chunks[k].length) { // Paper - if this changes, update getChunkIfLoaded below
+ return this.chunks[k][l];
+ if (xx >= 0 && xx < this.chunks.length && zz >= 0 && zz < this.chunks[xx].length) {
+ return this.chunks[xx][zz];
+ }
+ return null;
+ }
+ @Override
+ public FluidState getFluidIfLoaded(BlockPos blockposition) {
+ public final FluidState getFluidIfLoaded(BlockPos blockposition) {
+ ChunkAccess chunk = getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+ return chunk == null ? null : chunk.getFluidState(blockposition);
+ }
+
+ @Override
+ public BlockState getTypeIfLoaded(BlockPos blockposition) {
+ public final BlockState getBlockStateIfLoaded(BlockPos blockposition) {
+ ChunkAccess chunk = getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+ return chunk == null ? null : chunk.getBlockState(blockposition);
+ }
+ // Paper end
+
@Nullable
@Override
public BlockEntity getBlockEntity(BlockPos pos) {
public WorldBorder getWorldBorder() {
return this.level.getWorldBorder();
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
@ -6639,12 +6649,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - If loaded util
+ @Override
+ public FluidState getFluidIfLoaded(BlockPos blockposition) {
+ public final FluidState getFluidIfLoaded(BlockPos blockposition) {
+ return this.getFluidState(blockposition);
+ }
+
+ @Override
+ public BlockState getTypeIfLoaded(BlockPos blockposition) {
+ public final BlockState getBlockStateIfLoaded(BlockPos blockposition) {
+ return this.getBlockState(blockposition);
+ }
+ // Paper end
@ -6719,12 +6729,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - If loaded util
+ @Override
+ public FluidState getFluidIfLoaded(BlockPos blockposition) {
+ public final FluidState getFluidIfLoaded(BlockPos blockposition) {
+ return this.getFluidState(blockposition);
+ }
+
+ @Override
+ public BlockState getTypeIfLoaded(BlockPos blockposition) {
+ public final BlockState getBlockStateIfLoaded(BlockPos blockposition) {
+ return this.getBlockState(blockposition);
+ }
+ // Paper end
@ -7007,7 +7017,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ @Override
+ public BlockState getTypeIfLoaded(BlockPos blockposition) {
+ public BlockState getBlockStateIfLoaded(BlockPos blockposition) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }

View File

@ -33,7 +33,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (int dy = 0; dy <= 1; ++dy) {
+ int y = dy + yOff;
+ net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)world.getChunk(x >> 4, z >> 4);
+ net.minecraft.world.level.material.FluidState fluid = chunk.getBlockData(x, y, z).getFluidState();
+ net.minecraft.world.level.material.FluidState fluid = chunk.getBlockStateFinal(x, y, z).getFluidState();
+ if (fluid.is(FluidTags.WATER)) {
+ return true;
+ }

View File

@ -73,7 +73,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (int z = minZ; z <= maxZ; ++z) {
+ for (int x = minX; x <= maxX; ++x) {
+ pos.set(x, y, z);
+ BlockState type = world.getTypeIfLoaded(pos);
+ BlockState type = world.getBlockStateIfLoaded(pos);
+ if (type != null && !type.isAir()) {
+ return false;
+ }

View File

@ -72,7 +72,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } else if ((!far && source instanceof net.minecraft.server.level.ServerPlayer) || (source != null && source.collisionLoadChunks)) {
+ blockState = this.collisionGetter.getBlockState(this.pos);
+ } else {
+ blockState = this.collisionGetter.getTypeIfLoaded(this.pos);
+ blockState = this.collisionGetter.getBlockStateIfLoaded(this.pos);
+ }
+
+ if (blockState == null) {

View File

@ -1,8 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 3 Mar 2016 02:07:55 -0600
Subject: [PATCH] Optimize isValidLocation, getType and getBlockData for
inlining
Subject: [PATCH] Optimize isInWorldBounds and getBlockState for inlining
Hot methods, so reduce # of instructions for the method.
@ -21,12 +20,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+ // Paper start
+ public boolean isValidLocation(net.minecraft.world.level.LevelHeightAccessor levelHeightAccessor) {
+ public final boolean isInsideBuildHeightAndWorldBoundsHorizontal(net.minecraft.world.level.LevelHeightAccessor levelHeightAccessor) {
+ return getX() >= -30000000 && getZ() >= -30000000 && getX() < 30000000 && getZ() < 30000000 && !levelHeightAccessor.isOutsideBuildHeight(getY());
+ }
+ public boolean isInvalidYLocation(net.minecraft.world.level.LevelHeightAccessor levelHeightAccessor) {
+ return levelHeightAccessor.isOutsideBuildHeight(getY());
+ }
+ // Paper end
+
public Vec3i(int x, int y, int z) {
@ -41,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean isInWorldBounds(BlockPos pos) {
- return !this.isOutsideBuildHeight(pos) && Level.isInWorldBoundsHorizontal(pos);
+ return pos.isValidLocation(this); // Paper - use better/optimized check
+ return pos.isInsideBuildHeightAndWorldBoundsHorizontal(this); // Paper - use better/optimized check
}
public static boolean isInSpawnableBounds(BlockPos pos) {
@ -53,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return GameEventDispatcher.NOOP;
}
+ public abstract BlockState getType(final int x, final int y, final int z); // Paper
+ public abstract BlockState getBlockState(final int x, final int y, final int z); // Paper
@Nullable
public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean moved);
@ -66,7 +62,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
+ // Paper start
+ @Override public BlockState getType(int x, int y, int z) {
+ @Override
+ public BlockState getBlockState(int x, int y, int z) {
+ return Blocks.VOID_AIR.defaultBlockState();
+ }
+ // Paper end
@ -82,8 +79,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.wrapped.getBlockState(pos);
}
+ // Paper start
+ public final BlockState getType(final int x, final int y, final int z) {
+ return this.wrapped.getBlockData(x, y, z);
+ @Override
+ public final BlockState getBlockState(final int x, final int y, final int z) {
+ return this.wrapped.getBlockStateFinal(x, y, z);
+ }
+ // Paper end
@ -103,16 +101,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- int i = pos.getX();
- int j = pos.getY();
- int k = pos.getZ();
+ return this.getBlockData(pos.getX(), pos.getY(), pos.getZ());
+ return this.getBlockStateFinal(pos.getX(), pos.getY(), pos.getZ());
+ }
+
+ public BlockState getType(final int x, final int y, final int z) {
+ return this.getBlockData(x, y, z);
+ @Override
+ public BlockState getBlockState(final int x, final int y, final int z) {
+ return this.getBlockStateFinal(x, y, z);
+ }
+ public final BlockState getBlockData(final int x, final int y, final int z) {
+ public final BlockState getBlockStateFinal(final int x, final int y, final int z) {
+ // Method body / logic copied from below
+ final int i = this.getSectionIndex(y);
+ if (i < 0 || i >= this.sections.length || this.sections[i] == null || this.sections[i].nonEmptyBlockCount == 0) {
+ if (i < 0 || i >= this.sections.length || this.sections[i].nonEmptyBlockCount == 0 || this.sections[i].hasOnlyAir()) {
+ return Blocks.AIR.defaultBlockState();
+ }
+ // Inlined ChunkSection.getType() and DataPaletteBlock.a(int,int,int)
@ -120,7 +119,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ public BlockState getBlockData_unused(int i, int j, int k) {
+ public BlockState getBlockState_unused(int i, int j, int k) {
+ // Paper end
if (this.level.isDebug()) {
BlockState iblockdata = null;
@ -149,9 +148,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- int i = pos.getY();
- if (this.isOutsideBuildHeight(i)) {
+ // Paper start
+ return getType(pos.getX(), pos.getY(), pos.getZ());
+ return getBlockState(pos.getX(), pos.getY(), pos.getZ());
+ }
+ public BlockState getType(final int x, final int y, final int z) {
+ public BlockState getBlockState(final int x, final int y, final int z) {
+ if (this.isOutsideBuildHeight(y)) {
return Blocks.VOID_AIR.defaultBlockState();
} else {

View File

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
int k = Mth.floor(this.enderman.getZ() - 1.0D + random.nextDouble() * 2.0D);
BlockPos blockposition = new BlockPos(i, j, k);
- BlockState iblockdata = world.getBlockState(blockposition);
+ BlockState iblockdata = world.getTypeIfLoaded(blockposition); // Paper
+ BlockState iblockdata = world.getBlockStateIfLoaded(blockposition); // Paper
+ if (iblockdata == null) return; // Paper
BlockPos blockposition1 = blockposition.below();
BlockState iblockdata1 = world.getBlockState(blockposition1);
@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
int k = Mth.floor(this.enderman.getZ() - 2.0D + random.nextDouble() * 4.0D);
BlockPos blockposition = new BlockPos(i, j, k);
- BlockState iblockdata = world.getBlockState(blockposition);
+ BlockState iblockdata = world.getTypeIfLoaded(blockposition); // Paper
+ BlockState iblockdata = world.getBlockStateIfLoaded(blockposition); // Paper
+ if (iblockdata == null) return; // Paper
Vec3 vec3d = new Vec3((double) this.enderman.getBlockX() + 0.5D, (double) j + 0.5D, (double) this.enderman.getBlockZ() + 0.5D);
Vec3 vec3d1 = new Vec3((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D);

View File

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
for(Direction direction : Direction.values()) {
mutableBlockPos.setWithOffset(pos, direction);
- BlockState blockState = world.getBlockState(mutableBlockPos);
+ BlockState blockState = world.getTypeIfLoaded(mutableBlockPos); // Paper
+ BlockState blockState = world.getBlockStateIfLoaded(mutableBlockPos); // Paper
+ if (blockState == null) { continue; } // Paper
if (blockState.is(this) && !this.slightlyMelt(blockState, world, mutableBlockPos)) {
world.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, world.paperConfig.frostedIceDelayMin, world.paperConfig.frostedIceDelayMax)); // Paper - use configurable min/max delay
@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
mutableBlockPos.setWithOffset(pos, direction);
- if (world.getBlockState(mutableBlockPos).is(this)) {
+ // Paper start
+ BlockState blockState = world.getTypeIfLoaded(mutableBlockPos);
+ BlockState blockState = world.getBlockStateIfLoaded(mutableBlockPos);
+ if (blockState != null && blockState.is(this)) {
+ // Paper end
++i;

View File

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Nullable
private BlockPos getPosWithBlock(BlockPos pos, BlockGetter world) {
- if (world.getBlockState(pos).is(this.blockToRemove)) {
+ net.minecraft.world.level.block.state.BlockState block = world.getTypeIfLoaded(pos); // Paper
+ net.minecraft.world.level.block.state.BlockState block = world.getBlockStateIfLoaded(pos); // Paper
+ if (block == null) return null; // Paper
+ if (block.is(this.blockToRemove)) { // Paper
return pos;
@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
BlockPos blockposition1 = ablockposition1[j];
- if (world.getBlockState(blockposition1).is(this.blockToRemove)) {
+ net.minecraft.world.level.block.state.BlockState block2 = world.getTypeIfLoaded(blockposition1); // Paper
+ net.minecraft.world.level.block.state.BlockState block2 = world.getBlockStateIfLoaded(blockposition1); // Paper
+ if (block2 != null && block2.is(this.blockToRemove)) { // Paper
return blockposition1;
}

View File

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
FluidState fluid1 = (FluidState) entry.getValue();
BlockPos blockposition1 = pos.relative(enumdirection);
- BlockState iblockdata1 = world.getBlockState(blockposition1);
+ BlockState iblockdata1 = world.getTypeIfLoaded(blockposition1); // Paper
+ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition1); // Paper
+ if (iblockdata1 == null) continue; // Paper
if (this.canSpreadTo(world, pos, blockState, enumdirection, blockposition1, iblockdata1, world.getFluidState(blockposition1), fluid1.getType())) {
@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
BlockPos blockposition1 = pos.relative(enumdirection);
- BlockState iblockdata1 = world.getBlockState(blockposition1);
+
+ BlockState iblockdata1 = world.getTypeIfLoaded(blockposition1); // Paper
+ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition1); // Paper
+ if (iblockdata1 == null) continue; // Paper
FluidState fluid = iblockdata1.getFluidState();
@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - avoid loading chunks
+ Pair<BlockState, FluidState> pair = short2objectmap.get(short0);
+ if (pair == null) {
+ BlockState iblockdatax = world.getTypeIfLoaded(blockposition2);
+ BlockState iblockdatax = world.getBlockStateIfLoaded(blockposition2);
+ if (iblockdatax == null) {
+ continue;
+ }
@ -64,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start
+ Pair pair = (Pair) short2objectmap.get(short0);
+ if (pair == null) {
+ BlockState iblockdatax = world.getTypeIfLoaded(blockposition1);
+ BlockState iblockdatax = world.getBlockStateIfLoaded(blockposition1);
+ if (iblockdatax == null) continue;
+
+ pair = Pair.of(iblockdatax, iblockdatax.getFluidState());

View File

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator();
int i = pos.getY();
- BlockState iblockdata = chunk.getBlockState(pos);
+ BlockState iblockdata = world.getTypeIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn
+ BlockState iblockdata = world.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn
- if (!iblockdata.isRedstoneConductor(chunk, pos)) {
+ if (iblockdata != null && !iblockdata.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn

View File

@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
- BlockState iblockdata = this.getBlockState(blockposition);
+ // Paper start - Prevent raytrace from loading chunks
+ BlockState iblockdata = this.getTypeIfLoaded(blockposition);
+ BlockState iblockdata = this.getBlockStateIfLoaded(blockposition);
+ if (iblockdata == null) {
+ // copied the last function parameter (listed below)
+ Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo());

View File

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- BlockState blockState = world.getBlockState(globalPos.pos());
+ BlockState blockState = world.getTypeIfLoaded(globalPos.pos()); // Paper
+ BlockState blockState = world.getBlockStateIfLoaded(globalPos.pos()); // Paper
+ if (blockState == null) { return false; } // Paper
return globalPos.pos().closerThan(entity.position(), 2.0D) && blockState.is(BlockTags.BEDS) && !blockState.getValue(BedBlock.OCCUPIED);
}

View File

@ -4893,8 +4893,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public void setBlockEmptinessMap(final boolean[] emptinessMap) {}
+
// Paper start
@Override public BlockState getType(int x, int y, int z) {
return Blocks.VOID_AIR.defaultBlockState();
@Override
public BlockState getBlockState(int x, int y, int z) {
diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java

View File

@ -740,7 +740,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
StructureFeatureManager structuremanager = world.structureFeatureManager();
ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator();
int i = pos.getY();
BlockState iblockdata = world.getTypeIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn
BlockState iblockdata = world.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn
+ int j = 0; // Paper - moved up
if (iblockdata != null && !iblockdata.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn