Stop update from being sent to the player when the player places a block on themselves (#939)

This commit is contained in:
iam 2022-04-17 16:02:24 -04:00 committed by GitHub
parent e57e3ff305
commit bb236b34b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 11 deletions

View File

@ -329,7 +329,7 @@ final class BlockCollision {
Vec.ZERO, finalResult.collidedShapePosition, finalResult.blockType); Vec.ZERO, finalResult.collidedShapePosition, finalResult.blockType);
} }
static boolean canPlaceBlockAt(Instance instance, Point blockPos, Block b) { static Entity canPlaceBlockAt(Instance instance, Point blockPos, Block b) {
for (Entity entity : instance.getNearbyEntities(blockPos, 3)) { for (Entity entity : instance.getNearbyEntities(blockPos, 3)) {
final EntityType type = entity.getEntityType(); final EntityType type = entity.getEntityType();
if (type == EntityType.ITEM) if (type == EntityType.ITEM)
@ -348,9 +348,9 @@ final class BlockCollision {
} else { } else {
intersects = b.registry().collisionShape().intersectBox(entity.getPosition().sub(blockPos), entity.getBoundingBox()); intersects = b.registry().collisionShape().intersectBox(entity.getPosition().sub(blockPos), entity.getBoundingBox());
} }
if (intersects) return false; if (intersects) return entity;
} }
return true; return null;
} }
/** /**

View File

@ -80,7 +80,7 @@ public final class CollisionUtils {
return handlePhysics(entity, entityVelocity, null); return handlePhysics(entity, entityVelocity, null);
} }
public static boolean canPlaceBlockAt(Instance instance, Point blockPos, Block b) { public static Entity canPlaceBlockAt(Instance instance, Point blockPos, Block b) {
return BlockCollision.canPlaceBlockAt(instance, blockPos, b); return BlockCollision.canPlaceBlockAt(instance, blockPos, b);
} }

View File

@ -3,6 +3,7 @@ package net.minestom.server.listener;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.collision.CollisionUtils; import net.minestom.server.collision.CollisionUtils;
import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.GameMode; import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.EventDispatcher; import net.minestom.server.event.EventDispatcher;
@ -105,9 +106,18 @@ public class BlockPlacementListener {
} }
final Block placedBlock = useMaterial.block(); final Block placedBlock = useMaterial.block();
if (!CollisionUtils.canPlaceBlockAt(instance, placementPosition, placedBlock)) { Entity collisionEntity = CollisionUtils.canPlaceBlockAt(instance, placementPosition, placedBlock);
if (collisionEntity != null) {
// If a player is trying to place a block on themselves, the client will send a block change but will not set the block on the client
// For this reason, the block doesn't need to be updated for the client
// Client also doesn't predict placement of blocks on entities, but we need to refresh for cases where bounding boxes on the server don't match the client
if (collisionEntity != player)
refresh(player, chunk);
return; return;
} }
// BlockPlaceEvent check // BlockPlaceEvent check
PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent(player, placedBlock, blockFace, placementPosition, packet.hand()); PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent(player, placedBlock, blockFace, placementPosition, packet.hand());
playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE); playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE);

View File

@ -9,8 +9,7 @@ import net.minestom.server.entity.EntityType;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertTrue;
@EnvTest @EnvTest
public class PlacementCollisionIntegrationTest { public class PlacementCollisionIntegrationTest {
@ -18,27 +17,27 @@ public class PlacementCollisionIntegrationTest {
@Test @Test
public void empty(Env env) { public void empty(Env env) {
var instance = env.createFlatInstance(); var instance = env.createFlatInstance();
assertTrue(BlockCollision.canPlaceBlockAt(instance, new Vec(0, 40, 0), Block.STONE)); assertNull(BlockCollision.canPlaceBlockAt(instance, new Vec(0, 40, 0), Block.STONE));
} }
@Test @Test
public void entityBlock(Env env) { public void entityBlock(Env env) {
var instance = env.createFlatInstance(); var instance = env.createFlatInstance();
new Entity(EntityType.ZOMBIE).setInstance(instance, new Pos(0, 40, 0)).join(); new Entity(EntityType.ZOMBIE).setInstance(instance, new Pos(0, 40, 0)).join();
assertFalse(BlockCollision.canPlaceBlockAt(instance, new Vec(0, 40, 0), Block.STONE)); assertNotNull(BlockCollision.canPlaceBlockAt(instance, new Vec(0, 40, 0), Block.STONE));
} }
@Test @Test
public void slab(Env env) { public void slab(Env env) {
var instance = env.createFlatInstance(); var instance = env.createFlatInstance();
new Entity(EntityType.ZOMBIE).setInstance(instance, new Pos(0, 40.75, 0)).join(); new Entity(EntityType.ZOMBIE).setInstance(instance, new Pos(0, 40.75, 0)).join();
assertTrue(BlockCollision.canPlaceBlockAt(instance, new Vec(0, 40, 0), Block.STONE_SLAB)); assertNull(BlockCollision.canPlaceBlockAt(instance, new Vec(0, 40, 0), Block.STONE_SLAB));
} }
@Test @Test
public void belowPlayer(Env env) { public void belowPlayer(Env env) {
var instance = env.createFlatInstance(); var instance = env.createFlatInstance();
env.createPlayer(instance, new Pos(5.7, -8, 6.389)); env.createPlayer(instance, new Pos(5.7, -8, 6.389));
assertTrue(BlockCollision.canPlaceBlockAt(instance, new Vec(5, -9, 6), Block.STONE)); assertNull(BlockCollision.canPlaceBlockAt(instance, new Vec(5, -9, 6), Block.STONE));
} }
} }