This commit is contained in:
themode 2020-10-12 06:41:47 +02:00
parent 9184b3054f
commit 81c6f97336
5 changed files with 89 additions and 50 deletions

View File

@ -955,7 +955,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
* - update the viewable chunks (load and unload) * - update the viewable chunks (load and unload)
* - add/remove players from the viewers list if {@link #isAutoViewable()} is enabled * - add/remove players from the viewers list if {@link #isAutoViewable()} is enabled
* <p> * <p>
* WARNING: unsafe, should only be used internally in Minestom * WARNING: unsafe, should only be used internally in Minestom. Use {@link #teleport(Position)} instead.
* *
* @param x new position X * @param x new position X
* @param y new position Y * @param y new position Y
@ -1000,6 +1000,14 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
refreshPosition(position.getX(), position.getY(), position.getZ()); refreshPosition(position.getX(), position.getY(), position.getZ());
} }
/**
* Manage viewable entities automatically if {@link #isAutoViewable()} is enabled.
* <p>
* Called by {@link #refreshPosition(float, float, float)} when the new position is in a different {@link Chunk}.
*
* @param lastChunk the previous {@link Chunk} of this entity
* @param newChunk the new {@link Chunk} of this entity
*/
private void updateView(Chunk lastChunk, Chunk newChunk) { private void updateView(Chunk lastChunk, Chunk newChunk) {
final boolean isPlayer = this instanceof Player; final boolean isPlayer = this instanceof Player;
@ -1010,6 +1018,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
final long[] lastVisibleChunksEntity = ChunkUtils.getChunksInRange(new Position(16 * lastChunk.getChunkX(), 0, 16 * lastChunk.getChunkZ()), MinecraftServer.ENTITY_VIEW_DISTANCE); final long[] lastVisibleChunksEntity = ChunkUtils.getChunksInRange(new Position(16 * lastChunk.getChunkX(), 0, 16 * lastChunk.getChunkZ()), MinecraftServer.ENTITY_VIEW_DISTANCE);
final long[] updatedVisibleChunksEntity = ChunkUtils.getChunksInRange(new Position(16 * newChunk.getChunkX(), 0, 16 * newChunk.getChunkZ()), MinecraftServer.ENTITY_VIEW_DISTANCE); final long[] updatedVisibleChunksEntity = ChunkUtils.getChunksInRange(new Position(16 * newChunk.getChunkX(), 0, 16 * newChunk.getChunkZ()), MinecraftServer.ENTITY_VIEW_DISTANCE);
// Remove from previous chunks
final int[] oldChunksEntity = ArrayUtils.getDifferencesBetweenArray(lastVisibleChunksEntity, updatedVisibleChunksEntity); final int[] oldChunksEntity = ArrayUtils.getDifferencesBetweenArray(lastVisibleChunksEntity, updatedVisibleChunksEntity);
for (int index : oldChunksEntity) { for (int index : oldChunksEntity) {
final long chunkIndex = lastVisibleChunksEntity[index]; final long chunkIndex = lastVisibleChunksEntity[index];
@ -1032,6 +1041,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
}); });
} }
// Add to new chunks
final int[] newChunksEntity = ArrayUtils.getDifferencesBetweenArray(updatedVisibleChunksEntity, lastVisibleChunksEntity); final int[] newChunksEntity = ArrayUtils.getDifferencesBetweenArray(updatedVisibleChunksEntity, lastVisibleChunksEntity);
for (int index : newChunksEntity) { for (int index : newChunksEntity) {
final long chunkIndex = updatedVisibleChunksEntity[index]; final long chunkIndex = updatedVisibleChunksEntity[index];
@ -1072,14 +1082,28 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
this.cachePitch = pitch; this.cachePitch = pitch;
} }
public void refreshSneaking(boolean sneaking) { /**
* Make the entity sneak.
* <p>
* WARNING: this will not work for the client itself.
*
* @param sneaking true to make the entity sneak
*/
public void setSneaking(boolean sneaking) {
this.crouched = sneaking; this.crouched = sneaking;
this.pose = sneaking ? Pose.SNEAKING : Pose.STANDING; this.pose = sneaking ? Pose.SNEAKING : Pose.STANDING;
sendMetadataIndex(0); sendMetadataIndex(0);
sendMetadataIndex(6); sendMetadataIndex(6);
} }
public void refreshSprinting(boolean sprinting) { /**
* Make the entity sprint.
* <p>
* WARNING: this will not work on the client itself.
*
* @param sprinting true to make the entity sprint
*/
public void setSprinting(boolean sprinting) {
this.sprinting = sprinting; this.sprinting = sprinting;
sendMetadataIndex(0); sendMetadataIndex(0);
} }
@ -1140,8 +1164,9 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
} }
/** /**
* Remove the entity from the server immediately * Remove the entity from the server immediately.
* WARNING: this do not trigger the {@link EntityDeathEvent} event * <p>
* WARNING: this do not trigger the {@link EntityDeathEvent} event.
*/ */
public void remove() { public void remove() {
this.removed = true; this.removed = true;
@ -1177,9 +1202,9 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
} }
/** /**
* Get if the entity removal is scheduled * Get if the entity removal has been scheduled with {@link #scheduleRemove(long, TimeUnit)}.
* *
* @return true if {@link #scheduleRemove(long, TimeUnit)} has been called, false otherwise * @return true if the entity removal has been scheduled
*/ */
public boolean isRemoveScheduled() { public boolean isRemoveScheduled() {
return scheduledRemoveTime != 0; return scheduledRemoveTime != 0;
@ -1196,7 +1221,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
} }
/** /**
* Used to sync entities together, and sent when adding viewers * Get an {@link EntityMetaDataPacket} sent when adding viewers. Used for synchronization.
* *
* @return The {@link EntityMetaDataPacket} related to this entity * @return The {@link EntityMetaDataPacket} related to this entity
*/ */

