diff --git a/patches/server/Add-World-Util-Methods.patch b/patches/server/Add-World-Util-Methods.patch index 29ee91d6e1..d32d1351cd 100644 --- a/patches/server/Add-World-Util-Methods.patch +++ b/patches/server/Add-World-Util-Methods.patch @@ -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 diff --git a/patches/server/Anti-Xray.patch b/patches/server/Anti-Xray.patch index ac6f3902d7..f934762586 100644 --- a/patches/server/Anti-Xray.patch +++ b/patches/server/Anti-Xray.patch @@ -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); diff --git a/patches/server/Do-not-load-chunks-for-Pathfinding.patch b/patches/server/Do-not-load-chunks-for-Pathfinding.patch index 40acfa111b..633f6dcd76 100644 --- a/patches/server/Do-not-load-chunks-for-Pathfinding.patch +++ b/patches/server/Do-not-load-chunks-for-Pathfinding.patch @@ -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(); diff --git a/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch b/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch index a19aadc74b..b7eacd8cfd 100644 --- a/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch +++ b/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch @@ -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 diff --git a/patches/server/Don-t-load-Chunks-from-Hoppers-and-other-things.patch b/patches/server/Don-t-load-Chunks-from-Hoppers-and-other-things.patch index 208b0512cb..c5b316e61c 100644 --- a/patches/server/Don-t-load-Chunks-from-Hoppers-and-other-things.patch +++ b/patches/server/Don-t-load-Chunks-from-Hoppers-and-other-things.patch @@ -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); + } diff --git a/patches/server/Don-t-mark-dirty-in-invalid-locations-SPIGOT-6086.patch b/patches/server/Don-t-mark-dirty-in-invalid-locations-SPIGOT-6086.patch index dff5e447b9..eea7d66488 100644 --- a/patches/server/Don-t-mark-dirty-in-invalid-locations-SPIGOT-6086.patch +++ b/patches/server/Don-t-mark-dirty-in-invalid-locations-SPIGOT-6086.patch @@ -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) { diff --git a/patches/server/Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch b/patches/server/Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch index a19c475239..bbfc4c63b0 100644 --- a/patches/server/Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch +++ b/patches/server/Highly-optimise-single-and-multi-AABB-VoxelShapes-an.patch @@ -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 diff --git a/patches/server/MC-Utils.patch b/patches/server/MC-Utils.patch index dd49540c0e..4987c52607 100644 --- a/patches/server/MC-Utils.patch +++ b/patches/server/MC-Utils.patch @@ -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."); + } diff --git a/patches/server/Optimise-BlockSoil-nearby-water-lookup.patch b/patches/server/Optimise-BlockSoil-nearby-water-lookup.patch index 9504dce522..305277fb94 100644 --- a/patches/server/Optimise-BlockSoil-nearby-water-lookup.patch +++ b/patches/server/Optimise-BlockSoil-nearby-water-lookup.patch @@ -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; + } diff --git a/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch b/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch index ee652bef40..7198d70b80 100644 --- a/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch +++ b/patches/server/Optimise-collision-checking-in-player-move-packet-ha.patch @@ -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; + } diff --git a/patches/server/Optimize-Collision-to-not-load-chunks.patch b/patches/server/Optimize-Collision-to-not-load-chunks.patch index 088c218b37..d03e71e48d 100644 --- a/patches/server/Optimize-Collision-to-not-load-chunks.patch +++ b/patches/server/Optimize-Collision-to-not-load-chunks.patch @@ -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) { diff --git a/patches/server/Optimize-isValidLocation-getType-and-getBlockData-fo.patch b/patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch similarity index 85% rename from patches/server/Optimize-isValidLocation-getType-and-getBlockData-fo.patch rename to patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch index 91d26a6630..fb31aad9a8 100644 --- a/patches/server/Optimize-isValidLocation-getType-and-getBlockData-fo.patch +++ b/patches/server/Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch @@ -1,8 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar 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 { diff --git a/patches/server/Prevent-Enderman-from-loading-chunks.patch b/patches/server/Prevent-Enderman-from-loading-chunks.patch index 244c267f68..3b98fe6b0e 100644 --- a/patches/server/Prevent-Enderman-from-loading-chunks.patch +++ b/patches/server/Prevent-Enderman-from-loading-chunks.patch @@ -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); diff --git a/patches/server/Prevent-Frosted-Ice-from-loading-holding-chunks.patch b/patches/server/Prevent-Frosted-Ice-from-loading-holding-chunks.patch index cf547eecb7..ab30261e51 100644 --- a/patches/server/Prevent-Frosted-Ice-from-loading-holding-chunks.patch +++ b/patches/server/Prevent-Frosted-Ice-from-loading-holding-chunks.patch @@ -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; diff --git a/patches/server/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch b/patches/server/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch index ac69a2264c..c2f17fad31 100644 --- a/patches/server/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch +++ b/patches/server/Prevent-Mob-AI-Rules-from-Loading-Chunks.patch @@ -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; } diff --git a/patches/server/Prevent-chunk-loading-from-Fluid-Flowing.patch b/patches/server/Prevent-chunk-loading-from-Fluid-Flowing.patch index 434e53ef2b..9fb4af40fa 100644 --- a/patches/server/Prevent-chunk-loading-from-Fluid-Flowing.patch +++ b/patches/server/Prevent-chunk-loading-from-Fluid-Flowing.patch @@ -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 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()); diff --git a/patches/server/Prevent-mob-spawning-from-loading-generating-chunks.patch b/patches/server/Prevent-mob-spawning-from-loading-generating-chunks.patch index 706a5a9398..bd415097ad 100644 --- a/patches/server/Prevent-mob-spawning-from-loading-generating-chunks.patch +++ b/patches/server/Prevent-mob-spawning-from-loading-generating-chunks.patch @@ -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 diff --git a/patches/server/Prevent-rayTrace-from-loading-chunks.patch b/patches/server/Prevent-rayTrace-from-loading-chunks.patch index bdac6a8986..4b99d196db 100644 --- a/patches/server/Prevent-rayTrace-from-loading-chunks.patch +++ b/patches/server/Prevent-rayTrace-from-loading-chunks.patch @@ -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()); diff --git a/patches/server/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch b/patches/server/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch index fc67e01e55..d2ff17dfe7 100644 --- a/patches/server/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch +++ b/patches/server/Prevent-sync-chunk-loads-when-villagers-try-to-find-.patch @@ -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); } diff --git a/patches/server/Rewrite-the-light-engine.patch b/patches/server/Rewrite-the-light-engine.patch index 09591baebd..ff1e0afb51 100644 --- a/patches/server/Rewrite-the-light-engine.patch +++ b/patches/server/Rewrite-the-light-engine.patch @@ -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 diff --git a/patches/server/implement-optional-per-player-mob-spawns.patch b/patches/server/implement-optional-per-player-mob-spawns.patch index faae7fc5f8..b0455a4baf 100644 --- a/patches/server/implement-optional-per-player-mob-spawns.patch +++ b/patches/server/implement-optional-per-player-mob-spawns.patch @@ -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