diff --git a/patches/api/Fix-DamageSource-API.patch b/patches/api/Fix-DamageSource-API.patch new file mode 100644 index 0000000000..1178c75921 --- /dev/null +++ b/patches/api/Fix-DamageSource-API.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 16 Mar 2024 11:21:14 -0700 +Subject: [PATCH] Fix DamageSource API + + +diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java ++++ b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java +@@ -0,0 +0,0 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent { + } + // Paper end + ++ // Paper start ++ /** ++ * {@inheritDoc} ++ *

++ * The {@link DamageSource#getDirectEntity()} may be different from the {@link #getDamager()} ++ * if the Minecraft damage source did not originally include an damager entity, but one was included ++ * for this event {@link #getDamager()}. ++ */ ++ @Override ++ public @NotNull DamageSource getDamageSource() { ++ return super.getDamageSource(); ++ } ++ // Paper end ++ + /** + * Returns the entity that damaged the defender. + * diff --git a/patches/server/Fix-DamageSource-API.patch b/patches/server/Fix-DamageSource-API.patch new file mode 100644 index 0000000000..7034901e28 --- /dev/null +++ b/patches/server/Fix-DamageSource-API.patch @@ -0,0 +1,198 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 9 Mar 2024 14:13:04 -0800 +Subject: [PATCH] Fix DamageSource API + +Uses the correct entity in the EntityDamageByEntity event +Returns the correct entity for API's DamageSource#getCausingEntity + +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 boolean withSweep = false; + private boolean melting = false; + private boolean poison = false; +- private Entity customCausingEntity = null; // This field is a helper for when causing entity damage is not set by vanilla ++ @Nullable ++ private Entity customEventDamager = null; // This field is a helper for when causing entity damage is not set by vanilla // Paper - fix DamageSource API + + public DamageSource sweep() { + this.withSweep = true; +@@ -0,0 +0,0 @@ public class DamageSource { + return this.poison; + } + +- public Entity getCausingEntity() { +- return (this.customCausingEntity != null) ? this.customCausingEntity : this.causingEntity; ++ // Paper start - fix DamageSource API ++ public @Nullable Entity getCustomEventDamager() { ++ return (this.customEventDamager != null) ? this.customEventDamager : this.directEntity; + } + +- public DamageSource customCausingEntity(Entity entity) { ++ public DamageSource customEventDamager(Entity entity) { ++ if (this.directEntity != null) { ++ throw new IllegalStateException("Cannot set a custom event damager entity when a direct entity is already set (report as a bug to Paper)"); ++ } + DamageSource damageSource = this.cloneInstance(); +- damageSource.customCausingEntity = entity; ++ damageSource.customEventDamager = entity; ++ // Paper end - fix DamageSource API + return damageSource; + } + +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S + return; + } + +- if (!this.hurt(this.damageSources().lightningBolt().customCausingEntity(lightning), 5.0F)) { ++ if (!this.hurt(this.damageSources().lightningBolt().customEventDamager(lightning), 5.0F)) { // Paper - fix DamageSource API + return; + } + // CraftBukkit end +diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java ++++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java +@@ -0,0 +0,0 @@ public class Turtle extends Animal { + + @Override + public void thunderHit(ServerLevel world, LightningBolt lightning) { +- this.hurt(this.damageSources().lightningBolt().customCausingEntity(lightning), Float.MAX_VALUE); // CraftBukkit ++ this.hurt(this.damageSources().lightningBolt().customEventDamager(lightning), Float.MAX_VALUE); // CraftBukkit // Paper - fix DamageSource API + } + + @Override +diff --git a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java ++++ b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java +@@ -0,0 +0,0 @@ public abstract class HangingEntity extends Entity { + } else { + if (!this.isRemoved() && !this.level().isClientSide) { + // CraftBukkit start - fire break events +- Entity damager = (source.isIndirect()) ? source.getEntity() : source.getDirectEntity(); ++ Entity damager = (source.isIndirect() && source.getEntity() != null) ? source.getEntity() : source.getDirectEntity(); // Paper - fix DamageSource API + HangingBreakEvent event; + if (damager != null) { + event = new HangingBreakByEntityEvent((Hanging) this.getBukkitEntity(), damager.getBukkitEntity(), source.is(DamageTypeTags.IS_EXPLOSION) ? HangingBreakEvent.RemoveCause.EXPLOSION : HangingBreakEvent.RemoveCause.ENTITY); +diff --git a/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java b/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java +@@ -0,0 +0,0 @@ public class EvokerFangs extends Entity implements TraceableEntity { + + if (target.isAlive() && !target.isInvulnerable() && target != entityliving1) { + if (entityliving1 == null) { +- target.hurt(this.damageSources().magic().customCausingEntity(this), 6.0F); // CraftBukkit ++ target.hurt(this.damageSources().magic().customEventDamager(this), 6.0F); // CraftBukkit // Paper - fix DamageSource API + } else { + if (entityliving1.isAlliedTo((Entity) target)) { + return; +diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +@@ -0,0 +0,0 @@ public class ThrownEnderpearl extends ThrowableItemProjectile { + + entityplayer.connection.teleport(teleEvent.getTo()); + entity.resetFallDistance(); +- entity.hurt(this.damageSources().fall().customCausingEntity(this), 5.0F); // CraftBukkit ++ entity.hurt(this.damageSources().fall().customEventDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API + } + // CraftBukkit end + this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_TELEPORT, SoundSource.PLAYERS); +diff --git a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java ++++ b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java +@@ -0,0 +0,0 @@ public class WitherSkull extends AbstractHurtingProjectile { + } + } + } else { +- flag = entity.hurt(this.damageSources().magic().customCausingEntity(this), 5.0F); // Paper - Fire EntityDamageByEntityEvent for unowned wither skulls ++ flag = entity.hurt(this.damageSources().magic().customEventDamager(this), 5.0F); // Paper - Fire EntityDamageByEntityEvent for unowned wither skulls // Paper - fix DamageSource API + } + + if (flag && entity instanceof LivingEntity) { +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 { + this.z = z; + this.fire = createFire; + this.blockInteraction = destructionType; +- this.damageSource = damageSource == null ? world.damageSources().explosion(this).customCausingEntity(entity) : damageSource.customCausingEntity(entity); // CraftBukkit - handle source entity ++ this.damageSource = damageSource == null ? world.damageSources().explosion(this) : damageSource; // CraftBukkit - handle source entity // Paper - revert to fix DamageSource API + this.damageCalculator = behavior == null ? this.makeDamageCalculator(entity) : behavior; + this.smallExplosionParticles = particle; + this.largeExplosionParticles = emitterParticle; +diff --git a/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java b/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java ++++ b/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java +@@ -0,0 +0,0 @@ public class CraftDamageSource implements DamageSource { + + @Override + public org.bukkit.entity.Entity getCausingEntity() { +- net.minecraft.world.entity.Entity entity = this.getHandle().getCausingEntity(); ++ net.minecraft.world.entity.Entity entity = this.getHandle().getEntity(); // Paper - fix DamageSource API + return (entity != null) ? entity.getBukkitEntity() : null; + } + +@@ -0,0 +0,0 @@ public class CraftDamageSource implements DamageSource { + + @Override + public boolean isIndirect() { +- return this.getHandle().getCausingEntity() != this.getHandle().getDirectEntity(); ++ return this.getHandle().isIndirect(); // Paper - fix DamageSource API + } + + @Override +diff --git a/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSourceBuilder.java b/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSourceBuilder.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSourceBuilder.java ++++ b/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSourceBuilder.java +@@ -0,0 +0,0 @@ public class CraftDamageSourceBuilder implements DamageSource.Builder { + + @Override + public DamageSource build() { ++ // Paper start - fix DamageCause API ++ if (this.causingEntity != null && this.directEntity == null) { ++ throw new IllegalArgumentException("Direct entity must be set if causing entity is set"); ++ } ++ // Paper end - fix DamageCause API + return CraftDamageSource.buildFromBukkit(this.damageType, this.causingEntity, this.directEntity, this.damageLocation); + } + } +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 { + + private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map modifiers, Map> modifierFunctions, boolean cancelled) { + CraftDamageSource bukkitDamageSource = new CraftDamageSource(source); +- Entity damager = source.getCausingEntity(); ++ 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 +@@ -0,0 +0,0 @@ public class CraftEventFactory { + } else if (damager != null || source.getDirectEntity() != null) { + DamageCause cause = (source.isSweep()) ? DamageCause.ENTITY_SWEEP_ATTACK : DamageCause.ENTITY_ATTACK; + +- if (bukkitDamageSource.isIndirect() && source.getDirectEntity() != null) { +- damager = source.getDirectEntity(); +- } ++ // Paper - fix DamageSource API + + if (damager instanceof net.minecraft.world.entity.projectile.Projectile) { + if (damager.getBukkitEntity() instanceof ThrownPotion) {