mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-27 18:59:17 +00:00
Implement dirty entities to send updates once a tick
This commit is contained in:
@@ -26,24 +26,19 @@
|
||||
package org.geysermc.geyser.entity;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataMap;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataType;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A wrapper for temporarily storing entity metadata that will be sent to Bedrock.
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public final class GeyserDirtyMetadata {
|
||||
private final Entity entity;
|
||||
private final Map<EntityDataType<?>, Object> metadata = new Object2ObjectLinkedOpenHashMap<>();
|
||||
|
||||
public <T> void put(EntityDataType<T> entityData, T value) {
|
||||
metadata.put(entityData, value);
|
||||
entity.getMetadata().put(entityData, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -145,7 +145,7 @@ public class Entity implements GeyserEntity {
|
||||
/**
|
||||
* A container to store temporary metadata before it's sent to Bedrock.
|
||||
*/
|
||||
protected final GeyserDirtyMetadata dirtyMetadata = new GeyserDirtyMetadata(this);
|
||||
protected final GeyserDirtyMetadata dirtyMetadata = new GeyserDirtyMetadata();
|
||||
/**
|
||||
* A container storing all current metadata for an entity.
|
||||
*/
|
||||
@@ -413,7 +413,7 @@ public class Entity implements GeyserEntity {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dirtyMetadata.hasEntries() || flagsDirty) {
|
||||
if (dirtyMetadata.hasEntries() || flagsDirty || (propertyManager != null && propertyManager.hasProperties())) {
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(geyserId);
|
||||
if (flagsDirty) {
|
||||
@@ -837,20 +837,20 @@ public class Entity implements GeyserEntity {
|
||||
});
|
||||
|
||||
if (propertyManager.hasProperties()) {
|
||||
SetEntityDataPacket packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(geyserId());
|
||||
propertyManager.applyFloatProperties(packet.getProperties().getFloatProperties());
|
||||
propertyManager.applyIntProperties(packet.getProperties().getIntProperties());
|
||||
if (immediate) {
|
||||
SetEntityDataPacket packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(geyserId());
|
||||
propertyManager.applyFloatProperties(packet.getProperties().getFloatProperties());
|
||||
propertyManager.applyIntProperties(packet.getProperties().getIntProperties());
|
||||
session.sendUpstreamPacketImmediately(packet);
|
||||
} else {
|
||||
session.sendUpstreamPacket(packet);
|
||||
session.getEntityCache().markDirty(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void offset(float offset) {
|
||||
// TODO queue!!
|
||||
// TODO queue?
|
||||
if (isValid()) {
|
||||
this.moveRelative(0, offset, 0, 0, 0, isOnGround());
|
||||
}
|
||||
@@ -875,6 +875,7 @@ public class Entity implements GeyserEntity {
|
||||
public <T> void update(@NonNull GeyserEntityDataType<T> dataType, @Nullable T value) {
|
||||
if (dataType instanceof GeyserEntityDataImpl<T> geyserEntityDataImpl) {
|
||||
geyserEntityDataImpl.update(this, value);
|
||||
session.getEntityCache().markDirty(this);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid data type: " + dataType.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@@ -125,8 +125,8 @@ import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.geyser.command.CommandRegistry;
|
||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||
import org.geysermc.geyser.configuration.GeyserConfig;
|
||||
import org.geysermc.geyser.entity.VanillaEntities;
|
||||
import org.geysermc.geyser.entity.GeyserEntityData;
|
||||
import org.geysermc.geyser.entity.VanillaEntities;
|
||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||
import org.geysermc.geyser.entity.type.BoatEntity;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
@@ -235,6 +235,7 @@ import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -1262,6 +1263,11 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
clientVehicle.getVehicleComponent().tickVehicle();
|
||||
}
|
||||
|
||||
for (Iterator<Entity> it = entityCache.getDirtyEntities().iterator(); it.hasNext(); ) {
|
||||
it.next().updateBedrockMetadata();
|
||||
it.remove();
|
||||
}
|
||||
|
||||
for (Tickable entity : entityCache.getTickableEntities()) {
|
||||
entity.drawTick();
|
||||
if (gameShouldUpdate) {
|
||||
|
||||
@@ -33,6 +33,7 @@ import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.entity.type.Tickable;
|
||||
@@ -42,6 +43,7 @@ import org.geysermc.geyser.session.GeyserSession;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Consumer;
|
||||
@@ -63,6 +65,8 @@ public class EntityCache {
|
||||
private final Object2LongMap<UUID> entityUuidTranslations = new Object2LongOpenHashMap<>();
|
||||
private final Map<UUID, PlayerEntity> playerEntities = new Object2ObjectOpenHashMap<>();
|
||||
private final Map<UUID, BossBar> bossBars = new Object2ObjectOpenHashMap<>();
|
||||
@Getter
|
||||
private final Set<Entity> dirtyEntities = new ObjectOpenHashSet<>();
|
||||
|
||||
@Getter
|
||||
private final AtomicLong nextEntityId = new AtomicLong(2L);
|
||||
@@ -123,6 +127,11 @@ public class EntityCache {
|
||||
if (entity instanceof Tickable) {
|
||||
tickableEntities.remove(entity);
|
||||
}
|
||||
dirtyEntities.remove(entity);
|
||||
}
|
||||
|
||||
public void markDirty(Entity entity) {
|
||||
dirtyEntities.add(entity);
|
||||
}
|
||||
|
||||
public void removeAllEntities() {
|
||||
|
||||
Reference in New Issue
Block a user