From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Tue, 30 May 2023 12:59:10 -0700 Subject: [PATCH] Refresh ProjectileSource for projectiles Makes sure the value returned by Projectile#getShooter in the API matches the owner UUID specified in the entity nbt. Previously, after the entity reloaded, Projectile#getShooter would return null, while the entity still had an owner. Also fixes setting the shooter/owner to null actually clearing the owner. Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com> diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 9c686161a1248af1cc8ae20c67c7b2b8d881e07d..cedf5d153abf6d0edc2a56ca7e393ece362145d3 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -386,6 +386,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S public boolean inWorld = false; public boolean generation; public int maxAirTicks = this.getDefaultMaxAirSupply(); // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir() + @Nullable // Paper - Refresh ProjectileSource for projectiles public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only public boolean lastDamageCancelled; // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Keep track if the event was canceled public boolean persistentInvisibility = false; diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java index 270dd1db56b187bffaedba9f2b86b3e46dda3152..5b6d5c799cc8e601a01b6967917e15ba1e2db721 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java @@ -50,14 +50,31 @@ public abstract class Projectile extends Entity implements TraceableEntity { this.ownerUUID = entity.getUUID(); this.cachedOwner = entity; } - this.projectileSource = (entity != null && entity.getBukkitEntity() instanceof ProjectileSource) ? (ProjectileSource) entity.getBukkitEntity() : null; // CraftBukkit - + // Paper start - Refresh ProjectileSource for projectiles + else { + this.ownerUUID = null; + this.cachedOwner = null; + this.projectileSource = null; + } + // Paper end - Refresh ProjectileSource for projectiles + this.refreshProjectileSource(false); // Paper + } + // Paper start - Refresh ProjectileSource for projectiles + public void refreshProjectileSource(boolean fillCache) { + if (fillCache) { + this.getOwner(); + } + if (this.cachedOwner != null && !this.cachedOwner.isRemoved() && this.projectileSource == null && this.cachedOwner.getBukkitEntity() instanceof ProjectileSource projSource) { + this.projectileSource = projSource; + } } + // Paper end - Refresh ProjectileSource for projectiles @Nullable @Override public Entity getOwner() { if (this.cachedOwner != null && !this.cachedOwner.isRemoved()) { + this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles return this.cachedOwner; } else { if (this.ownerUUID != null) { @@ -67,6 +84,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { ServerLevel worldserver = (ServerLevel) world; this.cachedOwner = worldserver.getEntity(this.ownerUUID); + this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles return this.cachedOwner; } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java index c1c52f4fc5f900fac4098e5e37c52dfc4e82b8bb..236f94348ff8da661e23e3e17b7fc1b143680da9 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java @@ -60,6 +60,7 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti @Override public final org.bukkit.projectiles.ProjectileSource getShooter() { + this.getHandle().refreshProjectileSource(true); // Paper - Refresh ProjectileSource for projectiles return this.getHandle().projectileSource; }