From a5db5104b790da6779fcc64217f5d67ab823835f Mon Sep 17 00:00:00 2001 From: dima_dencep Date: Sat, 1 Nov 2025 19:40:11 +0700 Subject: [PATCH] Fixes for Custom entity properties API (#5949) * Fixes * Further fixes * let's not talk about this one --------- Co-authored-by: onebeastchris --- .../geyser/entity/EntityDefinition.java | 2 +- .../geyser/entity/EntityDefinitions.java | 2 +- .../properties/GeyserEntityProperties.java | 18 +++++++++++------- .../entity/properties/type/EnumProperty.java | 3 ++- .../entity/properties/type/FloatProperty.java | 5 +++-- .../entity/properties/type/IntProperty.java | 5 +++-- .../geysermc/geyser/entity/type/Entity.java | 2 +- 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java index 1cc529a07..f720eefd3 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinition.java @@ -161,7 +161,7 @@ public record EntityDefinition(EntityFactory factory, Entit if (identifier == null && type != null) { identifier = "minecraft:" + type.name().toLowerCase(Locale.ROOT); } - GeyserEntityProperties registeredProperties = propertiesBuilder == null ? null : propertiesBuilder.build(); + GeyserEntityProperties registeredProperties = propertiesBuilder == null ? new GeyserEntityProperties() : propertiesBuilder.build(); EntityDefinition definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, registeredProperties, translators); if (register && definition.entityType() != null) { Registries.ENTITY_DEFINITIONS.get().putIfAbsent(definition.entityType(), definition); diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 8b9a54c0c..a0eec8983 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -1339,7 +1339,7 @@ public final class EntityDefinitions { }); for (var definition : Registries.ENTITY_DEFINITIONS.get().values()) { - if (definition.registeredProperties() != null) { + if (!definition.registeredProperties().isEmpty()) { Registries.BEDROCK_ENTITY_PROPERTIES.get().add(definition.registeredProperties().toNbtMap(definition.identifier())); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java b/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java index fa9439998..e738ce57b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/GeyserEntityProperties.java @@ -50,13 +50,8 @@ public class GeyserEntityProperties { private final static Pattern ENTITY_PROPERTY_PATTERN = Pattern.compile("^[a-z0-9_.:-]*:[a-z0-9_.:-]*$"); - private final ObjectArrayList> properties; - private final Object2IntMap propertyIndices; - - private GeyserEntityProperties() { - this.properties = new ObjectArrayList<>(); - this.propertyIndices = new Object2IntOpenHashMap<>(); - } + private ObjectArrayList> properties; + private Object2IntMap propertyIndices; public NbtMap toNbtMap(String entityType) { NbtMapBuilder mapBuilder = NbtMap.builder(); @@ -75,6 +70,11 @@ public class GeyserEntityProperties { throw new IllegalStateException("Cannot add properties outside the GeyserDefineEntityProperties event!"); } + if (properties == null || propertyIndices == null) { + this.properties = new ObjectArrayList<>(0); + this.propertyIndices = new Object2IntOpenHashMap<>(0); + } + if (this.properties.size() > 32) { throw new IllegalArgumentException("Cannot register more than 32 properties for entity type " + entityType); } @@ -97,6 +97,10 @@ public class GeyserEntityProperties { return properties; } + public boolean isEmpty() { + return properties == null || properties.isEmpty(); + } + public int getPropertyIndex(String name) { return propertyIndices.getOrDefault(name, -1); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java index 42fbb6a81..234c3097d 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/EnumProperty.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity.properties.type; +import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.api.entity.property.type.GeyserEnumEntityProperty; import org.geysermc.geyser.api.util.Identifier; @@ -35,7 +36,7 @@ import java.util.Locale; public record EnumProperty>( Identifier identifier, Class enumClass, - E defaultValue + @NonNull E defaultValue ) implements AbstractEnumProperty, GeyserEnumEntityProperty { public EnumProperty { diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java index 16997dc8a..8afc23676 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/FloatProperty.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity.properties.type; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.data.entity.FloatEntityProperty; import org.geysermc.geyser.api.entity.property.type.GeyserFloatEntityProperty; @@ -34,7 +35,7 @@ public record FloatProperty( Identifier identifier, float max, float min, - Float defaultValue + @Nullable Float defaultValue ) implements PropertyType, GeyserFloatEntityProperty { public FloatProperty { @@ -42,7 +43,7 @@ public record FloatProperty( throw new IllegalArgumentException("Cannot create float entity property (%s) with a minimum value (%s) greater than maximum (%s)!" .formatted(identifier, min, max)); } - if (defaultValue < min || defaultValue > max) { + if (defaultValue != null && (defaultValue < min || defaultValue > max)) { throw new IllegalArgumentException("Cannot create float entity property (%s) with a default value (%s) outside of the range (%s - %s)!" .formatted(identifier, defaultValue, min, max)); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java b/core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java index 966277696..2e5a0c518 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java +++ b/core/src/main/java/org/geysermc/geyser/entity/properties/type/IntProperty.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity.properties.type; +import org.checkerframework.checker.nullness.qual.Nullable; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.data.entity.IntEntityProperty; import org.geysermc.geyser.GeyserImpl; @@ -35,7 +36,7 @@ public record IntProperty( Identifier identifier, int max, int min, - Integer defaultValue + @Nullable Integer defaultValue ) implements PropertyType, GeyserIntEntityProperty { public IntProperty { @@ -43,7 +44,7 @@ public record IntProperty( throw new IllegalArgumentException("Cannot create int entity property (%s) with a minimum value (%s) greater than maximum (%s)!" .formatted(identifier, min, max)); } - if (defaultValue < min || defaultValue > max) { + if (defaultValue != null && (defaultValue < min || defaultValue > max)) { throw new IllegalArgumentException("Cannot create int entity property (%s) with a default value (%s) outside of the range (%s - %s)!" .formatted(identifier, defaultValue, min, max)); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index 8f07aa296..b64446bea 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -167,7 +167,7 @@ public class Entity implements GeyserEntity { this.valid = false; - this.propertyManager = definition.registeredProperties() == null ? null : new GeyserEntityPropertyManager(definition.registeredProperties()); + this.propertyManager = definition.registeredProperties().isEmpty() ? null : new GeyserEntityPropertyManager(definition.registeredProperties()); setPosition(position); setAirSupply(getMaxAir());