mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-16 15:45:21 +01:00
feat: configurable entity synchronization interval (#2047)
* feat: entity synchronization overhaul * chore: add getter for sync interval --------- Co-authored-by: mworzala <mattheworzala@gmail.com>
This commit is contained in:
parent
4d2e78e7cf
commit
4f1017d398
@ -15,6 +15,7 @@ public final class ServerFlag {
|
||||
public static final int SERVER_TICKS_PER_SECOND = Integer.getInteger("minestom.tps", 20);
|
||||
public static final int CHUNK_VIEW_DISTANCE = Integer.getInteger("minestom.chunk-view-distance", 8);
|
||||
public static final int ENTITY_VIEW_DISTANCE = Integer.getInteger("minestom.entity-view-distance", 5);
|
||||
public static final int ENTITY_SYNCHRONIZATION_TICKS = Integer.getInteger("minestom.entity-synchronization-ticks", 20);
|
||||
public static final int WORKER_COUNT = Integer.getInteger("minestom.workers", Runtime.getRuntime().availableProcessors());
|
||||
public static final int MAX_PACKET_SIZE = Integer.getInteger("minestom.max-packet-size", 2_097_151); // 3 bytes var-int
|
||||
public static final int SOCKET_SEND_BUFFER_SIZE = Integer.getInteger("minestom.send-buffer-size", 262_143);
|
||||
|
@ -5,10 +5,7 @@ import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.event.HoverEvent.ShowEntity;
|
||||
import net.kyori.adventure.text.event.HoverEventSource;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.ServerProcess;
|
||||
import net.minestom.server.Tickable;
|
||||
import net.minestom.server.Viewable;
|
||||
import net.minestom.server.*;
|
||||
import net.minestom.server.collision.*;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
@ -31,8 +28,6 @@ import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockFace;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.network.packet.server.CachedPacket;
|
||||
import net.minestom.server.network.packet.server.LazyPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.play.*;
|
||||
import net.minestom.server.permission.Permission;
|
||||
import net.minestom.server.permission.PermissionHandler;
|
||||
@ -57,7 +52,6 @@ import net.minestom.server.utils.chunk.ChunkCache;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.utils.entity.EntityUtils;
|
||||
import net.minestom.server.utils.player.PlayerUtils;
|
||||
import net.minestom.server.utils.time.Cooldown;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@ -169,10 +163,9 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
||||
|
||||
protected EntityType entityType; // UNSAFE to change, modify at your own risk
|
||||
|
||||
// Network synchronization, send the absolute position of the entity each X milliseconds
|
||||
private static final Duration SYNCHRONIZATION_COOLDOWN = Duration.of(1, TimeUnit.MINUTE);
|
||||
private Duration customSynchronizationCooldown;
|
||||
private long lastAbsoluteSynchronizationTime;
|
||||
// Network synchronization, send the absolute position of the entity every n ticks
|
||||
private long synchronizationTicks = ServerFlag.ENTITY_SYNCHRONIZATION_TICKS;
|
||||
private long nextSynchronizationTick = synchronizationTicks;
|
||||
|
||||
protected Metadata metadata = new Metadata(this);
|
||||
protected EntityMeta entityMeta;
|
||||
@ -582,7 +575,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
||||
effectTick(time);
|
||||
}
|
||||
// Scheduled synchronization
|
||||
if (!Cooldown.hasCooldown(time, lastAbsoluteSynchronizationTime, getSynchronizationCooldown())) {
|
||||
if (ticks >= nextSynchronizationTick) {
|
||||
synchronizePosition(false);
|
||||
}
|
||||
}
|
||||
@ -1371,6 +1364,11 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
||||
this.position = position;
|
||||
this.previousPosition = previousPosition;
|
||||
if (!position.samePoint(previousPosition)) refreshCoordinate(position);
|
||||
if (nextSynchronizationTick <= ticks + 1) {
|
||||
// The entity will be synchronized at the end of its tick
|
||||
// not returning here will duplicate position packets
|
||||
return;
|
||||
}
|
||||
// Update viewers
|
||||
final boolean viewChange = !position.sameView(lastSyncedPosition);
|
||||
final double distanceX = Math.abs(position.x() - lastSyncedPosition.x());
|
||||
@ -1381,7 +1379,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
||||
final Chunk chunk = getChunk();
|
||||
if (distanceX > 8 || distanceY > 8 || distanceZ > 8) {
|
||||
PacketUtils.prepareViewablePacket(chunk, new EntityTeleportPacket(getEntityId(), position, isOnGround()), this);
|
||||
this.lastAbsoluteSynchronizationTime = System.currentTimeMillis();
|
||||
nextSynchronizationTick = synchronizationTicks + 1;
|
||||
} else if (positionChange && viewChange) {
|
||||
PacketUtils.prepareViewablePacket(chunk, EntityPositionAndRotationPacket.getPacket(getEntityId(), position,
|
||||
lastSyncedPosition, isOnGround()), this);
|
||||
@ -1681,9 +1679,11 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
||||
@ApiStatus.Internal
|
||||
protected void synchronizePosition(boolean includeSelf) {
|
||||
final Pos posCache = this.position;
|
||||
final ServerPacket packet = new EntityTeleportPacket(getEntityId(), posCache, isOnGround());
|
||||
PacketUtils.prepareViewablePacket(currentChunk, packet, this);
|
||||
this.lastAbsoluteSynchronizationTime = System.currentTimeMillis();
|
||||
PacketUtils.prepareViewablePacket(currentChunk, new EntityTeleportPacket(getEntityId(), posCache, isOnGround()), this);
|
||||
if (posCache.yaw() != lastSyncedPosition.yaw()) {
|
||||
PacketUtils.prepareViewablePacket(currentChunk, new EntityHeadLookPacket(getEntityId(), position.yaw()), this);
|
||||
}
|
||||
nextSynchronizationTick = ticks + synchronizationTicks;
|
||||
this.lastSyncedPosition = posCache;
|
||||
}
|
||||
|
||||
@ -1693,28 +1693,34 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks for a synchronization (position) to happen during next entity tick.
|
||||
* Asks for a position synchronization to happen during next entity tick.
|
||||
*/
|
||||
public void askSynchronization() {
|
||||
this.lastAbsoluteSynchronizationTime = 0;
|
||||
public void synchronizeNextTick() {
|
||||
this.nextSynchronizationTick = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom cooldown for position synchronization.
|
||||
* Returns the current synchronization interval. The default value is {@link ServerFlag#ENTITY_SYNCHRONIZATION_TICKS}
|
||||
* but can be overridden per entity with {@link #setSynchronizationTicks(long)}.
|
||||
*
|
||||
* @param cooldown custom cooldown for position synchronization.
|
||||
* @return The current synchronization ticks
|
||||
*/
|
||||
public void setCustomSynchronizationCooldown(@Nullable Duration cooldown) {
|
||||
this.customSynchronizationCooldown = cooldown;
|
||||
public long getSynchronizationTicks() {
|
||||
return this.synchronizationTicks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tick period until this entity's position is synchronized.
|
||||
*
|
||||
* @param ticks the new synchronization tick period
|
||||
*/
|
||||
public void setSynchronizationTicks(long ticks) {
|
||||
this.synchronizationTicks = ticks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HoverEvent<ShowEntity> asHoverEvent(@NotNull UnaryOperator<ShowEntity> op) {
|
||||
return HoverEvent.showEntity(ShowEntity.of(this.entityType, this.uuid));
|
||||
}
|
||||
|
||||
private Duration getSynchronizationCooldown() {
|
||||
return Objects.requireNonNullElse(this.customSynchronizationCooldown, SYNCHRONIZATION_COOLDOWN);
|
||||
return HoverEvent.showEntity(ShowEntity.showEntity(this.entityType, this.uuid));
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
|
Loading…
Reference in New Issue
Block a user