From 439ca99331767edab499184d511443824cf63579 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Mon, 3 Apr 2023 18:46:49 +0200 Subject: [PATCH] Fix block place logic Fix several issues when a player interact with a block: * the place sound isn't played for the dispensed shulker block * desync of the jukebox blocks between bukkit handler and the vanilla interaction * poi can desync when the BlockPhysicsEvent is cancelled --- .../minecraft/world/item/BlockItem.java.patch | 2 +- .../minecraft/world/level/Level.java.patch | 46 ++++++++++--------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch index 990471a15e..108ce992eb 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch @@ -76,7 +76,7 @@ SoundType soundeffecttype = iblockdata1.getSoundType(); - world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); -+ // world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), SoundCategory.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); ++ if (entityhuman == null) world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), net.minecraft.sounds.SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); // Paper - Fix block place logic; reintroduce this for the dispenser (i.e the shulker) world.gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition, GameEvent.Context.of(entityhuman, iblockdata1)); itemstack.consume(1, entityhuman); return InteractionResult.SUCCESS; diff --git a/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch b/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch index 54a0a39107..62c9a13d52 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch @@ -303,7 +303,7 @@ + // Paper start - if loaded @Nullable - @Override ++ @Override + public final ChunkAccess getChunkIfLoadedImmediately(int x, int z) { + return ((ServerLevel)this).chunkSource.getChunkAtIfLoadedImmediately(x, z); + } @@ -356,7 +356,7 @@ + return getWorldBorder().isWithinBounds(blockposition) ? getBlockStateIfLoaded(blockposition) : null; + } + -+ @Override + @Override public ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { + // Paper end ChunkAccess ichunkaccess = this.getChunkSource().getChunk(chunkX, chunkZ, leastStatus, create); @@ -381,7 +381,7 @@ if (this.isOutsideBuildHeight(pos)) { return false; } else if (!this.isClientSide && this.isDebug()) { -@@ -214,44 +454,124 @@ +@@ -214,45 +454,126 @@ } else { LevelChunk chunk = this.getChunkAt(pos); Block block = state.getBlock(); @@ -466,10 +466,10 @@ + // CraftBukkit end + return true; -+ } -+ } -+ } -+ + } + } + } + + // CraftBukkit start - Split off from above in order to directly send client and physic updates + public void notifyAndUpdatePhysics(BlockPos blockposition, LevelChunk chunk, BlockState oldBlock, BlockState newBlock, BlockState actualBlock, int i, int j) { + BlockState iblockdata = newBlock; @@ -497,31 +497,33 @@ + // CraftBukkit start + iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam + CraftWorld world = ((ServerLevel) this).getWorld(); ++ boolean cancelledUpdates = false; // Paper - Fix block place logic + if (world != null && ((ServerLevel)this).hasPhysicsEvent) { // Paper - BlockPhysicsEvent + BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata)); + this.getCraftServer().getPluginManager().callEvent(event); + -+ if (event.isCancelled()) { -+ return; -+ } ++ cancelledUpdates = event.isCancelled(); // Paper - Fix block place logic + } + // CraftBukkit end ++ if (!cancelledUpdates) { // Paper - Fix block place logic + iblockdata.updateNeighbourShapes(this, blockposition, k, j - 1); + iblockdata.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); - } ++ } // Paper - Fix block place logic ++ } + + // CraftBukkit start - SPIGOT-5710 + if (!this.preventPoiUpdated) { + this.onBlockStateChange(blockposition, iblockdata1, iblockdata2); + } + // CraftBukkit end - } - } ++ } ++ } + // CraftBukkit end - ++ public void onBlockStateChange(BlockPos pos, BlockState oldBlock, BlockState newBlock) {} -@@ -270,9 +590,26 @@ + @Override +@@ -270,9 +591,26 @@ return false; } else { FluidState fluid = this.getFluidState(pos); @@ -550,7 +552,7 @@ } if (drop) { -@@ -340,10 +677,18 @@ +@@ -340,10 +678,18 @@ @Override public BlockState getBlockState(BlockPos pos) { @@ -570,7 +572,7 @@ return chunk.getBlockState(pos); } -@@ -446,34 +791,53 @@ +@@ -446,34 +792,53 @@ this.pendingBlockEntityTickers.clear(); } @@ -622,18 +624,18 @@ + entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); + // Paper end - Prevent block entity and entity crashes } - } ++ } + // Paper start - Option to prevent armor stands from doing entity lookups + @Override + public boolean noCollision(@Nullable Entity entity, AABB box) { + if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return false; + return LevelAccessor.super.noCollision(entity, box); -+ } + } + // Paper end - Option to prevent armor stands from doing entity lookups public boolean shouldTickDeath(Entity entity) { return true; -@@ -510,13 +874,32 @@ +@@ -510,13 +875,32 @@ @Nullable @Override public BlockEntity getBlockEntity(BlockPos pos) { @@ -667,7 +669,7 @@ this.getChunkAt(blockposition).addAndRegisterBlockEntity(blockEntity); } } -@@ -643,7 +1026,7 @@ +@@ -643,7 +1027,7 @@ for (int k = 0; k < j; ++k) { EnderDragonPart entitycomplexpart = aentitycomplexpart[k]; @@ -676,7 +678,7 @@ if (t0 != null && predicate.test(t0)) { result.add(t0); -@@ -912,7 +1295,7 @@ +@@ -912,7 +1296,7 @@ public static enum ExplosionInteraction implements StringRepresentable {