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 1561b85a45f52a8162f43553f8485bfe084b8f1f..b26e4d58ea1898a5e4b31c3d6ab33f38835ab2c6 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java @@ -27,7 +27,8 @@ 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; @@ -56,13 +57,18 @@ 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 6de971aca46caad091271d125a079a1b7a5f163d..b2eff51f1ad1e702525ef298807ea7d2083f6218 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -3462,7 +3462,7 @@ 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 dbdb6c432448b151fa4421f14235f8bad23dc720..2eb099957a3d0bae3339ff4edbab103fb348abed 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java @@ -336,7 +336,7 @@ 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 4dea85a8ab8ae16d02e35d226fd155891ce2319a..eaad15a4d201356c34c1a09c7fbe5c35f76a2176 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java +++ b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java @@ -204,7 +204,7 @@ 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 a729460e35bbef134bdf0d72d8894c3df007f7b8..e6f549f1fcd261f96f0e4fc4cbe26a04c389d191 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java +++ b/src/main/java/net/minecraft/world/entity/projectile/EvokerFangs.java @@ -132,7 +132,7 @@ 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 28690877c443ceb2bdf20e6d251c9d32f667814c..1fb1e729d6879568d8b4943071fa940325b2e5b0 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEnderpearl.java @@ -86,7 +86,7 @@ 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 5c7a6fe97b1f0b55b4a5dddbb684e4424688f866..6f49b9b8707d74330adb973e0db3cd5bccf138b6 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java +++ b/src/main/java/net/minecraft/world/entity/projectile/WitherSkull.java @@ -72,7 +72,7 @@ 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 b678da2cbb93cea7971bc3c4d324cfca18b0bc97..90a82bd7977ebe520bdcc2ab99e11452d5cf4a21 100644 --- a/src/main/java/net/minecraft/world/level/Explosion.java +++ b/src/main/java/net/minecraft/world/level/Explosion.java @@ -103,7 +103,7 @@ 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 6ae1ad21807c039726021f8f26f92042acce2fda..b7e2327c50195e8d3ca3ca3b47c7c0f9ea8e289c 100644 --- a/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java +++ b/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java @@ -41,7 +41,7 @@ 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; } @@ -65,7 +65,7 @@ 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 4c6e15535fa40aad8cf1920f392589404f9ba79c..35eb95ef6fb6a0f7ea63351e90741c489fdd15f9 100644 --- a/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSourceBuilder.java +++ b/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSourceBuilder.java @@ -41,6 +41,11 @@ 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 4c2e8129481384a143384d327e14320023735b1a..cb3e9672f375a1a660757a05362729ddb5ca7504 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1082,7 +1082,7 @@ 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 @@ -1092,9 +1092,7 @@ 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) {