Date: Fri, 22 Oct 2021 16:24:17 -0700
-Subject: [PATCH] Add exploded block state to BlockExplodeEvent and
- EntityDamageByBlockEvent
+Subject: [PATCH] Add exploded block state to EntityDamageByBlockEvent
diff --git a/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java b/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
+++ b/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
-@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
- * Called when a block explodes interacting with blocks. The
- * event isn't called if the {@link org.bukkit.GameRule#MOB_GRIEFING}
- * is disabled as no block interaction will occur.
-+ *
-+ * The {@link Block} returned by this event is not necessarily
-+ * the block that caused the explosion, just the block at the location where
-+ * the explosion originated. See {@link #getExplodedBlockState()}
- */
- public class BlockExplodeEvent extends BlockEvent implements Cancellable {
- private static final HandlerList handlers = new HandlerList();
- private boolean cancel;
- private final List blocks;
- private float yield;
-+ private final org.bukkit.block.BlockState explodedBlockState; // Paper
-
-+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper
- public BlockExplodeEvent(@NotNull final Block what, @NotNull final List blocks, final float yield) {
-+ // Paper start
-+ this(what, blocks, yield, null);
-+ }
-+ @org.jetbrains.annotations.ApiStatus.Internal
-+ public BlockExplodeEvent(@NotNull final Block what, @NotNull final List blocks, final float yield, @org.jetbrains.annotations.Nullable org.bukkit.block.BlockState explodedBlockState) {
-+ // Paper end
- super(what);
- this.blocks = blocks;
- this.yield = yield;
- this.cancel = false;
-+ this.explodedBlockState = explodedBlockState; // Paper
- }
-
- @Override
@@ -0,0 +0,0 @@ public class BlockExplodeEvent extends BlockEvent implements Cancellable {
- this.cancel = cancel;
+ this.cancel = false;
}
-+ // Paper start
-+ /**
-+ * Get a capture of the block that directly caused
-+ * the explosion, like a bed or respawn anchor. This
-+ * block state is not placed so {@link org.bukkit.block.BlockState#isPlaced}
-+ * will be false.
-+ *
-+ * Can be null if no block directly caused the explosion.
-+ *
-+ * @return the exploded block state or null if not applicable
-+ */
-+ public @org.jetbrains.annotations.Nullable org.bukkit.block.BlockState getExplodedBlockState() {
-+ return this.explodedBlockState;
-+ }
-+ // Paper end
-+
- /**
- * Returns the list of blocks that would have been removed or were removed
- * from the explosion event.
++ @io.papermc.paper.annotation.DoNotUse // Paper
+ @Deprecated(forRemoval = true)
+ public BlockExplodeEvent(@NotNull final Block what, @NotNull final List blocks, final float yield) {
+ this(what, what.getState(), blocks, yield);
diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
diff --git a/patches/api/Convert-project-to-Gradle.patch b/patches/api/Convert-project-to-Gradle.patch
index 008323009a..b923b09468 100644
--- a/patches/api/Convert-project-to-Gradle.patch
+++ b/patches/api/Convert-project-to-Gradle.patch
@@ -135,7 +135,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
-
- org.spigotmc
- spigot-api
-- 1.20.5-R0.1-SNAPSHOT
+- 1.20.6-R0.1-SNAPSHOT
- jar
-
- Spigot-API
diff --git a/patches/api/Fix-upstream-javadocs.patch b/patches/api/Fix-upstream-javadocs.patch
index b999d3a7dc..8eec142eb7 100644
--- a/patches/api/Fix-upstream-javadocs.patch
+++ b/patches/api/Fix-upstream-javadocs.patch
@@ -603,13 +603,12 @@ diff --git a/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java b/src/m
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
+++ b/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java
-@@ -0,0 +0,0 @@ import org.bukkit.event.HandlerList;
- import org.jetbrains.annotations.NotNull;
-
- /**
-- * Called when a block explodes
-+ * Called when a block explodes interacting with blocks. The
-+ * event isn't called if the {@link org.bukkit.GameRule#MOB_GRIEFING}
+@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
+ * Note that due to the nature of explosions, {@link #getBlock()} will always be
+ * an air block. {@link #getExplodedBlockState()} should be used to get
+ * information about the block state that exploded.
++ *
++ * The event isn't called if the {@link org.bukkit.GameRule#MOB_GRIEFING}
+ * is disabled as no block interaction will occur.
*/
public class BlockExplodeEvent extends BlockEvent implements Cancellable {
diff --git a/patches/server/Add-exploded-block-state-to-BlockExplodeEvent-and-En.patch b/patches/server/Add-exploded-block-state-to-BlockExplodeEvent-and-En.patch
deleted file mode 100644
index 34577fc50a..0000000000
--- a/patches/server/Add-exploded-block-state-to-BlockExplodeEvent-and-En.patch
+++ /dev/null
@@ -1,177 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jake Potrebic
-Date: Fri, 22 Oct 2021 16:25:07 -0700
-Subject: [PATCH] Add exploded block state to BlockExplodeEvent and
- EntityDamageByBlockEvent
-
-
-diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java
-+++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java
-@@ -0,0 +0,0 @@ public class DamageSource {
- private final Entity directEntity;
- @Nullable
- private final Vec3 damageSourcePosition;
-+ public org.bukkit.block.BlockState explodedBlockState; // Paper - add exploded state
- // CraftBukkit start
- @Nullable
- private org.bukkit.block.Block directBlock; // The block that caused the damage. damageSourcePosition is not used for all block damages
-@@ -0,0 +0,0 @@ public class DamageSource {
-
- private DamageSource cloneInstance() {
- DamageSource damageSource = new DamageSource(this.type, this.directEntity, this.causingEntity, this.damageSourcePosition);
-+ damageSource.explodedBlockState = this.explodedBlockState; // Paper - Include explodedBlockState when clone this instance of DamageSource
- damageSource.directBlock = this.getDirectBlock();
- damageSource.withSweep = this.isSweep();
- damageSource.poison = this.isPoison();
-diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSources.java b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java
-+++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
-@@ -0,0 +0,0 @@ public class DamageSources {
- return this.source(DamageTypes.SONIC_BOOM, attacker);
- }
-
-+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - add exploded state
- public DamageSource badRespawnPointExplosion(Vec3 position) {
-- return new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), position);
-+ // Paper start - add exploded state
-+ return this.badRespawnPointExplosion(position, null);
-+ }
-+
-+ public DamageSource badRespawnPointExplosion(Vec3 position, @Nullable org.bukkit.block.BlockState explodedBlockState) {
-+ DamageSource source = new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), position);
-+ source.explodedBlockState = explodedBlockState;
-+ return source;
-+ // Paper end - add exploded state
- }
-
- public DamageSource outOfBorder() {
-diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/Explosion.java
-+++ b/src/main/java/net/minecraft/world/level/Explosion.java
-@@ -0,0 +0,0 @@ public class Explosion {
- bukkitBlocks = event.blockList();
- this.yield = event.getYield();
- } else {
-- BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, this.yield);
-+ BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, this.yield, this.damageSource.explodedBlockState); // Paper - add exploded state
- this.level.getCraftServer().getPluginManager().callEvent(event);
- this.wasCanceled = event.isCancelled();
- bukkitBlocks = event.blockList();
-diff --git a/src/main/java/net/minecraft/world/level/block/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/block/BedBlock.java
-+++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java
-@@ -0,0 +0,0 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
-
- // CraftBukkit - moved world and biome check into EntityHuman
- if (false && !BedBlock.canSetSpawn(world)) {
-+ final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getUnplacedBlockState(world, pos, state); // Paper - add exploded state (this won't be called due to the false, but it's good for reference)
- world.removeBlock(pos, false);
- BlockPos blockposition1 = pos.relative(((Direction) state.getValue(BedBlock.FACING)).getOpposite());
-
-@@ -0,0 +0,0 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
-
- Vec3 vec3d = pos.getCenter();
-
-- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
-+ world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state
- return InteractionResult.SUCCESS;
- } else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) {
- if (!this.kickVillagerOutOfBed(world, pos)) {
-@@ -0,0 +0,0 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
- private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition) {
- {
- {
-+ final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getUnplacedBlockState(world, blockposition, iblockdata); // Paper - add exploded state
- world.removeBlock(blockposition, false);
- BlockPos blockposition1 = blockposition.relative(((Direction) iblockdata.getValue(BedBlock.FACING)).getOpposite());
-
-@@ -0,0 +0,0 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
-
- Vec3 vec3d = blockposition.getCenter();
-
-- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
-+ world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state
- return InteractionResult.SUCCESS;
- }
- }
-diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
-+++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
-@@ -0,0 +0,0 @@ public class RespawnAnchorBlock extends Block {
- }
-
- private void explode(BlockState state, Level world, final BlockPos explodedPos) {
-+ final org.bukkit.block.BlockState explodedBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world, explodedPos, state, null); // Paper - add exploded state
- world.removeBlock(explodedPos, false);
- Stream stream = Direction.Plane.HORIZONTAL.stream(); // CraftBukkit - decompile error
-
-@@ -0,0 +0,0 @@ public class RespawnAnchorBlock extends Block {
- };
- Vec3 vec3d = explodedPos.getCenter();
-
-- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
-+ world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state
- }
-
- public static boolean canSetSpawn(Level world) {
-diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
-+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
-@@ -0,0 +0,0 @@ public final class CraftBlockStates {
- BlockEntity tileEntity = (blockEntityTag == null) ? null : BlockEntity.loadStatic(blockPosition, blockData, blockEntityTag, registry);
- return CraftBlockStates.getBlockState(null, blockPosition, blockData, tileEntity);
- }
-+ // Paper start - add exploded state
-+ public static BlockState getUnplacedBlockState(net.minecraft.world.level.BlockGetter levelAccessor, BlockPos blockPos, net.minecraft.world.level.block.state.BlockState blockData) {
-+ BlockEntity tileEntity = levelAccessor.getBlockEntity(blockPos);
-+ return CraftBlockStates.getBlockState(null, blockPos, blockData, tileEntity);
-+ }
-+ // Paper end - add exploded state
-
- // See BlockStateFactory#createBlockState(World, BlockPosition, IBlockData, TileEntity)
- private static CraftBlockState getBlockState(World world, BlockPos blockPosition, net.minecraft.world.level.block.state.BlockState blockData, BlockEntity tileEntity) {
-diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
-@@ -0,0 +0,0 @@ public class CraftEventFactory {
- Entity damager = (bukkitDamageSource.isIndirect() && source.getDirectEntity() != null) ? source.getDirectEntity() : source.getCausingEntity();
- if (source.is(DamageTypeTags.IS_EXPLOSION)) {
- if (damager == null) {
-- return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
-+ return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.explodedBlockState); // Paper - Include BlockState for damage
- }
- DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION;
- return CraftEventFactory.callEntityDamageEvent(damager, entity, damageCause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
-@@ -0,0 +0,0 @@ public class CraftEventFactory {
- } else {
- throw new IllegalStateException(String.format("Unhandled damage of %s by %s from %s", entity, source.getDirectBlock(), source.getMsgId()));
- }
-- return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
-+ return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.explodedBlockState); // Paper - Include BlockState for damage
- }
-
- DamageCause cause;
-@@ -0,0 +0,0 @@ public class CraftEventFactory {
- return CraftEventFactory.callEntityDamageEvent(event, damagee, cancelled);
- }
-
-- private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map modifiers, Map> modifierFunctions, boolean cancelled) {
-- EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions);
-+ // Paper start
-+ private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map modifiers, Map> modifierFunctions, boolean cancelled) { // Paper
-+ return callEntityDamageEvent(damager, damagee, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, null);
-+ }
-+ private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map modifiers, Map> modifierFunctions, boolean cancelled, @Nullable org.bukkit.block.BlockState explodedBlockState) {
-+ EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, explodedBlockState);
-+ // Paper end
- return CraftEventFactory.callEntityDamageEvent(event, damagee, cancelled);
- }
-
diff --git a/patches/server/Add-exploded-block-state-to-EntityDamageByBlockEvent.patch b/patches/server/Add-exploded-block-state-to-EntityDamageByBlockEvent.patch
new file mode 100644
index 0000000000..b3fde36100
--- /dev/null
+++ b/patches/server/Add-exploded-block-state-to-EntityDamageByBlockEvent.patch
@@ -0,0 +1,67 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jake Potrebic
+Date: Fri, 22 Oct 2021 16:25:07 -0700
+Subject: [PATCH] Add exploded block state to EntityDamageByBlockEvent
+
+== AT ==
+public org.bukkit.craftbukkit.block.CraftBlockStates getBlockState(Lorg/bukkit/World;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/entity/BlockEntity;)Lorg/bukkit/craftbukkit/block/CraftBlockState;
+
+diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSources.java b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/damagesource/DamageSources.java
++++ b/src/main/java/net/minecraft/world/damagesource/DamageSources.java
+@@ -0,0 +0,0 @@ public class DamageSources {
+ return this.source(DamageTypes.SONIC_BOOM, attacker);
+ }
+
++ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - add exploded state
+ public DamageSource badRespawnPointExplosion(Vec3 position) {
+ // CraftBukkit start
+ return this.badRespawnPointExplosion(position, null, null, null);
+@@ -0,0 +0,0 @@ public class DamageSources {
+ public DamageSource badRespawnPointExplosion(Vec3 vec3d, net.minecraft.world.level.Level world, net.minecraft.world.level.block.state.BlockState blockData, net.minecraft.core.BlockPos position) {
+ DamageSource damageSource = new DamageSource(this.damageTypes.getHolderOrThrow(DamageTypes.BAD_RESPAWN_POINT), vec3d);
+ if (world != null && blockData != null && position != null) {
+- damageSource.blockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world, position, blockData, null);
++ damageSource.blockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world.getWorld(), position, blockData, world.getBlockEntity(position)); // Paper
+ }
+ return damageSource;
+ // CraftBukkit end
+diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+@@ -0,0 +0,0 @@ public class CraftEventFactory {
+ Entity damager = (bukkitDamageSource.isIndirect() && source.getDirectEntity() != null) ? source.getDirectEntity() : source.getCausingEntity();
+ if (source.is(DamageTypeTags.IS_EXPLOSION)) {
+ if (damager == null) {
+- return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
++ return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.blockState); // Paper - Include BlockState for damage
+ }
+ DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION;
+ return CraftEventFactory.callEntityDamageEvent(damager, entity, damageCause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API
+@@ -0,0 +0,0 @@ public class CraftEventFactory {
+ } else {
+ throw new IllegalStateException(String.format("Unhandled damage of %s by %s from %s", entity, source.getDirectBlock(), source.getMsgId()));
+ }
+- return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled);
++ return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.blockState); // Paper - Include BlockState for damage
+ }
+
+ DamageCause cause;
+@@ -0,0 +0,0 @@ public class CraftEventFactory {
+ return CraftEventFactory.callEntityDamageEvent(event, damagee, cancelled);
+ }
+
+- private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map modifiers, Map> modifierFunctions, boolean cancelled) {
+- EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions);
++ // Paper start
++ private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map modifiers, Map> modifierFunctions, boolean cancelled) { // Paper
++ return callEntityDamageEvent(damager, damagee, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, null);
++ }
++ private static EntityDamageEvent callEntityDamageEvent(Block damager, Entity damagee, DamageCause cause, org.bukkit.damage.DamageSource bukkitDamageSource, Map modifiers, Map> modifierFunctions, boolean cancelled, @Nullable org.bukkit.block.BlockState explodedBlockState) {
++ EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(damager, damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, explodedBlockState);
++ // Paper end
+ return CraftEventFactory.callEntityDamageEvent(event, damagee, cancelled);
+ }
+
diff --git a/patches/server/Catch-JsonParseException-in-block-entity-names.patch b/patches/server/Catch-JsonParseException-in-block-entity-names.patch
new file mode 100644
index 0000000000..5b5782293f
--- /dev/null
+++ b/patches/server/Catch-JsonParseException-in-block-entity-names.patch
@@ -0,0 +1,27 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Noah van der Aa
+Date: Mon, 29 Apr 2024 23:12:33 +0200
+Subject: [PATCH] Catch JsonParseException in block entity names
+
+As a result, data that no longer parses correctly will not crash the server
+instead just logging the exception and continuing (and in most cases should
+fix the data)
+
+Player data is fixed pretty much immediately but some block data (like
+Shulkers) may need to be changed in order for it to re-save properly
+
+No more crashing though.
+
+diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
++++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
+@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
+ }
+
+ if (nbt.contains("custom_name", 8)) {
+- this.customName = Component.Serializer.fromJson(nbt.getString("custom_name"), registryLookup);
++ this.customName = BlockEntity.parseCustomNameSafe(nbt.getString("custom_name"), registryLookup); // Paper
+ } else {
+ this.customName = null;
+ }
diff --git a/patches/server/Catch-JsonParseException-in-entity-and-block-entity-.patch b/patches/server/Catch-JsonParseException-in-entity-and-block-entity-.patch
deleted file mode 100644
index 45916defee..0000000000
--- a/patches/server/Catch-JsonParseException-in-entity-and-block-entity-.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Zach Brown <1254957+zachbr@users.noreply.github.com>
-Date: Sat, 22 Sep 2018 15:56:59 -0400
-Subject: [PATCH] Catch JsonParseException in entity and block entity names
-
-As a result, data that no longer parses correctly will not crash the server
-instead just logging the exception and continuing (and in most cases should
-fix the data)
-
-Player data is fixed pretty much immediately but some block data (like
-Shulkers) may need to be changed in order for it to re-save properly
-
-No more crashing though.
-
-diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/io/papermc/paper/util/MCUtil.java
-+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
-@@ -0,0 +0,0 @@ public final class MCUtil {
-
- return builder.build();
- }
-+
-+ @Nullable
-+ public static net.minecraft.network.chat.Component getBaseComponentFromNbt(final String key, final net.minecraft.nbt.CompoundTag compound, final net.minecraft.core.HolderLookup.Provider lookupProvider) {
-+ if (!compound.contains(key)) {
-+ return null;
-+ }
-+ final String string = compound.getString(key);
-+ try {
-+ return net.minecraft.network.chat.Component.Serializer.fromJson(string, lookupProvider);
-+ } catch (com.google.gson.JsonParseException e) {
-+ org.bukkit.Bukkit.getLogger().warning("Unable to parse " + key + " from " + compound +": " + e.getMessage());
-+ }
-+
-+ return null;
-+ }
- }
-diff --git a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
-+++ b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
-@@ -0,0 +0,0 @@ public abstract class BaseCommandBlock implements CommandSource {
- this.command = nbt.getString("Command");
- this.successCount = nbt.getInt("SuccessCount");
- if (nbt.contains("CustomName", 8)) {
-- this.setCustomName(Component.Serializer.fromJson(nbt.getString("CustomName"), registries));
-+ this.setCustomName(io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt, registries)); // Paper - Catch ParseException
- } else {
- this.setCustomName((Component) null);
- }
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
-@@ -0,0 +0,0 @@ public class BannerBlockEntity extends BlockEntity implements Nameable {
- protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registryLookup) {
- super.loadAdditional(nbt, registryLookup);
- if (nbt.contains("CustomName", 8)) {
-- this.name = Component.Serializer.fromJson(nbt.getString("CustomName"), registryLookup);
-+ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt, registryLookup); // Paper - Catch ParseException
- }
-
- if (nbt.contains("patterns")) {
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
-@@ -0,0 +0,0 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
- super.loadAdditional(nbt, registryLookup);
- this.lockKey = LockCode.fromTag(nbt);
- if (nbt.contains("CustomName", 8)) {
-- this.name = Component.Serializer.fromJson(nbt.getString("CustomName"), registryLookup);
-+ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt, registryLookup); // Paper - Catch ParseException
- }
-
- }
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
-@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
- this.secondaryPower = BeaconBlockEntity.loadEffect(nbt, "secondary_effect");
- this.levels = nbt.getInt("Levels"); // CraftBukkit - SPIGOT-5053, use where available
- if (nbt.contains("CustomName", 8)) {
-- this.name = Component.Serializer.fromJson(nbt.getString("CustomName"), registryLookup);
-+ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt, registryLookup); // Paper - Catch ParseException
- }
-
- this.lockKey = LockCode.fromTag(nbt);
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/EnchantingTableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/EnchantingTableBlockEntity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/EnchantingTableBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/EnchantingTableBlockEntity.java
-@@ -0,0 +0,0 @@ public class EnchantingTableBlockEntity extends BlockEntity implements Nameable
- protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registryLookup) {
- super.loadAdditional(nbt, registryLookup);
- if (nbt.contains("CustomName", 8)) {
-- this.name = Component.Serializer.fromJson(nbt.getString("CustomName"), registryLookup);
-+ this.name = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("CustomName", nbt, registryLookup); // Paper - Catch ParseException
- }
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
-@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
- }
-
- if (nbt.contains("custom_name", 8)) {
-- this.customName = Component.Serializer.fromJson(nbt.getString("custom_name"), registryLookup);
-+ this.customName = io.papermc.paper.util.MCUtil.getBaseComponentFromNbt("custom_name", nbt, registryLookup); // Paper - Catch ParseException
- } else {
- this.customName = null;
- }
diff --git a/patches/server/Don-t-lose-removed-data-components-in-ItemMeta.patch b/patches/server/Don-t-lose-removed-data-components-in-ItemMeta.patch
index 9811f0d424..fdf1bf25ec 100644
--- a/patches/server/Don-t-lose-removed-data-components-in-ItemMeta.patch
+++ b/patches/server/Don-t-lose-removed-data-components-in-ItemMeta.patch
@@ -44,4 +44,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }, () -> itemTag.remove(e.getKey()));
}
- if (!this.persistentDataContainer.isEmpty()) {
+ CompoundTag customTag = (this.customTag != null) ? this.customTag.copy() : null;
diff --git a/patches/server/Fix-DamageSource-API.patch b/patches/server/Fix-DamageSource-API.patch
index 531482a46e..a597b57fa6 100644
--- a/patches/server/Fix-DamageSource-API.patch
+++ b/patches/server/Fix-DamageSource-API.patch
@@ -201,4 +201,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final Entity damager = source.getCustomEventDamager(); // Paper - fix DamageSource API
if (source.is(DamageTypeTags.IS_EXPLOSION)) {
if (damager == null) {
- return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.explodedBlockState); // Paper - Include BlockState for damage
+ return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.blockState); // Paper - Include BlockState for damage
diff --git a/patches/server/Fix-ItemFlags.patch b/patches/server/Fix-ItemFlags.patch
index f0c53e209d..eb914cbcd4 100644
--- a/patches/server/Fix-ItemFlags.patch
+++ b/patches/server/Fix-ItemFlags.patch
@@ -61,7 +61,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
CraftMetaItem(DataComponentPatch tag) {
@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
- }
+ this.customTag = null;
}
});
+ // Paper start - fix ItemFlags
diff --git a/patches/server/Fix-a-couple-of-upstream-bed-issues.patch b/patches/server/Fix-a-couple-of-upstream-bed-issues.patch
index 0386b458e6..956fe9eb51 100644
--- a/patches/server/Fix-a-couple-of-upstream-bed-issues.patch
+++ b/patches/server/Fix-a-couple-of-upstream-bed-issues.patch
@@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/level/block/BedBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java
@@ -0,0 +0,0 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, explodedBlockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // Paper - add exploded state
+ world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
return InteractionResult.SUCCESS;
} else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) {
+ if (!BedBlock.canSetSpawn(world)) return this.explodeBed(state, world, pos); // Paper - check explode first
diff --git a/patches/server/Properly-handle-pdc-and-custom-tags-in-ItemMeta.patch b/patches/server/Properly-handle-pdc-and-custom-tags-in-ItemMeta.patch
deleted file mode 100644
index 7234750649..0000000000
--- a/patches/server/Properly-handle-pdc-and-custom-tags-in-ItemMeta.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jake Potrebic
-Date: Fri, 26 Apr 2024 11:38:28 -0700
-Subject: [PATCH] Properly handle pdc and custom tags in ItemMeta
-
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
- this.customTag = customData.copyTag();
- if (this.customTag.contains(CraftMetaItem.BUKKIT_CUSTOM_TAG.NBT)) {
- CompoundTag compound = this.customTag.getCompound(CraftMetaItem.BUKKIT_CUSTOM_TAG.NBT);
-+ this.customTag.remove(CraftMetaItem.BUKKIT_CUSTOM_TAG.NBT); // Paper - remove PDC from custom tag
-+ if (this.customTag.isEmpty()) this.customTag = null; // Paper - remove PDC from custom tag
- Set keys = compound.getAllKeys();
- for (String key : keys) {
- this.persistentDataContainer.put(key, compound.get(key).copy());
-@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
- ByteArrayInputStream buf = new ByteArrayInputStream(Base64.getDecoder().decode(custom));
- try {
- this.customTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap());
-+ this.customTag.remove(CraftMetaItem.BUKKIT_CUSTOM_TAG.NBT); // Paper - ensure PDC isn't in custom tag
-+ if (this.customTag.isEmpty()) this.customTag = null; // Paper - ensure PDC isn't in custom tag
- } catch (IOException ex) {
- Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex);
- }
-@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
-
- if (this.customTag != null) {
- itemTag.put(CraftMetaItem.CUSTOM_DATA, CustomData.of(this.customTag));
-+ this.customTag.remove(CraftMetaItem.BUKKIT_CUSTOM_TAG.BUKKIT); // Paper - remove PDC from custom tag
-+ if (this.customTag.isEmpty()) this.customTag = null; // Paper - reset custom tag if empty
- }
- }
-
diff --git a/patches/server/Sanitize-sent-BlockEntity-NBT.patch b/patches/server/Sanitize-sent-BlockEntity-NBT.patch
index 8c12d1712a..6ad7ed40ff 100644
--- a/patches/server/Sanitize-sent-BlockEntity-NBT.patch
+++ b/patches/server/Sanitize-sent-BlockEntity-NBT.patch
@@ -9,11 +9,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
@@ -0,0 +0,0 @@ public class ClientboundBlockEntityDataPacket implements Packet nbtGetter) {
- RegistryAccess iregistrycustom = blockEntity.getLevel().registryAccess();
-- return new ClientboundBlockEntityDataPacket(blockEntity.getBlockPos(), blockEntity.getType(), (CompoundTag) nbtGetter.apply(blockEntity, iregistrycustom));
-+ return new ClientboundBlockEntityDataPacket(blockEntity.getBlockPos(), blockEntity.getType(), (CompoundTag) blockEntity.sanitizeSentNbt(nbtGetter.apply(blockEntity, iregistrycustom))); // Paper - Sanitize sent data
+ public static ClientboundBlockEntityDataPacket create(BlockEntity blockEntity, BiFunction nbtGetter) {
+ RegistryAccess registryAccess = blockEntity.getLevel().registryAccess();
+- return new ClientboundBlockEntityDataPacket(blockEntity.getBlockPos(), blockEntity.getType(), nbtGetter.apply(blockEntity, registryAccess));
++ return new ClientboundBlockEntityDataPacket(blockEntity.getBlockPos(), blockEntity.getType(), blockEntity.sanitizeSentNbt(nbtGetter.apply(blockEntity, registryAccess))); // Paper - Sanitize sent data
}
public static ClientboundBlockEntityDataPacket create(BlockEntity blockEntity) {
diff --git a/patches/server/Setup-Gradle-project.patch b/patches/server/Setup-Gradle-project.patch
index cf21a75732..baaf3e6133 100644
--- a/patches/server/Setup-Gradle-project.patch
+++ b/patches/server/Setup-Gradle-project.patch
@@ -170,7 +170,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- org.spigotmc
- spigot
- jar
-- 1.20.5-R0.1-SNAPSHOT
+- 1.20.6-R0.1-SNAPSHOT
- Spigot
- https://www.spigotmc.org/
-
diff --git a/work/BuildData b/work/BuildData
index a7f7c2118b..32d1baf2f4 160000
--- a/work/BuildData
+++ b/work/BuildData
@@ -1 +1 @@
-Subproject commit a7f7c2118b877fde4cf0f32f1f730ffcdee8e9ee
+Subproject commit 32d1baf2f4e0e7cd1ac22c7b2f6eb4c387e8a343
diff --git a/work/Bukkit b/work/Bukkit
index 304e83eb38..ac72b19b01 160000
--- a/work/Bukkit
+++ b/work/Bukkit
@@ -1 +1 @@
-Subproject commit 304e83eb384c338546aa96eea51388e0e8407e26
+Subproject commit ac72b19b01bcb3aef5710677b0b942e098479660
diff --git a/work/CraftBukkit b/work/CraftBukkit
index 91b1fc3f1c..0799013466 160000
--- a/work/CraftBukkit
+++ b/work/CraftBukkit
@@ -1 +1 @@
-Subproject commit 91b1fc3f1cf89e2591367dca1fa7362fe376f289
+Subproject commit 079901346673010c8eafe4b1e651b0c05d2e2f41
diff --git a/work/Spigot b/work/Spigot
index b698b49caf..e2c1eee02c 160000
--- a/work/Spigot
+++ b/work/Spigot
@@ -1 +1 @@
-Subproject commit b698b49caf14f97a717afd67e13fd7ac59f51089
+Subproject commit e2c1eee02c2e00f71d78c56d6439dafc3af7dfac