If a player shoots an arrow and the arrow is deflected, whilst the player is offline, the arrow looses its owner tag.
Linked issues
Attachments
Comments 6
Im also using Squibbles Stasis Chamber… in 1.21.4 this bug was only by paper, but in 1.21.6 its also present in vanilla
This is because the AbstractArrow
stores the owner as an EntityReference
. During deflection, Projectile#getOwner
is called which attempts to find the entity in the current level.
It’s unclear why the equivalent of this.setOwner(this.getOwner())
is called in the first place, which may result in the invalidation of the reference and the owner to be lost.
A fix for this would be to instead pass a nullable EntityReference
instead of a nullable Entity
as the owner parameter in Projectile#deflect
@Mixin(Projectile.class)
public class ProjectileMixin {
@Shadow
@Nullable
protected EntityReference<Entity> owner;
/**
* This deflect method takes the `Entity` owner, not an `EntityReference<Entity>`.
* This means during deflection, the owner is resolved from its reference.
* Because the owner is no longer online, it is nullified.
*/
@WrapWithCondition(method = "deflect", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/projectile/Projectile;setOwner(Lnet/minecraft/world/entity/Entity;)V"))
private boolean preventNullifyingOwner(Projectile instance, Entity owner) {
// only allow setting the owner if:
// 1. the new owner is not null
// 2. the current owner reference is null (which means it never had a reference to any owner)
return this.owner == null || owner != null;
}
}
mixin to patch the issue
<1.21.6 This was not an issue. This bug was introduced with the changes in arrow behavior in 1.21.6. This is affecting player experience greatly on the server I play, as we use Squibble's Stasis making use of this feature. The arrow loses owner tag when player logs off and does not regain in when they log back on. This is not an issue in single player (by my tests).