Fix entity defaults across all protocols (#4312)

Minecraft <= 1.13.2 silently ignores unknown entity type ids and doesn't print any warning, while we currently still track them. Minecraft 1.14+ will spawn a pig if the entity type is invalid while we track ENTITY as wrong type. Both cases can cause various entity data issues where the server sends wrong data for non-existing entities while we still handle it.
This commit is contained in:
EnZaXD 2024-12-15 10:12:05 +01:00 committed by GitHub
parent 3b27af0964
commit 08b921729d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 82 additions and 90 deletions

View File

@ -22,7 +22,6 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import com.viaversion.viaversion.api.Via;
import java.util.HashMap;
import java.util.Map;
@ -36,10 +35,6 @@ public class EntityTypes1_10 {
} else {
type = EntityType.findById(typeId);
}
if (type == null) {
Via.getPlatform().getLogger().severe("Could not find 1.10 type id " + typeId + " objectType=" + object);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type;
}

View File

@ -22,7 +22,6 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import com.viaversion.viaversion.api.Via;
import java.util.HashMap;
import java.util.Map;
@ -36,10 +35,6 @@ public class EntityTypes1_11 {
} else {
type = EntityType.findById(typeId);
}
if (type == null) {
Via.getPlatform().getLogger().severe("Could not find 1.11 type id " + typeId + " objectType=" + object);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type;
}

View File

@ -22,7 +22,6 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import com.viaversion.viaversion.api.Via;
import java.util.HashMap;
import java.util.Map;
@ -36,10 +35,6 @@ public class EntityTypes1_12 {
} else {
type = EntityType.findById(typeId);
}
if (type == null) {
Via.getPlatform().getLogger().severe("Could not find 1.12 type id " + typeId + " objectType=" + object);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type;
}

View File

@ -22,7 +22,6 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import com.viaversion.viaversion.api.Via;
import java.util.HashMap;
import java.util.Map;
@ -36,10 +35,6 @@ public class EntityTypes1_13 {
} else {
type = EntityType.findById(typeId);
}
if (type == null) {
Via.getPlatform().getLogger().severe("Could not find 1.13 type id " + typeId + " objectType=" + object);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type;
}

View File

@ -25,8 +25,8 @@ package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import java.util.Locale;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_14 implements EntityType {
@ -246,7 +246,7 @@ public enum EntityTypes1_14 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -25,8 +25,8 @@ package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import java.util.Locale;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_15 implements EntityType {
@ -247,7 +247,7 @@ public enum EntityTypes1_15 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -25,8 +25,8 @@ package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import java.util.Locale;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_16 implements EntityType {
@ -251,7 +251,7 @@ public enum EntityTypes1_16 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -25,8 +25,8 @@ package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import java.util.Locale;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_16_2 implements EntityType {
@ -254,7 +254,7 @@ public enum EntityTypes1_16_2 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -25,8 +25,8 @@ package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import java.util.Locale;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_17 implements EntityType {
@ -260,7 +260,7 @@ public enum EntityTypes1_17 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -25,8 +25,8 @@ package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import java.util.Locale;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_19 implements EntityType {
@ -265,7 +265,7 @@ public enum EntityTypes1_19 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -25,8 +25,8 @@ package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import java.util.Locale;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_19_3 implements EntityType {
@ -266,7 +266,7 @@ public enum EntityTypes1_19_3 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -25,8 +25,8 @@ package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import java.util.Locale;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_19_4 implements EntityType {
@ -273,7 +273,7 @@ public enum EntityTypes1_19_4 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -25,8 +25,8 @@ package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import java.util.Locale;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_20_3 implements EntityType {
@ -275,7 +275,7 @@ public enum EntityTypes1_20_3 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -25,8 +25,8 @@ package com.viaversion.viaversion.api.minecraft.entities;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.EntityTypeUtil;
import java.util.Locale;
import com.viaversion.viaversion.util.Key;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
public enum EntityTypes1_20_5 implements EntityType {
@ -281,7 +281,7 @@ public enum EntityTypes1_20_5 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -305,7 +305,7 @@ public enum EntityTypes1_21_2 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -304,7 +304,7 @@ public enum EntityTypes1_21_4 implements EntityType {
}
public static EntityType getTypeFromId(final int typeId) {
return EntityTypeUtil.getTypeFromId(TYPES, typeId, ENTITY);
return EntityTypeUtil.getTypeFromId(TYPES, typeId, PIG);
}
public static void initialize(final Protocol<?, ?, ?, ?> protocol) {

View File

@ -22,7 +22,6 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import com.viaversion.viaversion.api.Via;
import java.util.HashMap;
import java.util.Map;
@ -36,10 +35,6 @@ public class EntityTypes1_8 {
} else {
type = EntityType.findById(typeId);
}
if (type == null) {
Via.getPlatform().getLogger().severe("Could not find 1.8 type id " + typeId + " objectType=" + object);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type;
}

View File

@ -22,7 +22,6 @@
*/
package com.viaversion.viaversion.api.minecraft.entities;
import com.viaversion.viaversion.api.Via;
import java.util.HashMap;
import java.util.Map;
@ -36,10 +35,6 @@ public class EntityTypes1_9 {
} else {
type = EntityType.findById(typeId);
}
if (type == null) {
Via.getPlatform().getLogger().severe("Could not find 1.9 type id " + typeId + " objectType=" + object);
return EntityType.ENTITY; // Fall back to the basic ENTITY
}
return type;
}

View File

@ -331,7 +331,6 @@ public class EntityPacketRewriter1_11 extends EntityRewriter<ClientboundPackets1
public EntityType rewriteEntityType(int numType, List<EntityData> entityData) {
EntityType type = EntityType.findById(numType);
if (type == null) {
Via.getManager().getPlatform().getLogger().severe("Error: could not find Entity type " + numType + " with entity data: " + entityData);
return null;
}

View File

@ -18,15 +18,15 @@
package com.viaversion.viaversion.protocols.v1_13_2to1_14.rewriter;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.VillagerData;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_13;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_14;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
@ -82,41 +82,42 @@ public class EntityPacketRewriter1_14 extends EntityRewriter<ClientboundPackets1
int typeId = wrapper.get(Types.VAR_INT, 1);
EntityTypes1_13.EntityType type1_13 = EntityTypes1_13.getTypeFromId(typeId, true);
if (type1_13 == null) {
return;
}
typeId = newEntityId(type1_13.getId());
EntityType type1_14 = EntityTypes1_14.getTypeFromId(typeId);
if (type1_14 != null) {
int data = wrapper.get(Types.INT, 0);
if (type1_14.is(EntityTypes1_14.FALLING_BLOCK)) {
wrapper.set(Types.INT, 0, protocol.getMappingData().getNewBlockStateId(data));
} else if (type1_14.is(EntityTypes1_14.MINECART)) {
typeId = switch (data) {
case 1 -> EntityTypes1_14.CHEST_MINECART.getId();
case 2 -> EntityTypes1_14.FURNACE_MINECART.getId();
case 3 -> EntityTypes1_14.TNT_MINECART.getId();
case 4 -> EntityTypes1_14.SPAWNER_MINECART.getId();
case 5 -> EntityTypes1_14.HOPPER_MINECART.getId();
case 6 -> EntityTypes1_14.COMMAND_BLOCK_MINECART.getId();
default -> typeId; // default 0 = rideable minecart
};
} else if ((type1_14.is(EntityTypes1_14.ITEM) && data > 0)
|| type1_14.isOrHasParent(EntityTypes1_14.ABSTRACT_ARROW)) {
if (type1_14.isOrHasParent(EntityTypes1_14.ABSTRACT_ARROW)) {
wrapper.set(Types.INT, 0, data - 1);
}
// send velocity in separate packet, 1.14 is now ignoring the velocity
PacketWrapper velocity = wrapper.create(ClientboundPackets1_14.SET_ENTITY_MOTION);
velocity.write(Types.VAR_INT, entityId);
velocity.write(Types.SHORT, wrapper.get(Types.SHORT, 0));
velocity.write(Types.SHORT, wrapper.get(Types.SHORT, 1));
velocity.write(Types.SHORT, wrapper.get(Types.SHORT, 2));
velocity.scheduleSend(Protocol1_13_2To1_14.class);
int data = wrapper.get(Types.INT, 0);
if (type1_14.is(EntityTypes1_14.FALLING_BLOCK)) {
wrapper.set(Types.INT, 0, protocol.getMappingData().getNewBlockStateId(data));
} else if (type1_14.is(EntityTypes1_14.MINECART)) {
typeId = switch (data) {
case 1 -> EntityTypes1_14.CHEST_MINECART.getId();
case 2 -> EntityTypes1_14.FURNACE_MINECART.getId();
case 3 -> EntityTypes1_14.TNT_MINECART.getId();
case 4 -> EntityTypes1_14.SPAWNER_MINECART.getId();
case 5 -> EntityTypes1_14.HOPPER_MINECART.getId();
case 6 -> EntityTypes1_14.COMMAND_BLOCK_MINECART.getId();
default -> typeId; // default 0 = rideable minecart
};
} else if ((type1_14.is(EntityTypes1_14.ITEM) && data > 0)
|| type1_14.isOrHasParent(EntityTypes1_14.ABSTRACT_ARROW)) {
if (type1_14.isOrHasParent(EntityTypes1_14.ABSTRACT_ARROW)) {
wrapper.set(Types.INT, 0, data - 1);
}
// Register Type ID
wrapper.user().getEntityTracker(Protocol1_13_2To1_14.class).addEntity(entityId, type1_14);
// send velocity in separate packet, 1.14 is now ignoring the velocity
PacketWrapper velocity = wrapper.create(ClientboundPackets1_14.SET_ENTITY_MOTION);
velocity.write(Types.VAR_INT, entityId);
velocity.write(Types.SHORT, wrapper.get(Types.SHORT, 0));
velocity.write(Types.SHORT, wrapper.get(Types.SHORT, 1));
velocity.write(Types.SHORT, wrapper.get(Types.SHORT, 2));
velocity.scheduleSend(Protocol1_13_2To1_14.class);
}
// Register Type ID
wrapper.user().getEntityTracker(Protocol1_13_2To1_14.class).addEntity(entityId, type1_14);
wrapper.set(Types.VAR_INT, 1, typeId);
});
}
@ -139,7 +140,14 @@ public class EntityPacketRewriter1_14 extends EntityRewriter<ClientboundPackets1
map(Types.SHORT); // 11 - Velocity Z
map(Types1_13_2.ENTITY_DATA_LIST, Types1_14.ENTITY_DATA_LIST); // 12 - Entity data
handler(trackerAndRewriterHandler(Types1_14.ENTITY_DATA_LIST));
handler(wrapper -> {
int entityType = wrapper.get(Types.VAR_INT, 1);
if (EntityTypes1_13.getTypeFromId(entityType, false) == null) {
// <= 1.13.2 will ignore unknown entity types, 1.14+ will spawn a pig as default
wrapper.cancel();
}
trackerAndRewriterHandler(Types1_14.ENTITY_DATA_LIST).handle(wrapper);
});
}
});

View File

@ -18,12 +18,13 @@
package com.viaversion.viaversion.protocols.v1_8to1_9.rewriter;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_9;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_9;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
@ -63,7 +64,11 @@ public class SpawnPacketRewriter1_9 {
int entityID = wrapper.get(Types.VAR_INT, 0);
int typeID = wrapper.get(Types.BYTE, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class);
tracker.addEntity(entityID, EntityTypes1_9.getTypeFromId(typeID, true));
EntityType entityType = EntityTypes1_9.getTypeFromId(typeID, true);
if (entityType != null) {
tracker.addEntity(entityID, entityType);
}
});
map(Types.INT, toNewDouble); // 3 - X - Needs to be divided by 32
@ -176,7 +181,11 @@ public class SpawnPacketRewriter1_9 {
int entityID = wrapper.get(Types.VAR_INT, 0);
int typeID = wrapper.get(Types.UNSIGNED_BYTE, 0);
EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_9.class);
tracker.addEntity(entityID, EntityTypes1_9.getTypeFromId(typeID, false));
EntityType entityType = EntityTypes1_9.getTypeFromId(typeID, false);
if (entityType != null) {
tracker.addEntity(entityID, entityType);
}
});
map(Types.INT, toNewDouble); // 3 - X - Needs to be divided by 32

View File

@ -510,6 +510,9 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
}
final EntityType entityType = typeFromId(trackMappedType ? mappedTypeId : typeId);
if (entityType == null) {
return null;
}
tracker(wrapper.user()).addEntity(entityId, entityType);
return entityType;
}
@ -557,6 +560,9 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
byte type = wrapper.get(Types.BYTE, 0);
EntityType entType = objectTypeFromId(type);
if (entType == null) {
return;
}
// Register Type ID
tracker(wrapper.user()).addEntity(entityId, entType);
};