D
Deleted member 94
Guest
I did ask this last year on Discord channel, but I have tried more things since then but I still have not found solution so I thought I ask here if anyone has any ideas, if not it is OK.
My goal is to detect specific movement of a falling block entity, when it collides with cobble wall. Currently I detect similar movement by using
Here is the type of movement I speak of:
Sand (or other gravity block) pushes up by piston, hits slime but does not go 100% into end portal. In vanilla, it is duped. In paper it sits on edge.
Here is code I use to detect other type of similar movement:
Things I have thought of
Please advise if you have any ideas, I am okay with use of NMS or anything hacky I just can not have bootstrap for server. It must work like normal plugin and ideal I should be able to make it compatible with
My goal is to detect specific movement of a falling block entity, when it collides with cobble wall. Currently I detect similar movement by using
EntityChangeBlockEvent
and check correct velocity, but this is not possible for this type of movement because the velocity returns 0, 0, 0
.Here is the type of movement I speak of:

Sand (or other gravity block) pushes up by piston, hits slime but does not go 100% into end portal. In vanilla, it is duped. In paper it sits on edge.
Here is code I use to detect other type of similar movement:
Java:
@EventHandler(priority = EventPriority.HIGHEST)
public void onEntityChangeBlock(final EntityChangeBlockEvent event) {
if (!(event.getEntity() instanceof final FallingBlock falling) || event.getTo() == Material.AIR) return;
final Vector velocity = falling.getVelocity().clone();
for (BlockFace face : ALLOWED_PORTAL_FACES) {
final Block relative = event.getBlock().getRelative(face);
if (relative.getType() != Material.END_PORTAL) continue;
if ((face == BlockFace.NORTH && velocity.getZ() < 0D)
|| (face == BlockFace.EAST && velocity.getX() > 0D)
|| (face == BlockFace.SOUTH && velocity.getZ() > 0D)
|| (face == BlockFace.WEST && velocity.getX() < 0D)) {
LOGGER.info("Falling block {} hit!", falling);
return;
}
}
}
Things I have thought of
- Possible collision event, I do not think this exists
- Listen to
EntityMoveEvent
and calculate this specific motion/check blockfaces on each move. This seems very costly so I do not want to do this, and will require storing previous positions as well to calculate correct movement. I am afraid this will create many false positives and false negatives, it will be very tight algorithm and will not be easy to expand for other cases like this. - Use ByteBuddyAgent to rewrite class for falling blocks at runtime. I am told this is not possible without pre-defined agent via bootstrap or access to the server classloader, which I do not have. I have not been able to do this successfully, my test code fails with no error just silent:
Java:
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(FallingBlockEntity.class)
.method(
ElementMatchers.named("tick")
)
.intercept(MethodDelegation.to(FallingFakeBlockEntity.class))
.make()
.load(FallingBlockEntity.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
Java:
public class FallingFakeBlockEntity {
public void tick() {
System.out.println("ticked");
}
}
Please advise if you have any ideas, I am okay with use of NMS or anything hacky I just can not have bootstrap for server. It must work like normal plugin and ideal I should be able to make it compatible with
/reload
but this is not requirement.- Version Output
- 1.17+