Fix velocity packets being sent for flying players

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2022-06-04 20:38:31 +02:00
parent 58b6e90142
commit ff712575ad
2 changed files with 27 additions and 18 deletions

View File

@ -581,11 +581,11 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
// World border collision
final Pos finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition);
final boolean positionChanged = !finalVelocityPosition.samePoint(position);
final boolean flying = this instanceof Player player && player.isFlying();
final boolean isPlayer = this instanceof Player;
final boolean flying = isPlayer && ((Player) this).isFlying();
if (!positionChanged) {
if (flying) {
this.velocity = Vec.ZERO;
sendPacketToViewers(getVelocityPacket());
return;
} else if (hasVelocity || newVelocity.isZero()) {
this.velocity = noGravity ? Vec.ZERO : new Vec(
@ -593,7 +593,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
-gravityAcceleration * tps * (1 - gravityDragPerTick),
0
);
sendPacketToViewers(getVelocityPacket());
if (!isPlayer) sendPacketToViewers(getVelocityPacket());
return;
}
}
@ -620,7 +620,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
updateVelocity(wasOnGround, flying, positionBeforeMove, newVelocity);
}
// Verify if velocity packet has to be sent
if (!(this instanceof Player) && (hasVelocity || gravityTickCount > 0)) {
if (!isPlayer && (hasVelocity || gravityTickCount > 0)) {
sendPacketToViewers(getVelocityPacket());
}
}

View File

@ -5,6 +5,7 @@ import net.minestom.server.api.EnvTest;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.instance.Instance;
import net.minestom.server.network.packet.server.play.EntityVelocityPacket;
import net.minestom.server.utils.chunk.ChunkUtils;
import org.junit.jupiter.api.Test;
@ -21,16 +22,14 @@ public class EntityVelocityIntegrationTest {
entity.setInstance(instance, new Pos(0, 42, 0)).join();
env.tick(); // Ensure velocity downwards is present
testMovement(env, entity, new Vec[] {
new Vec(0.0, 42.0, 0.0),
testMovement(env, entity, new Vec(0.0, 42.0, 0.0),
new Vec(0.0, 41.92159999847412, 0.0),
new Vec(0.0, 41.76636799395752, 0.0),
new Vec(0.0, 41.53584062504456, 0.0),
new Vec(0.0, 41.231523797587016, 0.0),
new Vec(0.0, 40.85489329934836, 0.0),
new Vec(0.0, 40.40739540236494, 0.0),
new Vec(0.0, 40.0, 0.0)
});
new Vec(0.0, 40.0, 0.0));
}
@Test
@ -44,8 +43,7 @@ public class EntityVelocityIntegrationTest {
env.tick(); // Ensures the entity is onGround
entity.takeKnockback(0.4f, 0, -1);
testMovement(env, entity, new Vec[] {
new Vec(0.0, 40.0, 0.0),
testMovement(env, entity, new Vec(0.0, 40.0, 0.0),
new Vec(0.0, 40.360800005197525, 0.4000000059604645),
new Vec(0.0, 40.63598401564693, 0.6184000345826153),
new Vec(0.0, 40.827264349610196, 0.8171440663565412),
@ -62,8 +60,7 @@ public class EntityVelocityIntegrationTest {
new Vec(0.0, 40.0, 1.9757875252341128),
new Vec(0.0, 40.0, 1.9840936051840241),
new Vec(0.0, 40.0, 1.9886287253634418),
new Vec(0.0, 40.0, 1.9886287253634418),
});
new Vec(0.0, 40.0, 1.9886287253634418));
}
@Test
@ -80,8 +77,7 @@ public class EntityVelocityIntegrationTest {
assertTrue(entity.hasVelocity());
testMovement(env, entity, new Vec[] {
new Vec(0.0, 40.0, 0.0),
testMovement(env, entity, new Vec(0.0, 40.0, 0.0),
new Vec(0.0, 40.4, 0.7000000029802322),
new Vec(0.0, 40.71360000610351, 1.0822000490009787),
new Vec(0.0, 40.94252801654052, 1.4300021009034531),
@ -99,8 +95,7 @@ public class EntityVelocityIntegrationTest {
new Vec(0.0, 40.0, 3.5916417190562298),
new Vec(0.0, 40.0, 3.6048691516168874),
new Vec(0.0, 40.0, 3.6120913306338815),
new Vec(0.0, 40.0, 3.616034640835186)
});
new Vec(0.0, 40.0, 3.616034640835186));
}
@Test
@ -128,6 +123,20 @@ public class EntityVelocityIntegrationTest {
assertEquals(player.getVelocity().y(), 0);
}
@Test
public void flyingPlayerMovement(Env env) {
// Player movement should not send velocity packets as already client predicted
var instance = env.createFlatInstance();
var player = env.createPlayer(instance, new Pos(0, 42, 0));
player.setFlying(true);
var witness = env.createConnection();
witness.connect(instance, new Pos(0, 42, 0)).join();
var tracker = witness.trackIncoming(EntityVelocityPacket.class);
env.tick(); // Process gravity velocity
tracker.assertEmpty();
}
@Test
public void testHasVelocity(Env env) {
var instance = env.createFlatInstance();
@ -151,7 +160,7 @@ public class EntityVelocityIntegrationTest {
assertFalse(entity.hasVelocity());
}
private void testMovement(Env env, Entity entity, Vec[] sample) {
private void testMovement(Env env, Entity entity, Vec... sample) {
final double epsilon = 0.003;
for (Vec vec : sample) {
assertEquals(vec.x(), entity.getPosition().x(), epsilon);
@ -162,7 +171,7 @@ public class EntityVelocityIntegrationTest {
}
private void loadChunks(Instance instance) {
ChunkUtils.optionalLoadAll(instance, new long[] {
ChunkUtils.optionalLoadAll(instance, new long[]{
ChunkUtils.getChunkIndex(-1, -1),
ChunkUtils.getChunkIndex(-1, 0),
ChunkUtils.getChunkIndex(-1, 1),