Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import net.raphimc.viabedrock.protocol.data.enums.bedrock.ActorFlags;
import net.raphimc.viabedrock.protocol.data.enums.bedrock.generated.DataItemType;
import net.raphimc.viabedrock.protocol.data.enums.java.generated.BossEventOperationType;
import net.raphimc.viabedrock.protocol.model.EntityProperties;
import net.raphimc.viabedrock.protocol.model.Position3f;
import net.raphimc.viabedrock.protocol.rewriter.EntityMetadataRewriter;
import net.raphimc.viabedrock.protocol.types.BedrockTypes;
Expand Down Expand Up @@ -123,6 +124,10 @@ public final void updateEntityData(final EntityData[] entityData, final List<Ent
this.onEntityDataChanged();
}

public final void translateEntityProperties(final EntityProperties properties, final List<EntityData> javaEntityData) {
EntityMetadataRewriter.rewriteProperties(this.user, this, properties, javaEntityData);
}

public void playSound(final String soundEvent) {
final PacketWrapper levelSoundEvent = PacketWrapper.create(ClientboundBedrockPackets.LEVEL_SOUND_EVENT, this.user);
levelSoundEvent.write(BedrockTypes.STRING, soundEvent); // event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,12 @@ public Map<String, EntityEffect> effects() {

protected boolean translateAttribute(final EntityAttribute attribute, final PacketWrapper javaAttributes, final AtomicInteger attributeCount, final List<EntityData> javaEntityData) {
return switch (attribute.name()) {
case "minecraft:attack_damage", "minecraft:knockback_resistance", "minecraft:movement" -> {
case "minecraft:attack_damage", "minecraft:knockback_resistance", "minecraft:movement", "minecraft:scale" -> {
javaAttributes.write(Types.VAR_INT, BedrockProtocol.MAPPINGS.getJavaEntityAttributes().get(switch (attribute.name()) {
case "minecraft:attack_damage" -> Attributes.ATTACK_DAMAGE;
case "minecraft:knockback_resistance" -> Attributes.KNOCKBACK_RESISTANCE;
case "minecraft:movement" -> Attributes.MOVEMENT_SPEED;
case "minecraft:scale" -> Attributes.SCALE;
default -> throw new IllegalStateException("Unhandled entity attribute: " + attribute.name());
})); // attribute id
javaAttributes.write(Types.DOUBLE, (double) attribute.computeClampedValue()); // base value
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* This file is part of ViaBedrock - https://github.com/RaphiMC/ViaBedrock
* Copyright (C) 2023-2026 RK_01/RaphiMC and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.raphimc.viabedrock.api.model.entity.properties;

public interface EntityProperty {

record BooleanProperty(String identifier) implements EntityProperty { }

record IntProperty(String identifier, int minValue, int maxValue) implements EntityProperty { }

record FloatProperty(String identifier, float minValue, float maxValue) implements EntityProperty { }

record EnumProperty(String identifier, String[] possibleValues) implements EntityProperty { }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* This file is part of ViaBedrock - https://github.com/RaphiMC/ViaBedrock
* Copyright (C) 2023-2026 RK_01/RaphiMC and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.raphimc.viabedrock.api.model.entity.properties;

import java.util.List;

public record EntityPropertyList(List<EntityProperty> intProperties, List<EntityProperty.FloatProperty> floatProperties) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ public void init(final UserConnection user) {

user.put(new InventoryTransactionRewriter(user));
user.put(new MapTracker(user));
user.put(new EntityPropertyTracker(user));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

import com.google.common.collect.Lists;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.PaintingVariant;
import com.viaversion.viaversion.api.minecraft.Vector3d;
Expand All @@ -36,6 +39,8 @@
import net.raphimc.viabedrock.api.model.entity.CustomEntity;
import net.raphimc.viabedrock.api.model.entity.Entity;
import net.raphimc.viabedrock.api.model.entity.LivingEntity;
import net.raphimc.viabedrock.api.model.entity.properties.EntityProperty;
import net.raphimc.viabedrock.api.model.entity.properties.EntityPropertyList;
import net.raphimc.viabedrock.api.resourcepack.definition.EntityDefinitions;
import net.raphimc.viabedrock.api.util.MathUtil;
import net.raphimc.viabedrock.api.util.PacketFactory;
Expand All @@ -50,11 +55,9 @@
import net.raphimc.viabedrock.protocol.data.enums.java.generated.EquipmentSlot;
import net.raphimc.viabedrock.protocol.data.generated.java.EntityDataFields;
import net.raphimc.viabedrock.protocol.data.generated.java.RegistryKeys;
import net.raphimc.viabedrock.protocol.model.BedrockItem;
import net.raphimc.viabedrock.protocol.model.EntityAttribute;
import net.raphimc.viabedrock.protocol.model.EntityEffect;
import net.raphimc.viabedrock.protocol.model.Position3f;
import net.raphimc.viabedrock.protocol.model.*;
import net.raphimc.viabedrock.protocol.rewriter.ItemRewriter;
import net.raphimc.viabedrock.protocol.storage.EntityPropertyTracker;
import net.raphimc.viabedrock.protocol.storage.EntityTracker;
import net.raphimc.viabedrock.protocol.storage.GameSessionStorage;
import net.raphimc.viabedrock.protocol.storage.ResourcePackStorage;
Expand Down Expand Up @@ -504,7 +507,7 @@ public static void register(final BedrockProtocol protocol) {

final long entityRuntimeId = wrapper.read(BedrockTypes.UNSIGNED_VAR_LONG); // entity runtime id
final EntityData[] entityData = wrapper.read(BedrockTypes.ENTITY_DATA_ARRAY); // entity data
wrapper.read(BedrockTypes.ENTITY_PROPERTIES); // entity properties
final EntityProperties entityProperties = wrapper.read(BedrockTypes.ENTITY_PROPERTIES); // entity properties
wrapper.read(BedrockTypes.UNSIGNED_VAR_LONG); // tick

final Entity entity = entityTracker.getEntityByRid(entityRuntimeId);
Expand All @@ -515,9 +518,57 @@ public static void register(final BedrockProtocol protocol) {

final List<EntityData> javaEntityData = new ArrayList<>();
entity.updateEntityData(entityData, javaEntityData);
entity.translateEntityProperties(entityProperties, javaEntityData);
wrapper.write(Types.VAR_INT, entity.javaId()); // entity id
wrapper.write(VersionedTypes.V26_3.entityDataList, javaEntityData); // entity data
});
protocol.registerClientbound(ClientboundBedrockPackets.SYNC_ENTITY_PROPERTY, null, wrapper -> {
wrapper.cancel();
final Tag tag = wrapper.read(BedrockTypes.NETWORK_TAG);

final EntityPropertyTracker epTracker = wrapper.user().get(EntityPropertyTracker.class);

final String entityType = ((CompoundTag) tag).getString("type");
final List<EntityProperty> intEntityProperties = new ArrayList<>();
final List<EntityProperty.FloatProperty> floatEntityProperties = new ArrayList<>();

final ListTag<CompoundTag> properties = ((CompoundTag) tag).getListTag("properties", CompoundTag.class);
for (CompoundTag property : properties) {
final EntityProperty newProperty = switch (property.getInt("type")) {
case 0 -> new EntityProperty.IntProperty(
property.getString("name"),
property.getInt("min"),
property.getInt("max")
);
case 1 -> new EntityProperty.FloatProperty(
property.getString("name"),
property.getFloat("min"),
property.getFloat("max")
);
case 2 -> new EntityProperty.BooleanProperty(
property.getString("name")
);
case 3 -> new EntityProperty.EnumProperty(
property.getString("name"),
property.getListTag("enum", StringTag.class).stream().map(StringTag::getValue).toArray(String[]::new)
);
default -> {
ViaBedrock.getPlatform().getLogger().log(Level.WARNING, "Received entity property with unknown type: " + property.getInt("type"));
yield null;
}
};

if (newProperty != null) {
if (newProperty instanceof EntityProperty.FloatProperty floatProperty) {
floatEntityProperties.add(floatProperty);
} else {
intEntityProperties.add(newProperty);
}
}
}

epTracker.addEntity(entityType, new EntityPropertyList(intEntityProperties, floatEntityProperties));
});
protocol.registerClientbound(ClientboundBedrockPackets.MOB_EFFECT, ClientboundPackets26_3.UPDATE_MOB_EFFECT, wrapper -> {
final long entityRuntimeId = wrapper.read(BedrockTypes.UNSIGNED_VAR_LONG); // entity runtime id
final MobEffectPacketPayload_Event event = MobEffectPacketPayload_Event.getByValue(wrapper.read(Types.BYTE), MobEffectPacketPayload_Event.Invalid); // event id
Expand Down
Loading