View File

@ -450,10 +450,20 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
sendPacketToViewers(getMetadataPacket()); sendPacketToViewers(getMetadataPacket());
} }
/**
* Used to change the {@code isDead} internal field.
*
* @param isDead the new field value
*/
protected void refreshIsDead(boolean isDead) { protected void refreshIsDead(boolean isDead) {
this.isDead = isDead; this.isDead = isDead;
} }
/**
* Get an {@link EntityPropertiesPacket} for this entity with all of its attributes values.
*
* @return an {@link EntityPropertiesPacket} linked to this entity
*/
protected EntityPropertiesPacket getPropertiesPacket() { protected EntityPropertiesPacket getPropertiesPacket() {
EntityPropertiesPacket propertiesPacket = new EntityPropertiesPacket(); EntityPropertiesPacket propertiesPacket = new EntityPropertiesPacket();
propertiesPacket.entityId = getEntityId(); propertiesPacket.entityId = getEntityId();
@ -477,7 +487,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
} }
/** /**
* Set all the attributes to {@link Attribute#getDefaultValue()} * Sets all the attributes to {@link Attribute#getDefaultValue()}
*/ */
private void setupAttributes() { private void setupAttributes() {
for (Attribute attribute : Attribute.values()) { for (Attribute attribute : Attribute.values()) {

View File

@ -82,7 +82,7 @@ public class Player extends LivingEntity implements CommandSender {
private DimensionType dimensionType; private DimensionType dimensionType;
private GameMode gameMode; private GameMode gameMode;
protected final Set<Chunk> viewableChunks = new CopyOnWriteArraySet<>(); protected final Set<Chunk> viewableChunks = new CopyOnWriteArraySet<>();
private int teleportId = 0; private final AtomicInteger teleportId = new AtomicInteger();
protected boolean onGround; protected boolean onGround;
private final ConcurrentLinkedQueue<ClientPlayPacket> packets = new ConcurrentLinkedQueue<>(); private final ConcurrentLinkedQueue<ClientPlayPacket> packets = new ConcurrentLinkedQueue<>();
@ -1607,9 +1607,9 @@ public class Player extends LivingEntity implements CommandSender {
*/ */
protected void updatePlayerPosition() { protected void updatePlayerPosition() {
PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket(); PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket();
positionAndLookPacket.position = position.clone(); positionAndLookPacket.position = position.clone(); // clone needed to prevent synchronization issue
positionAndLookPacket.flags = 0x00; positionAndLookPacket.flags = 0x00;
positionAndLookPacket.teleportId = teleportId++; positionAndLookPacket.teleportId = teleportId.incrementAndGet();
playerConnection.sendPacket(positionAndLookPacket); playerConnection.sendPacket(positionAndLookPacket);
} }

View File

@ -80,7 +80,10 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
// list of scheduled tasks to be executed during the next instance tick // list of scheduled tasks to be executed during the next instance tick
protected final ConcurrentLinkedQueue<Consumer<Instance>> nextTick = new ConcurrentLinkedQueue<>(); protected final ConcurrentLinkedQueue<Consumer<Instance>> nextTick = new ConcurrentLinkedQueue<>();
// instance custom data
private Data data; private Data data;
// the explosion supplier
private ExplosionSupplier explosionSupplier; private ExplosionSupplier explosionSupplier;
// Pathfinder // Pathfinder
@ -112,7 +115,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
/** /**
* Used to change the id of the block in a specific {@link BlockPosition}. * Used to change the id of the block in a specific {@link BlockPosition}.
* <p> * <p>
* In case of a CustomBlock it does not remove it but only refresh its visual * In case of a {@link CustomBlock} it does not remove it but only refresh its visual.
* *
* @param blockPosition the block position * @param blockPosition the block position
* @param blockStateId the new block state * @param blockStateId the new block state
@ -123,14 +126,14 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* Does call {@link net.minestom.server.event.player.PlayerBlockBreakEvent} * Does call {@link net.minestom.server.event.player.PlayerBlockBreakEvent}
* and send particle packets * and send particle packets
* *
* @param player the player who break the block * @param player the {@link Player} who break the block
* @param blockPosition the position of the broken block * @param blockPosition the {@link BlockPosition} of the broken block
* @return true if the block has been broken, false if it has been cancelled * @return true if the block has been broken, false if it has been cancelled
*/ */
public abstract boolean breakBlock(Player player, BlockPosition blockPosition); public abstract boolean breakBlock(Player player, BlockPosition blockPosition);
/** /**
* Force the generation of a {@link Chunk}, even if no file and {@link ChunkGenerator} are defined * Force the generation of a {@link Chunk}, even if no file and {@link ChunkGenerator} are defined.
* *
* @param chunkX the chunk X * @param chunkX the chunk X
* @param chunkZ the chunk Z * @param chunkZ the chunk Z
@ -141,7 +144,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
/** /**
* Load the chunk if the chunk is already loaded or if * Load the chunk if the chunk is already loaded or if
* {@link #hasEnabledAutoChunkLoad()} returns true * {@link #hasEnabledAutoChunkLoad()} returns true.
* *
* @param chunkX the chunk X * @param chunkX the chunk X
* @param chunkZ the chunk Z * @param chunkZ the chunk Z
@ -151,9 +154,9 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
public abstract void loadOptionalChunk(int chunkX, int chunkZ, ChunkCallback callback); public abstract void loadOptionalChunk(int chunkX, int chunkZ, ChunkCallback callback);
/** /**
* Schedule the removal of a chunk, this method does not promise when it will be done * Schedule the removal of a {@link Chunk}, this method does not promise when it will be done.
* <p> * <p>
* WARNING: during unloading, all entities other than {@link Player} will be removed * WARNING: during unloading, all entities other than {@link Player} will be removed.
* <p> * <p>
* For {@link InstanceContainer} it is done during {@link InstanceContainer#tick(long)} * For {@link InstanceContainer} it is done during {@link InstanceContainer#tick(long)}
* *
@ -173,7 +176,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
public abstract Chunk getChunk(int chunkX, int chunkZ); public abstract Chunk getChunk(int chunkX, int chunkZ);
/** /**
* Save a {@link Chunk} to permanent storage * Save a {@link Chunk} to permanent storage.
* *
* @param chunk the {@link Chunk} to save * @param chunk the {@link Chunk} to save
* @param callback called when the {@link Chunk} is done saving * @param callback called when the {@link Chunk} is done saving
@ -505,7 +508,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Refresh the visual block id at the position * Refresh the visual block id at the {@link BlockPosition}
* <p> * <p>
* WARNING: the custom block id at the position will not change * WARNING: the custom block id at the position will not change
* *
@ -517,9 +520,9 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Load the chunk at the given position without any callback * Load the {@link Chunk} at the given position without any callback.
* <p> * <p>
* WARNING: this is a non-blocking task * WARNING: this is a non-blocking task.
* *
* @param chunkX the chunk X * @param chunkX the chunk X
* @param chunkZ the chunk Z * @param chunkZ the chunk Z
@ -529,7 +532,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Load the chunk at the given position with a callback * Load the chunk at the given {@link Position} with a callback
* *
* @param position the chunk position * @param position the chunk position
* @param callback the callback to run when the chunk is loaded * @param callback the callback to run when the chunk is loaded
@ -541,7 +544,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Load chunk (if {@link #hasEnabledAutoChunkLoad()} returns true) at the given position with a callback * Load a {@link Chunk} (if {@link #hasEnabledAutoChunkLoad()} returns true) at the given {@link Position} with a callback
* *
* @param position the chunk position * @param position the chunk position
* @param callback the callback executed when the chunk is loaded (or with a null chunk if not) * @param callback the callback executed when the chunk is loaded (or with a null chunk if not)
@ -591,7 +594,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Give the block state id at the given position * Give the block state id at the given {@link BlockPosition}
* *
* @param blockPosition the block position * @param blockPosition the block position
* @return the block state id at the position * @return the block state id at the position
@ -615,7 +618,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Get the custom block object at the given position, or null if not any * Get the custom block object at the given {@link BlockPosition}, or null if not any.
* *
* @param blockPosition the block position * @param blockPosition the block position
* @return the custom block object at the position, null if not any * @return the custom block object at the position, null if not any
@ -662,7 +665,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Get the block data at the given {@link BlockPosition}, or null if not any * Get the block {@link Data} at the given {@link BlockPosition}, or null if not any
* *
* @param blockPosition the block position * @param blockPosition the block position
* @return the block data at the position, null if not any * @return the block data at the position, null if not any
@ -672,7 +675,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Set the block data at the given {@link BlockPosition} * Set the block {@link Data} at the given {@link BlockPosition}
* *
* @param x the X position * @param x the X position
* @param y the Y position * @param y the Y position
@ -688,7 +691,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Set the block data at the given {@link BlockPosition} * Set the block {@link Data} at the given {@link BlockPosition}
* *
* @param blockPosition the block position * @param blockPosition the block position
* @param data the data to be set, can be null * @param data the data to be set, can be null
@ -698,7 +701,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Get the chunk at the given {@link BlockPosition}, null if not loaded. * Get the {@link Chunk} at the given {@link BlockPosition}, null if not loaded.
* *
* @param x the X position * @param x the X position
* @param z the Z position * @param z the Z position
@ -711,7 +714,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Check if the chunk at the position is loaded * Check if the {@link Chunk} at the position is loaded
* *
* @param chunkX the chunk X * @param chunkX the chunk X
* @param chunkZ the chunk Z * @param chunkZ the chunk Z
@ -722,7 +725,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Get the chunk at the given {@link BlockPosition}, null if not loaded * Get the {@link Chunk} at the given {@link BlockPosition}, null if not loaded.
* *
* @param blockPosition the chunk position * @param blockPosition the chunk position
* @return the chunk at the given position, null if not loaded * @return the chunk at the given position, null if not loaded
@ -732,7 +735,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Get the chunk at the given {@link Position}, null if not loaded * Get the {@link Chunk} at the given {@link Position}, null if not loaded.
* *
* @param position the chunk position * @param position the chunk position
* @return the chunk at the given position, null if not loaded * @return the chunk at the given position, null if not loaded
@ -751,7 +754,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Save all chunks without any callback * Save all {@link Chunk} without any callback.
*/ */
public void saveChunksToStorage() { public void saveChunksToStorage() {
saveChunksToStorage(null); saveChunksToStorage(null);
@ -785,9 +788,9 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
/** /**
* Used when called {@link Entity#setInstance(Instance)}, it is used to refresh viewable chunks * Used when called {@link Entity#setInstance(Instance)}, it is used to refresh viewable chunks
* and add viewers if {@code entity} is a Player * and add viewers if {@code entity} is a {@link Player}.
* <p> * <p>
* Warning: unsafe, you probably want to use {@link Entity#setInstance(Instance)} instead * Warning: unsafe, you probably want to use {@link Entity#setInstance(Instance)} instead.
* *
* @param entity the entity to add * @param entity the entity to add
*/ */
@ -828,9 +831,9 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Used when an entity is removed from the instance, it removes all of his viewers * Used when an {@link Entity} is removed from the instance, it removes all of his viewers.
* <p> * <p>
* Warning: unsafe, you probably want to set the entity to another instance * Warning: unsafe, you probably want to set the entity to another instance.
* *
* @param entity the entity to remove * @param entity the entity to remove
*/ */
@ -851,9 +854,9 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Add the specified entity to the instance entities cache * Add the specified {@link Entity} to the instance entities cache.
* <p> * <p>
* Warning: this is done automatically when the entity move out of his chunk * Warning: this is done automatically when the entity move out of his chunk.
* *
* @param entity the entity to add * @param entity the entity to add
* @param chunk the chunk where the entity will be added * @param chunk the chunk where the entity will be added
@ -882,9 +885,9 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Remove the specified entity to the instance entities cache * Remove the specified {@link Entity} to the instance entities cache.
* <p> * <p>
* Warning: this is done automatically when the entity move out of his chunk * Warning: this is done automatically when the entity move out of his chunk.
* *
* @param entity the entity to remove * @param entity the entity to remove
* @param chunk the chunk where the entity will be removed * @param chunk the chunk where the entity will be removed
@ -920,8 +923,9 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Schedule a block update at a given position. * Schedule a block update at a given {@link BlockPosition}.
* Does nothing if no custom block is present at 'position'. * Does nothing if no {@link CustomBlock} is present at 'position'.
* <p>
* Cancelled if the block changes between this call and the actual update * Cancelled if the block changes between this call and the actual update
* *
* @param time in how long this update must be performed? * @param time in how long this update must be performed?
@ -933,7 +937,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
/** /**
* Performs a single tick in the instance, including scheduled tasks from {@link #scheduleNextTick(Consumer)}. * Performs a single tick in the instance, including scheduled tasks from {@link #scheduleNextTick(Consumer)}.
* <p> * <p>
* Warning: this does not update chunks and entities * Warning: this does not update chunks and entities.
* *
* @param time the current time * @param time the current time
*/ */

View File

@ -9,16 +9,16 @@ public class EntityActionListener {
ClientEntityActionPacket.Action action = packet.action; ClientEntityActionPacket.Action action = packet.action;
switch (action) { switch (action) {
case START_SNEAKING: case START_SNEAKING:
player.refreshSneaking(true); player.setSneaking(true);
break; break;
case STOP_SNEAKING: case STOP_SNEAKING:
player.refreshSneaking(false); player.setSneaking(false);
break; break;
case START_SPRINTING: case START_SPRINTING:
player.refreshSprinting(true); player.setSprinting(true);
break; break;
case STOP_SPRINTING: case STOP_SPRINTING:
player.refreshSprinting(false); player.setSprinting(false);
break; break;
// TODO do remaining actions // TODO do remaining actions
} }