aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJake Potrebic <[email protected]>2024-03-16 11:51:22 -0700
committerGitHub <[email protected]>2024-03-16 11:51:22 -0700
commitd361a7f60912250ceeee9461f1f97d23dd87ff76 (patch)
tree07dcfe4f3c881fad4ed80cfc1c951d8688a47449
parente6034867bab45fd507d68e238500bba730c6ffb9 (diff)
downloadPaper-d361a7f60912250ceeee9461f1f97d23dd87ff76.tar.gz
Paper-d361a7f60912250ceeee9461f1f97d23dd87ff76.zip
Fix DamageSource API (#10307)
Uses the correct entity in the EntityDamageByEntity event Returns the correct entity for API's DamageSource#getCausingEntity
-rw-r--r--patches/api/0466-Fix-DamageSource-API.patch31
-rw-r--r--patches/server/1055-Fix-DamageSource-API.patch198
2 files changed, 229 insertions, 0 deletions
diff --git a/patches/api/0466-Fix-DamageSource-API.patch b/patches/api/0466-Fix-DamageSource-API.patch
new file mode 100644
index 0000000000..efe4403e2c
--- /dev/null
+++ b/patches/api/0466-Fix-DamageSource-API.patch
@@ -0,0 +1,31 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jake Potrebic <[email protected]>
+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 6b24d1281cb8f0253430c9c1a1323e2670bb9c93..8ea4be529400b34df3d31b0f17c2d145345523d9 100644
+--- a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java
++++ b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java
+@@ -60,6 +60,20 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent {
+ }
+ // Paper end
+
++ // Paper start
++ /**
++ * {@inheritDoc}
++ * <p>
++ * 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/1055-Fix-DamageSource-API.patch b/patches/server/1055-Fix-DamageSource-API.patch
new file mode 100644
index 0000000000..3c80fe5209
--- /dev/null
+++ b/patches/server/1055-Fix-DamageSource-API.patch
@@ -0,0 +1,198 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jake Potrebic <[email protected]>
+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 be2220457e941803b14d78c550d0db777c79a886..f5a86c0fb1a7a313afc4c56ffc445a7fe7821428 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<DamageModifier, Double> modifiers, Map<DamageModifier, Function<? super Double, Double>> 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) {