diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/cat/CatVariant.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/cat/CatVariant.java
new file mode 100644
index 0000000000..218f64727a
--- /dev/null
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/cat/CatVariant.java
@@ -0,0 +1,36 @@
+/*
+ * This file is part of packetevents - https://github.com/retrooper/packetevents
+ * Copyright (C) 2024 retrooper 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 .
+ */
+
+package com.github.retrooper.packetevents.protocol.entity.cat;
+
+import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
+import com.github.retrooper.packetevents.resources.ResourceLocation;
+import com.github.retrooper.packetevents.wrapper.PacketWrapper;
+
+public interface CatVariant extends MappedEntity {
+
+ ResourceLocation getTexture();
+
+ static CatVariant read(PacketWrapper> wrapper) {
+ return wrapper.readMappedEntity(CatVariants.getRegistry());
+ }
+
+ static void write(PacketWrapper> wrapper, CatVariant variant) {
+ wrapper.writeMappedEntity(variant);
+ }
+}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/cat/CatVariantImpl.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/cat/CatVariantImpl.java
new file mode 100644
index 0000000000..20e20440f2
--- /dev/null
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/cat/CatVariantImpl.java
@@ -0,0 +1,38 @@
+/*
+ * This file is part of packetevents - https://github.com/retrooper/packetevents
+ * Copyright (C) 2024 retrooper 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 .
+ */
+
+package com.github.retrooper.packetevents.protocol.entity.cat;
+
+import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
+import com.github.retrooper.packetevents.resources.ResourceLocation;
+import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
+
+public class CatVariantImpl extends AbstractMappedEntity implements CatVariant {
+
+ private final ResourceLocation texture;
+
+ public CatVariantImpl(TypesBuilderData data, ResourceLocation texture) {
+ super(data);
+ this.texture = texture;
+ }
+
+ @Override
+ public ResourceLocation getTexture() {
+ return this.texture;
+ }
+}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/cat/CatVariants.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/cat/CatVariants.java
new file mode 100644
index 0000000000..77ebe88c24
--- /dev/null
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/cat/CatVariants.java
@@ -0,0 +1,59 @@
+/*
+ * This file is part of packetevents - https://github.com/retrooper/packetevents
+ * Copyright (C) 2024 retrooper 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 .
+ */
+
+package com.github.retrooper.packetevents.protocol.entity.cat;
+
+import com.github.retrooper.packetevents.resources.ResourceLocation;
+import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
+
+public final class CatVariants {
+
+ private static final VersionedRegistry REGISTRY = new VersionedRegistry<>(
+ "cat_variant", "entity/cat_variant_mappings");
+
+ public static final CatVariant TABBY = define("tabby");
+ public static final CatVariant BLACK = define("black");
+ public static final CatVariant RED = define("red");
+ public static final CatVariant SIAMESE = define("siamese");
+ public static final CatVariant BRITISH_SHORTHAIR = define("british_shorthair");
+ public static final CatVariant CALICO = define("calico");
+ public static final CatVariant PERSIAN = define("persian");
+ public static final CatVariant RAGDOLL = define("ragdoll");
+ public static final CatVariant WHITE = define("white");
+ public static final CatVariant JELLIE = define("jellie");
+ public static final CatVariant ALL_BLACK = define("all_black");
+
+ private CatVariants() {
+ }
+
+ private static CatVariant define(String name) {
+ return define(name, ResourceLocation.minecraft("textures/entity/cat/" + name + ".png"));
+ }
+
+ private static CatVariant define(String name, ResourceLocation texture) {
+ return REGISTRY.define(name, data -> new CatVariantImpl(data, texture));
+ }
+
+ public static VersionedRegistry getRegistry() {
+ return REGISTRY;
+ }
+
+ static {
+ REGISTRY.unloadMappings();
+ }
+}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityData.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityData.java
index b369b55363..35ec89d60c 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityData.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityData.java
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.protocol.entity.data;
+@Deprecated
public class EntityData {
private int index;
private EntityDataType> type;
@@ -52,4 +53,4 @@ public Object getValue() {
public void setValue(Object value) {
this.value = value;
}
-}
\ No newline at end of file
+}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataType.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataType.java
index 30d01b2cff..e3d183c89f 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataType.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataType.java
@@ -24,33 +24,29 @@
import java.util.function.BiConsumer;
import java.util.function.Function;
-public class EntityDataType {
- private final String name;
- private final int[] ids;
- private final Function, T> dataDeserializer;
- private final BiConsumer, Object> dataSerializer;
-
- public EntityDataType(String name, int[] ids, Function, T> dataDeserializer, BiConsumer, Object> dataSerializer) {
- this.name = name;
- this.ids = ids;
- this.dataDeserializer = dataDeserializer;
- this.dataSerializer = dataSerializer;
+@Deprecated
+public final class EntityDataType {
+
+ private final IEntityDataType delegate;
+
+ EntityDataType(IEntityDataType delegate) {
+ this.delegate = delegate;
}
public String getName() {
- return name;
+ return this.delegate.getName().toString();
}
public int getId(ClientVersion version) {
- int index = EntityDataTypes.TYPES_BUILDER.getDataIndex(version);
- return ids[index];
+ return this.delegate.getId(version);
}
public Function, T> getDataDeserializer() {
- return dataDeserializer;
+ return this.delegate::deserialize;
}
+ @SuppressWarnings("unchecked")
public BiConsumer, Object> getDataSerializer() {
- return dataSerializer;
+ return (wrapper, value) -> this.delegate.serialize(wrapper, (T) value);
}
}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataTypeImpl.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataTypeImpl.java
new file mode 100644
index 0000000000..66a46263d0
--- /dev/null
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataTypeImpl.java
@@ -0,0 +1,69 @@
+/*
+ * This file is part of packetevents - https://github.com/retrooper/packetevents
+ * Copyright (C) 2024 retrooper 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 .
+ */
+
+package com.github.retrooper.packetevents.protocol.entity.data;
+
+import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
+import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
+import com.github.retrooper.packetevents.wrapper.PacketWrapper;
+
+import java.util.function.Function;
+
+public class EntityDataTypeImpl extends AbstractMappedEntity implements IEntityDataType {
+
+ @Deprecated
+ private final EntityDataType legacy;
+
+ private final PacketWrapper.Reader reader;
+ private final PacketWrapper.Writer writer;
+
+ @SuppressWarnings("deprecation")
+ public EntityDataTypeImpl(
+ TypesBuilderData data,
+ PacketWrapper.Reader reader,
+ PacketWrapper.Writer writer
+ ) {
+ super(data);
+ this.legacy = new EntityDataType<>(this);
+ this.reader = reader;
+ this.writer = writer;
+ }
+
+ @Override
+ public T deserialize(PacketWrapper> wrapper) {
+ return this.reader.apply(wrapper);
+ }
+
+ @Override
+ public void serialize(PacketWrapper> wrapper, T value) {
+ this.writer.accept(wrapper, value);
+ }
+
+ @Override
+ public IEntityDataType map(Function processor, Function unprocessor) {
+ return new EntityDataTypeImpl<>(this.data,
+ wrapper -> processor.apply(this.reader.apply(wrapper)),
+ (wrapper, value) -> this.writer.accept(wrapper, unprocessor.apply(value)));
+ }
+
+ @Deprecated
+ @Override
+ public EntityDataType asLegacy() {
+ return this.legacy;
+ }
+}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataTypes.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataTypes.java
index 11a5ab6b6e..3d86139ac2 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataTypes.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataTypes.java
@@ -21,356 +21,366 @@
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.armadillo.ArmadilloState;
+import com.github.retrooper.packetevents.protocol.entity.cat.CatVariant;
+import com.github.retrooper.packetevents.protocol.entity.cat.CatVariants;
+import com.github.retrooper.packetevents.protocol.entity.frog.FrogVariant;
+import com.github.retrooper.packetevents.protocol.entity.frog.FrogVariants;
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
import com.github.retrooper.packetevents.protocol.entity.sniffer.SnifferState;
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
+import com.github.retrooper.packetevents.protocol.entity.wolfvariant.WolfVariant;
+import com.github.retrooper.packetevents.protocol.entity.wolfvariant.WolfVariants;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.particle.Particle;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.BlockFace;
import com.github.retrooper.packetevents.protocol.world.WorldBlockPosition;
-import com.github.retrooper.packetevents.resources.ResourceLocation;
+import com.github.retrooper.packetevents.protocol.world.painting.PaintingVariant;
+import com.github.retrooper.packetevents.protocol.world.painting.PaintingVariants;
+import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
import com.github.retrooper.packetevents.util.Quaternion4f;
import com.github.retrooper.packetevents.util.Vector3f;
import com.github.retrooper.packetevents.util.Vector3i;
-import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
-import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
+import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
-
-import java.util.*;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-
-public class EntityDataTypes {
- //1.7 -> 1.18 block_position is just 3 ints, not serialized with a long
- //short was removed in 1.9+
- //boolean was added in 1.9
- //nbt was added in 1.12
-
- private static final Map> ENTITY_DATA_TYPE_MAP = new HashMap<>();
- private static final Map>> ENTITY_DATA_TYPE_ID_MAP = new HashMap<>();
- protected static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_data_type_mappings");
-
- public static final EntityDataType BYTE = define("byte", PacketWrapper::readByte, PacketWrapper::writeByte);
-
- public static final EntityDataType SHORT = define("short", PacketWrapper::readShort, PacketWrapper::writeShort);
-
- public static final EntityDataType INT = define("int", wrapper -> {
- if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
- return wrapper.readVarInt();
- } else {
- return wrapper.readInt();
+import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+public final class EntityDataTypes {
+
+ // there is no proper mojang registry for this yet, the registry name is just a guess
+ private static final VersionedRegistry> REGISTRY = new VersionedRegistry<>(
+ "entity_data_serializer", "entity/entity_data_type_mappings");
+
+ public static final IEntityDataType TYPE_BYTE = define("byte",
+ PacketWrapper::readByte, PacketWrapper::writeByte);
+ public static final IEntityDataType INT_TYPE = define("int",
+ EntityDataTypes::readVersionedVarInt, EntityDataTypes::writeVersionedVarInt);
+ /**
+ * Added with 1.19.3
+ */
+ public static final IEntityDataType TYPE_LONG = define("long",
+ PacketWrapper::readVarLong, PacketWrapper::writeVarLong);
+ public static final IEntityDataType TYPE_FLOAT = define("float",
+ PacketWrapper::readFloat, PacketWrapper::writeFloat);
+ public static final IEntityDataType TYPE_STRING = define("string",
+ PacketWrapper::readString, PacketWrapper::writeString);
+ /**
+ * Added with 1.9
+ */
+ public static final IEntityDataType TYPE_COMPONENT = define("component",
+ PacketWrapper::readComponent, PacketWrapper::writeComponent);
+ /**
+ * Added with 1.13
+ */
+ public static final IEntityDataType> TYPE_OPTIONAL_COMPONENT = define("optional_component",
+ wrapper -> wrapper.readRealOptional(PacketWrapper::readComponent),
+ (wrapper, component) -> wrapper.writeRealOptional(component, PacketWrapper::writeComponent));
+ public static final IEntityDataType TYPE_ITEM_STACK = define("item_stack",
+ PacketWrapper::readItemStack, PacketWrapper::writeItemStack);
+ /**
+ * Added with 1.9
+ */
+ public static final IEntityDataType TYPE_BOOLEAN = define("boolean",
+ PacketWrapper::readBoolean, PacketWrapper::writeBoolean);
+ public static final IEntityDataType TYPE_ROTATIONS = define("rotations",
+ Vector3f::read, Vector3f::write);
+ public static final IEntityDataType TYPE_BLOCK_POS = define("block_pos",
+ EntityDataTypes::readVersionedBlockPosition, EntityDataTypes::writeVersionedBlockPosition);
+ /**
+ * Added with 1.9
+ */
+ public static final IEntityDataType> TYPE_OPTIONAL_BLOCK_POS = define("optional_block_pos",
+ wrapper -> wrapper.readRealOptional(EntityDataTypes::readVersionedBlockPosition),
+ (wrapper, pos) -> wrapper.writeRealOptional(pos, EntityDataTypes::writeVersionedBlockPosition));
+ /**
+ * Added with 1.9
+ */
+ public static final IEntityDataType TYPE_DIRECTION = define("direction",
+ wrapper -> BlockFace.getBlockFaceByValue(wrapper.readVarInt()), PacketWrapper::writeEnum);
+ /**
+ * Added with 1.9
+ */
+ public static final IEntityDataType> TYPE_OPTIONAL_UUID = define("optional_uuid",
+ wrapper -> wrapper.readRealOptional(PacketWrapper::readUUID),
+ (wrapper, uuid) -> wrapper.writeRealOptional(uuid, PacketWrapper::writeUUID));
+ /**
+ * Added with 1.19.4
+ */
+ public static final IEntityDataType TYPE_BLOCK_STATE = define("block_state",
+ wrapper -> WrappedBlockState.getByGlobalId(wrapper.getServerVersion().toClientVersion(), wrapper.readVarInt()),
+ (wrapper, state) -> wrapper.writeVarInt(state.getGlobalId()));
+ /**
+ * Added with 1.9
+ */
+ public static final IEntityDataType> TYPE_OPTIONAL_BLOCK_STATE = define("optional_block_state", wrapper -> {
+ int id = wrapper.readVarInt();
+ if (id != 0) {
+ ClientVersion version = wrapper.getServerVersion().toClientVersion();
+ return Optional.of(WrappedBlockState.getByGlobalId(version, id));
}
- }, (wrapper, value) -> {
- if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
- wrapper.writeVarInt(value);
+ return Optional.empty();
+ }, (wrapper, state) -> {
+ if (state.isPresent()) {
+ wrapper.writeVarInt(state.get().getGlobalId());
} else {
- wrapper.writeInt(value);
+ wrapper.writeVarInt(0);
}
});
+ /**
+ * Added with 1.11
+ */
+ public static final IEntityDataType TYPE_COMPOUND_TAG = define("compound_tag",
+ PacketWrapper::readNBT, PacketWrapper::writeNBT);
+ /**
+ * Added with 1.13
+ */
+ public static final IEntityDataType> TYPE_PARTICLE = define("particle",
+ Particle::read, Particle::write);
+ /**
+ * Added with 1.20.5
+ */
+ public static final IEntityDataType>> TYPE_PARTICLES = define("particles",
+ wrapper -> wrapper.readList(Particle::read),
+ (wrapper, particles) -> wrapper.writeList(particles, Particle::write));
+ /**
+ * Added with 1.14
+ */
+ public static final IEntityDataType TYPE_VILLAGER_DATA = define("villager_data",
+ PacketWrapper::readVillagerData, PacketWrapper::writeVillagerData);
+ /**
+ * Added with 1.14
+ */
+ public static final IEntityDataType> TYPE_OPTIONAL_UNSIGNED_INT = define("optional_unsigned_int", wrapper -> {
+ int num = wrapper.readVarInt();
+ if (num != 0) {
+ return Optional.of(num - 1);
+ }
+ return Optional.empty();
+ }, (wrapper, value) ->
+ wrapper.writeVarInt(value.orElse(-1) + 1));
+ /**
+ * Added with 1.14
+ */
+ public static final IEntityDataType TYPE_POSE = define("pose",
+ wrapper -> EntityPose.getById(wrapper.getServerVersion().toClientVersion(), wrapper.readVarInt()),
+ (wrapper, pose) -> wrapper.writeVarInt(pose.getId(wrapper.getServerVersion().toClientVersion())));
+ /**
+ * Added with 1.19
+ */
+ public static final IEntityDataType TYPE_CAT_VARIANT = define("cat_variant", CatVariant::read, CatVariant::write);
+ /**
+ * Added with 1.20.5
+ */
+ public static final IEntityDataType TYPE_WOLF_VARIANT = define("wolf_variant", WolfVariant::read, WolfVariant::write);
+ /**
+ * Added with 1.19
+ */
+ public static final IEntityDataType TYPE_FROG_VARIANT = define("frog_variant", FrogVariant::read, FrogVariant::write);
+ /**
+ * Added with 1.19
+ */
+ public static final IEntityDataType> TYPE_OPTIONAL_GLOBAL_POS = define("optional_global_pos",
+ wrapper -> wrapper.readRealOptional(WorldBlockPosition::read),
+ (wrapper, pos) -> wrapper.writeRealOptional(pos, PacketWrapper::writeWorldBlockPosition));
+ /**
+ * Added with 1.19
+ */
+ public static final IEntityDataType TYPE_PAINTING_VARIANT = define("painting_variant", PaintingVariant::read, PaintingVariant::write);
+ /**
+ * Added with 1.19.4
+ */
+ public static final IEntityDataType TYPE_SNIFFER_STATE = define("sniffer_state",
+ wrapper -> wrapper.readEnum(SnifferState.values()), PacketWrapper::writeEnum);
+ /**
+ * Added with 1.20.5
+ */
+ public static final IEntityDataType TYPE_ARMADILLO_STATE = define("armadillo_state",
+ wrapper -> wrapper.readEnum(ArmadilloState.values()), PacketWrapper::writeEnum);
+ /**
+ * Added with 1.19.4
+ */
+ public static final IEntityDataType TYPE_VECTOR3 = define("vector3", Vector3f::read, Vector3f::write);
+ /**
+ * Added with 1.19.4
+ */
+ public static final IEntityDataType TYPE_QUATERNION = define("quaternion", Quaternion4f::read, Quaternion4f::write);
- public static final EntityDataType LONG = define("long", PacketWrapper::readVarLong, PacketWrapper::writeVarLong);
-
- public static final EntityDataType FLOAT = define("float", PacketWrapper::readFloat, PacketWrapper::writeFloat);
-
- public static final EntityDataType STRING = define("string", PacketWrapper::readString, PacketWrapper::writeString);
+ /**
+ * Removed in 1.9
+ */
+ @ApiStatus.Obsolete
+ public static final IEntityDataType TYPE_SHORT = define("short", PacketWrapper::readShort, PacketWrapper::writeShort);
+ //
+ private static final GsonComponentSerializer GSON_SERIALIZER = GsonComponentSerializer.gson();
@Deprecated
- public static final EntityDataType COMPONENT = define("component", PacketWrapper::readComponentJSON, PacketWrapper::writeComponentJSON);
- public static final EntityDataType ADV_COMPONENT = define("component", PacketWrapper::readComponent, PacketWrapper::writeComponent);
-
+ public static final EntityDataType BYTE = TYPE_BYTE.asLegacy();
@Deprecated
- public static final EntityDataType> OPTIONAL_COMPONENT = define("optional_component", readOptionalComponentJSONDeserializer(), writeOptionalComponentJSONSerializer());
- public static final EntityDataType> OPTIONAL_ADV_COMPONENT = define("optional_component", readOptionalComponentDeserializer(), writeOptionalComponentSerializer());
-
- public static final EntityDataType ITEMSTACK = define("itemstack", PacketWrapper::readItemStack, PacketWrapper::writeItemStack);
-
- public static final EntityDataType> OPTIONAL_ITEMSTACK = define("optional_itemstack",
- (PacketWrapper> wrapper) -> Optional.of(wrapper.readItemStack()),
- (PacketWrapper> wrapper, Optional value) -> wrapper.writeItemStack(value.orElse(null)));
-
- public static final EntityDataType BOOLEAN = define("boolean", PacketWrapper::readBoolean, PacketWrapper::writeBoolean);
-
- public static final EntityDataType ROTATION = define("rotation",
- (PacketWrapper> wrapper) -> new Vector3f(wrapper.readFloat(), wrapper.readFloat(), wrapper.readFloat()),
- (PacketWrapper> wrapper, Vector3f value) -> {
- wrapper.writeFloat(value.x);
- wrapper.writeFloat(value.y);
- wrapper.writeFloat(value.z);
- });
-
- public static final EntityDataType BLOCK_POSITION = define("block_position", (PacketWrapper> wrapper) -> {
- if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
- return wrapper.readBlockPosition();
- } else {
- int x = wrapper.readInt();
- int y = wrapper.readInt();
- int z = wrapper.readInt();
- return new Vector3i(x, y, z);
- }
- }, (wrapper, blockPosition) -> {
- if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
- wrapper.writeBlockPosition(blockPosition);
- } else {
- wrapper.writeInt(blockPosition.getX());
- wrapper.writeInt(blockPosition.getY());
- wrapper.writeInt(blockPosition.getZ());
- }
- });
-
- public static final EntityDataType> OPTIONAL_BLOCK_POSITION = define("optional_block_position",
- readOptionalBlockPositionDeserializer(), writeOptionalBlockPositionSerializer());
-
- public static final EntityDataType BLOCK_FACE = define("block_face", (PacketWrapper> wrapper) -> {
- int id = wrapper.readVarInt();
- return BlockFace.getBlockFaceByValue(id);
- },
- (PacketWrapper> wrapper, BlockFace value) -> wrapper.writeVarInt(value.getFaceValue()));
-
- public static final EntityDataType> OPTIONAL_UUID = define("optional_uuid",
- (PacketWrapper> wrapper) -> Optional.ofNullable(wrapper.readOptional(PacketWrapper::readUUID)),
- (PacketWrapper> wrapper, Optional value) ->
- wrapper.writeOptional(value.orElse(null), PacketWrapper::writeUUID));
-
- public static final EntityDataType BLOCK_STATE = define("block_state",
- readIntDeserializer(), writeIntSerializer());
-
- public static final EntityDataType OPTIONAL_BLOCK_STATE = define("optional_block_state", readIntDeserializer(), writeIntSerializer());
-
- public static final EntityDataType NBT = define("nbt", PacketWrapper::readNBT, PacketWrapper::writeNBT);
-
- public static final EntityDataType> PARTICLE = define("particle", Particle::read, Particle::write);
-
- public static final EntityDataType VILLAGER_DATA = define("villager_data", PacketWrapper::readVillagerData, PacketWrapper::writeVillagerData);
-
- public static final EntityDataType> OPTIONAL_INT = define("optional_int", (PacketWrapper> wrapper) -> {
- int i = wrapper.readVarInt();
- return i == 0 ? Optional.empty() : Optional.of(i - 1);
- }, (PacketWrapper> wrapper, Optional value) -> {
- wrapper.writeVarInt(value.orElse(-1) + 1);
- });
-
- public static final EntityDataType ENTITY_POSE = define("entity_pose", (PacketWrapper> wrapper) -> {
- int id = wrapper.readVarInt();
- return EntityPose.getById(wrapper.getServerVersion().toClientVersion(), id);
- }, (PacketWrapper> wrapper, EntityPose value) -> wrapper.writeVarInt(value.getId(wrapper.getServerVersion().toClientVersion())));
-
- public static final EntityDataType CAT_VARIANT = define("cat_variant_type", readIntDeserializer(), writeIntSerializer());
-
- public static final EntityDataType FROG_VARIANT = define("frog_variant_type", readIntDeserializer(), writeIntSerializer());
-
- public static final EntityDataType> OPTIONAL_GLOBAL_POSITION = define("optional_global_position",
- (PacketWrapper> wrapper) -> Optional.ofNullable(wrapper.readOptional(w -> new WorldBlockPosition(new ResourceLocation(w.readString(32767)), w.readBlockPosition()))),
- (PacketWrapper> wrapper, Optional value) -> wrapper.writeOptional(value.orElse(null), (w, globalPos) -> {
- w.writeString(globalPos.getWorld().toString());
- w.writeBlockPosition(globalPos.getBlockPosition());
- }));
-
- public static final EntityDataType PAINTING_VARIANT_TYPE = define("painting_variant_type", readIntDeserializer(), writeIntSerializer());
-
- public static final EntityDataType SNIFFER_STATE = define("sniffer_state", (PacketWrapper> wrapper) -> {
- int id = wrapper.readVarInt();
- return SnifferState.values()[id];
- }, (PacketWrapper> wrapper, SnifferState value) -> wrapper.writeVarInt(value.ordinal()));
-
- public static final EntityDataType VECTOR3F = define("vector3f",
- (PacketWrapper> wrapper) -> new Vector3f(wrapper.readFloat(), wrapper.readFloat(), wrapper.readFloat()),
- (PacketWrapper> wrapper, Vector3f value) -> {
- wrapper.writeFloat(value.x);
- wrapper.writeFloat(value.y);
- wrapper.writeFloat(value.z);
- });
-
- public static final EntityDataType QUATERNION = define("quaternion",
- (PacketWrapper> wrapper) -> new Quaternion4f(wrapper.readFloat(), wrapper.readFloat(), wrapper.readFloat(), wrapper.readFloat()),
- (PacketWrapper> wrapper, Quaternion4f value) -> {
- wrapper.writeFloat(value.getX());
- wrapper.writeFloat(value.getY());
- wrapper.writeFloat(value.getZ());
- wrapper.writeFloat(value.getW());
- });
-
- // Added in 1.20.5
- public static final EntityDataType ARMADILLO_STATE = define("armadillo_state",
- (PacketWrapper> wrapper) -> ArmadilloState.values()[wrapper.readVarInt()],
- (PacketWrapper> wrapper, ArmadilloState value) -> wrapper.writeVarInt(value.ordinal())
- );
+ public static final EntityDataType INT = INT_TYPE.asLegacy();
+ @Deprecated
+ public static final EntityDataType SHORT = TYPE_SHORT.asLegacy();
+ @Deprecated
+ public static final EntityDataType LONG = TYPE_LONG.asLegacy();
+ @Deprecated
+ public static final EntityDataType FLOAT = TYPE_FLOAT.asLegacy();
+ @Deprecated
+ public static final EntityDataType STRING = TYPE_STRING.asLegacy();
+ @Deprecated
+ public static final EntityDataType COMPONENT = TYPE_COMPONENT.map(
+ GSON_SERIALIZER::serialize, GSON_SERIALIZER::deserialize).asLegacy();
+ @Deprecated
+ public static final EntityDataType ADV_COMPONENT = TYPE_COMPONENT.asLegacy();
+ @Deprecated
+ public static final EntityDataType> OPTIONAL_COMPONENT = TYPE_OPTIONAL_COMPONENT.map(
+ comp -> comp.map(GSON_SERIALIZER::serialize),
+ string -> string.map(GSON_SERIALIZER::deserialize)).asLegacy();
+ @Deprecated
+ public static final EntityDataType> OPTIONAL_ADV_COMPONENT = TYPE_OPTIONAL_COMPONENT.asLegacy();
+ @Deprecated
+ public static final EntityDataType ITEMSTACK = TYPE_ITEM_STACK.asLegacy();
+ @Deprecated
+ public static final EntityDataType> OPTIONAL_ITEMSTACK = TYPE_ITEM_STACK.map(
+ Optional::of, opt -> opt.orElse(ItemStack.EMPTY)).asLegacy();
+ @Deprecated
+ public static final EntityDataType BOOLEAN = TYPE_BOOLEAN.asLegacy();
+ @Deprecated
+ public static final EntityDataType ROTATION = TYPE_ROTATIONS.asLegacy();
+ @Deprecated
+ public static final EntityDataType BLOCK_POSITION = TYPE_BLOCK_POS.asLegacy();
+ @Deprecated
+ public static final EntityDataType> OPTIONAL_BLOCK_POSITION = TYPE_OPTIONAL_BLOCK_POS.asLegacy();
+ @Deprecated
+ public static final EntityDataType BLOCK_FACE = TYPE_DIRECTION.asLegacy();
+ @Deprecated
+ public static final EntityDataType> OPTIONAL_UUID = TYPE_OPTIONAL_UUID.asLegacy();
+ @Deprecated
+ public static final EntityDataType BLOCK_STATE = TYPE_BLOCK_STATE.map(
+ WrappedBlockState::getGlobalId, WrappedBlockState::getByGlobalId).asLegacy();
+ @Deprecated
+ public static final EntityDataType OPTIONAL_BLOCK_STATE = TYPE_OPTIONAL_BLOCK_STATE.map(
+ state -> state.map(WrappedBlockState::getGlobalId).orElse(0),
+ id -> id == 0 ? Optional.empty() : Optional.of(WrappedBlockState.getByGlobalId(id))).asLegacy();
+ @Deprecated
+ public static final EntityDataType NBT = TYPE_COMPOUND_TAG.asLegacy();
+ @Deprecated
+ public static final EntityDataType> PARTICLE = TYPE_PARTICLE.asLegacy();
+ @Deprecated
+ public static final EntityDataType>> PARTICLES = TYPE_PARTICLES.asLegacy();
+ @Deprecated
+ public static final EntityDataType VILLAGER_DATA = TYPE_VILLAGER_DATA.asLegacy();
+ @Deprecated
+ public static final EntityDataType> OPTIONAL_INT = TYPE_OPTIONAL_UNSIGNED_INT.asLegacy();
+ @Deprecated
+ public static final EntityDataType ENTITY_POSE = TYPE_POSE.asLegacy();
+ @Deprecated
+ public static final EntityDataType CAT_VARIANT = TYPE_CAT_VARIANT.map(
+ variant -> variant.getId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()),
+ id -> CatVariants.getRegistry().getById(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), id)).asLegacy();
+ @Deprecated
+ public static final EntityDataType WOLF_VARIANT = TYPE_WOLF_VARIANT.map(
+ variant -> variant.getId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()),
+ id -> WolfVariants.getRegistry().getById(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), id)).asLegacy();
+ @Deprecated
+ public static final EntityDataType FROG_VARIANT = TYPE_FROG_VARIANT.map(
+ variant -> variant.getId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()),
+ id -> FrogVariants.getRegistry().getById(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), id)).asLegacy();
+ @Deprecated
+ public static final EntityDataType> OPTIONAL_GLOBAL_POSITION = TYPE_OPTIONAL_GLOBAL_POS.asLegacy();
+ @Deprecated
+ public static final EntityDataType PAINTING_VARIANT_TYPE = TYPE_PAINTING_VARIANT.map(
+ variant -> variant.getId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()),
+ id -> PaintingVariants.getRegistry().getById(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), id)).asLegacy();
+ @Deprecated
+ public static final EntityDataType SNIFFER_STATE = TYPE_SNIFFER_STATE.asLegacy();
+ @Deprecated
+ public static final EntityDataType ARMADILLO_STATE = TYPE_ARMADILLO_STATE.asLegacy();
+ @Deprecated
+ public static final EntityDataType VECTOR3F = TYPE_VECTOR3.asLegacy();
+ @Deprecated
+ public static final EntityDataType QUATERNION = TYPE_QUATERNION.asLegacy();
- public static final EntityDataType>> PARTICLES = define("particles",
- wrapper -> wrapper.readList(Particle::read),
- (wrapper, particles) -> wrapper.writeList(particles, Particle::write)
- );
+ @Deprecated
+ private static final List> LEGACY_ENTRIES = Collections.unmodifiableList(REGISTRY.getEntries().stream()
+ .map(IEntityDataType::asLegacy).collect(Collectors.toList()));
+ //
- public static final EntityDataType WOLF_VARIANT =
- define("wolf_variant_type", readIntDeserializer(), writeIntSerializer());
+ public static VersionedRegistry> getRegistry() {
+ return REGISTRY;
+ }
/**
* Returns an immutable view of the entity-data types.
+ *
* @return Entity-Data Types
*/
+ @Deprecated
public static Collection> values() {
- return Collections.unmodifiableCollection(ENTITY_DATA_TYPE_MAP.values());
- }
-
- public static EntityDataType> getById(ClientVersion version, int id) {
- int index = TYPES_BUILDER.getDataIndex(version);
- Map> typeIdMap = ENTITY_DATA_TYPE_ID_MAP.get((byte) index);
- return typeIdMap.get(id);
- }
-
- public static EntityDataType> getByName(String name) {
- return ENTITY_DATA_TYPE_MAP.get(name);
- }
-
- public static EntityDataType define(String name, Function, T> deserializer, BiConsumer, T> serializer) {
- TypesBuilderData data = TYPES_BUILDER.define(name);
- EntityDataType type = new EntityDataType<>(name, data.getData(), deserializer,
- (BiConsumer, Object>) serializer);
- ENTITY_DATA_TYPE_MAP.put(type.getName(), type);
- for (ClientVersion version : TYPES_BUILDER.getVersions()) {
- int index = TYPES_BUILDER.getDataIndex(version);
- if (index == -1) continue;
- Map> typeIdMap = ENTITY_DATA_TYPE_ID_MAP
- .computeIfAbsent((byte) index, k -> new HashMap<>());
- typeIdMap.put(type.getId(version), type);
- }
- return type;
- }
-
- private static Function, T> readIntDeserializer() {
- if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
- return (PacketWrapper> wrapper) -> (T) ((Object) wrapper.readVarInt());
- } else {
- return (PacketWrapper> wrapper) -> (T) ((Object) wrapper.readInt());
- }
+ return LEGACY_ENTRIES;
}
- private static BiConsumer, T> writeIntSerializer() {
- return (PacketWrapper> wrapper, T value) -> {
- int output = 0;
- if (value instanceof Byte) {
- output = ((Byte) value).intValue();
- } else if (value instanceof Short) {
- output = ((Short) value).intValue();
- } else if (value instanceof Integer) {
- output = (Integer) value;
- } else if (value instanceof Long) {
- output = ((Long) value).intValue();
- }
- if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
- wrapper.writeVarInt(output);
- } else {
- wrapper.writeInt(output);
- }
- };
+ @Deprecated
+ public static @Nullable EntityDataType> getById(ClientVersion version, int id) {
+ IEntityDataType> type = REGISTRY.getById(version, id);
+ return type == null ? null : type.asLegacy();
}
@Deprecated
- private static Function, Optional> readOptionalComponentJSONDeserializer() {
- return (PacketWrapper> wrapper) -> {
- if (wrapper.readBoolean()) {
- return Optional.of(wrapper.readComponentJSON());
- } else {
- return Optional.empty();
- }
- };
+ public static @Nullable EntityDataType> getByName(String name) {
+ IEntityDataType> type = REGISTRY.getByName(name);
+ return type == null ? null : type.asLegacy();
}
- @Deprecated
- private static BiConsumer, Optional> writeOptionalComponentJSONSerializer() {
- return (PacketWrapper> wrapper, Optional value) -> {
- if (value != null && value.isPresent()) {
- wrapper.writeBoolean(true);
- wrapper.writeComponentJSON(value.get());
- } else {
- wrapper.writeBoolean(false);
- }
- };
+ private static IEntityDataType define(
+ String name, PacketWrapper.Reader reader, PacketWrapper.Writer writer) {
+ return REGISTRY.define(name, data ->
+ new EntityDataTypeImpl<>(data, reader, writer));
}
- private static Function, Optional> readOptionalComponentDeserializer() {
- return (PacketWrapper> wrapper) -> {
- if (wrapper.readBoolean()) {
- return Optional.of(wrapper.readComponent());
- } else {
- return Optional.empty();
- }
- };
+ private static int readVersionedVarInt(PacketWrapper> wrapper) {
+ if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
+ return wrapper.readVarInt();
+ }
+ return wrapper.readInt();
}
- private static BiConsumer, Optional> writeOptionalComponentSerializer() {
- return (PacketWrapper> wrapper, Optional value) -> {
- if (value != null && value.isPresent()) {
- wrapper.writeBoolean(true);
- wrapper.writeComponent(value.get());
- } else {
- wrapper.writeBoolean(false);
- }
- };
+ private static void writeVersionedVarInt(PacketWrapper> wrapper, Number number) {
+ if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
+ wrapper.writeVarInt(number.intValue());
+ } else {
+ wrapper.writeInt(number.intValue());
+ }
}
- private static Function, T> readOptionalBlockPositionDeserializer() {
- if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
- return (PacketWrapper> wrapper) -> {
- if (wrapper.readBoolean()) {
- return (T) Optional.of(wrapper.readBlockPosition());
- } else {
- return (T) Optional.empty();
- }
- };
+ private static Vector3i readVersionedBlockPosition(PacketWrapper> wrapper) {
+ if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
+ return wrapper.readBlockPosition();
} else {
- return (PacketWrapper> wrapper) -> {
- if (wrapper.readBoolean()) {
- int x = wrapper.readInt();
- int y = wrapper.readInt();
- int z = wrapper.readInt();
- return (T) Optional.of(new Vector3i(x, y, z));
- } else {
- return (T) Optional.empty();
- }
- };
+ return new Vector3i(wrapper.readInt(), wrapper.readInt(), wrapper.readInt());
}
}
- private static BiConsumer, T> writeOptionalBlockPositionSerializer() {
- if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
- return (PacketWrapper> wrapper, T value) -> {
- if (value instanceof Optional) {
- Optional> optional = (Optional>) value;
- if (optional.isPresent()) {
- wrapper.writeBoolean(true);
- wrapper.writeBlockPosition((Vector3i) optional.get());
- } else {
- wrapper.writeBoolean(false);
- }
- } else {
- wrapper.writeBoolean(false);
- }
- };
+ private static void writeVersionedBlockPosition(PacketWrapper> wrapper, Vector3i vector) {
+ if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
+ wrapper.writeBlockPosition(vector);
} else {
- return (PacketWrapper> wrapper, T value) -> {
- if (value instanceof Optional) {
- Optional> optional = (Optional>) value;
- if (optional.isPresent()) {
- wrapper.writeBoolean(true);
- Vector3i position = (Vector3i) optional.get();
- wrapper.writeInt(position.getX());
- wrapper.writeInt(position.getY());
- wrapper.writeInt(position.getZ());
- } else {
- wrapper.writeBoolean(false);
- }
- } else {
- wrapper.writeBoolean(false);
- }
- };
+ wrapper.writeInt(vector.x);
+ wrapper.writeInt(vector.y);
+ wrapper.writeInt(vector.z);
}
}
static {
- TYPES_BUILDER.unloadFileMappings();
+ REGISTRY.unloadMappings();
}
-
}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataValue.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataValue.java
new file mode 100644
index 0000000000..472284c283
--- /dev/null
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/EntityDataValue.java
@@ -0,0 +1,82 @@
+/*
+ * This file is part of packetevents - https://github.com/retrooper/packetevents
+ * Copyright (C) 2024 retrooper 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 .
+ */
+
+package com.github.retrooper.packetevents.protocol.entity.data;
+
+import java.util.Objects;
+
+public class EntityDataValue {
+
+ private int index;
+ private IEntityDataType type;
+ private T value;
+
+ public EntityDataValue(int index, IEntityDataType type, T value) {
+ this.index = index;
+ this.type = type;
+ this.value = value;
+ }
+
+ @Deprecated
+ public EntityData toLegacy() {
+ return new EntityData(this.index, this.type.asLegacy(), this.value);
+ }
+
+ public int getIndex() {
+ return this.index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+
+ public IEntityDataType getType() {
+ return this.type;
+ }
+
+ public void setType(IEntityDataType type) {
+ this.type = type;
+ }
+
+ public T getValue() {
+ return this.value;
+ }
+
+ public void setValue(T value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof EntityDataValue)) return false;
+ EntityDataValue> that = (EntityDataValue>) obj;
+ if (this.index != that.index) return false;
+ if (!this.type.equals(that.type)) return false;
+ return this.value.equals(that.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.index, this.type, this.value);
+ }
+
+ @Override
+ public String toString() {
+ return "EntityDataValue{index=" + this.index + ", type=" + this.type + ", value=" + this.value + '}';
+ }
+}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/IEntityDataType.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/IEntityDataType.java
new file mode 100644
index 0000000000..13168c5354
--- /dev/null
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/data/IEntityDataType.java
@@ -0,0 +1,44 @@
+/*
+ * This file is part of packetevents - https://github.com/retrooper/packetevents
+ * Copyright (C) 2024 retrooper 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 .
+ */
+
+package com.github.retrooper.packetevents.protocol.entity.data;
+
+import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
+import com.github.retrooper.packetevents.wrapper.PacketWrapper;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract;
+
+import java.util.function.Function;
+
+public interface IEntityDataType extends MappedEntity {
+
+ T deserialize(PacketWrapper> wrapper);
+
+ void serialize(PacketWrapper> wrapper, T value);
+
+ /**
+ * Used internally for backwards compatibility
+ * for a few datatypes, may be removed at any time.
+ */
+ @ApiStatus.Internal
+ @Contract("_, _ -> new")
+ IEntityDataType map(Function processor, Function unprocessor);
+
+ @Deprecated
+ EntityDataType asLegacy();
+}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/frog/FrogVariant.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/frog/FrogVariant.java
new file mode 100644
index 0000000000..344e8028c7
--- /dev/null
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/frog/FrogVariant.java
@@ -0,0 +1,36 @@
+/*
+ * This file is part of packetevents - https://github.com/retrooper/packetevents
+ * Copyright (C) 2024 retrooper 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 .
+ */
+
+package com.github.retrooper.packetevents.protocol.entity.frog;
+
+import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
+import com.github.retrooper.packetevents.resources.ResourceLocation;
+import com.github.retrooper.packetevents.wrapper.PacketWrapper;
+
+public interface FrogVariant extends MappedEntity {
+
+ ResourceLocation getTexture();
+
+ static FrogVariant read(PacketWrapper> wrapper) {
+ return wrapper.readMappedEntity(FrogVariants.getRegistry());
+ }
+
+ static void write(PacketWrapper> wrapper, FrogVariant variant) {
+ wrapper.writeMappedEntity(variant);
+ }
+}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/frog/FrogVariantImpl.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/frog/FrogVariantImpl.java
new file mode 100644
index 0000000000..3d42839bb2
--- /dev/null
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/frog/FrogVariantImpl.java
@@ -0,0 +1,38 @@
+/*
+ * This file is part of packetevents - https://github.com/retrooper/packetevents
+ * Copyright (C) 2024 retrooper 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 .
+ */
+
+package com.github.retrooper.packetevents.protocol.entity.frog;
+
+import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
+import com.github.retrooper.packetevents.resources.ResourceLocation;
+import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
+
+public class FrogVariantImpl extends AbstractMappedEntity implements FrogVariant {
+
+ private final ResourceLocation texture;
+
+ public FrogVariantImpl(TypesBuilderData data, ResourceLocation texture) {
+ super(data);
+ this.texture = texture;
+ }
+
+ @Override
+ public ResourceLocation getTexture() {
+ return this.texture;
+ }
+}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/frog/FrogVariants.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/frog/FrogVariants.java
new file mode 100644
index 0000000000..abf7811976
--- /dev/null
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/frog/FrogVariants.java
@@ -0,0 +1,51 @@
+/*
+ * This file is part of packetevents - https://github.com/retrooper/packetevents
+ * Copyright (C) 2024 retrooper 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 .
+ */
+
+package com.github.retrooper.packetevents.protocol.entity.frog;
+
+import com.github.retrooper.packetevents.resources.ResourceLocation;
+import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
+
+public final class FrogVariants {
+
+ public static final VersionedRegistry REGISTRY = new VersionedRegistry<>(
+ "frog_variant", "entity/frog_variant_mappings");
+
+ public static final FrogVariant TEMPERATE = define("temperate");
+ public static final FrogVariant WARM = define("warm");
+ public static final FrogVariant COLD = define("cold");
+
+ private FrogVariants() {
+ }
+
+ private static FrogVariant define(String name) {
+ return define(name, ResourceLocation.minecraft("textures/entity/frog/" + name + "_frog.png"));
+ }
+
+ private static FrogVariant define(String name, ResourceLocation texture) {
+ return REGISTRY.define(name, data -> new FrogVariantImpl(data, texture));
+ }
+
+ public static VersionedRegistry getRegistry() {
+ return REGISTRY;
+ }
+
+ static {
+ REGISTRY.unloadMappings();
+ }
+}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/wolfvariant/WolfVariant.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/wolfvariant/WolfVariant.java
index 752a73d6c4..3f1dad181c 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/wolfvariant/WolfVariant.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/entity/wolfvariant/WolfVariant.java
@@ -30,6 +30,7 @@
import com.github.retrooper.packetevents.protocol.world.biome.Biomes;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
+import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
public interface WolfVariant extends MappedEntity, CopyableEntity, DeepComparableEntity {
@@ -42,6 +43,29 @@ public interface WolfVariant extends MappedEntity, CopyableEntity,
MappedEntitySet getBiomes();
+ static WolfVariant read(PacketWrapper> wrapper) {
+ return wrapper.readMappedEntityOrDirect(WolfVariants.getRegistry(), WolfVariant::readDirect);
+ }
+
+ static void write(PacketWrapper> wrapper, WolfVariant variant) {
+ wrapper.writeMappedEntityOrDirect(variant, WolfVariant::writeDirect);
+ }
+
+ static WolfVariant readDirect(PacketWrapper> wrapper) {
+ ResourceLocation wildTexture = wrapper.readIdentifier();
+ ResourceLocation tameTexture = wrapper.readIdentifier();
+ ResourceLocation angryTexture = wrapper.readIdentifier();
+ MappedEntitySet biomes = MappedEntitySet.read(wrapper, Biomes.getRegistry());
+ return new StaticWolfVariant(wildTexture, tameTexture, angryTexture, biomes);
+ }
+
+ static void writeDirect(PacketWrapper> wrapper, WolfVariant variant) {
+ wrapper.writeIdentifier(variant.getWildTexture());
+ wrapper.writeIdentifier(variant.getTameTexture());
+ wrapper.writeIdentifier(variant.getAngryTexture());
+ MappedEntitySet.write(wrapper, variant.getBiomes());
+ }
+
static WolfVariant decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
NBTCompound compound = (NBTCompound) nbt;
ResourceLocation wildTexture = new ResourceLocation(compound.getStringTagValueOrThrow("wild_texture"));
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/world/WorldBlockPosition.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/world/WorldBlockPosition.java
index c1d8fcc675..5892bd0c1d 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/protocol/world/WorldBlockPosition.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/world/WorldBlockPosition.java
@@ -21,9 +21,11 @@
import com.github.retrooper.packetevents.protocol.world.dimension.DimensionType;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.Vector3i;
+import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.NotNull;
public class WorldBlockPosition {
+
private ResourceLocation world;
private Vector3i blockPosition;
@@ -42,10 +44,25 @@ public WorldBlockPosition(@NotNull Dimension dimension, @NotNull Vector3i blockP
this(new ResourceLocation(dimension.getDimensionName()), blockPosition);
}
+ /**
+ * @deprecated Multiple dimensions can have the same dimension type, please reference the specific dimension using a {@link ResourceLocation}.
+ */
+ @Deprecated
public WorldBlockPosition(@NotNull DimensionType dimensionType, @NotNull Vector3i blockPosition) {
this(dimensionType.getName(), blockPosition);
}
+ public static WorldBlockPosition read(PacketWrapper> wrapper) {
+ ResourceLocation dimension = wrapper.readIdentifier();
+ Vector3i pos = wrapper.readBlockPosition();
+ return new WorldBlockPosition(dimension, pos);
+ }
+
+ public static void write(PacketWrapper> wrapper, WorldBlockPosition pos) {
+ wrapper.writeIdentifier(pos.world);
+ wrapper.writeBlockPosition(pos.blockPosition);
+ }
+
public ResourceLocation getWorld() {
return world;
}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/PaintingVariant.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/PaintingVariant.java
index 3eec7376db..f0668ea024 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/PaintingVariant.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/PaintingVariant.java
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.protocol.world.painting;
+import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
import com.github.retrooper.packetevents.protocol.mapper.DeepComparableEntity;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
@@ -27,8 +28,10 @@
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
+import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
+import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
public interface PaintingVariant extends MappedEntity, CopyableEntity, DeepComparableEntity {
@@ -39,17 +42,38 @@ public interface PaintingVariant extends MappedEntity, CopyableEntity wrapper) {
+ return wrapper.readMappedEntityOrDirect(PaintingVariants.getRegistry(), PaintingVariant::readDirect);
+ }
+
+ static void write(PacketWrapper> wrapper, PaintingVariant variant) {
+ wrapper.writeMappedEntityOrDirect(variant, PaintingVariant::writeDirect);
+ }
+
static PaintingVariant readDirect(PacketWrapper> wrapper) {
int width = wrapper.readVarInt();
int height = wrapper.readVarInt();
ResourceLocation assetId = wrapper.readIdentifier();
- return new StaticPaintingVariant(width, height, assetId);
+ Component title = null, author = null;
+ if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
+ title = wrapper.readOptional(PacketWrapper::readComponent);
+ author = wrapper.readOptional(PacketWrapper::readComponent);
+ }
+ return new StaticPaintingVariant(width, height, assetId, title, author);
}
static void writeDirect(PacketWrapper> wrapper, PaintingVariant variant) {
wrapper.writeVarInt(variant.getWidth());
wrapper.writeVarInt(variant.getHeight());
wrapper.writeIdentifier(variant.getAssetId());
+ if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
+ wrapper.writeOptional(variant.getTitle(), PacketWrapper::writeComponent);
+ wrapper.writeOptional(variant.getAuthor(), PacketWrapper::writeComponent);
+ }
}
static PaintingVariant decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
@@ -57,7 +81,18 @@ static PaintingVariant decode(NBT nbt, ClientVersion version, @Nullable TypesBui
int width = compound.getNumberTagOrThrow("width").getAsInt();
int height = compound.getNumberTagOrThrow("height").getAsInt();
ResourceLocation assetId = new ResourceLocation(compound.getStringTagValueOrThrow("asset_id"));
- return new StaticPaintingVariant(data, width, height, assetId);
+ Component title = null, author = null;
+ if (version.isNewerThanOrEquals(ClientVersion.V_1_21_2)) {
+ NBT titleTag = compound.getTagOrNull("title");
+ if (titleTag != null) {
+ title = AdventureSerializer.fromNbt(titleTag);
+ }
+ NBT authorTag = compound.getTagOrNull("author");
+ if (authorTag != null) {
+ author = AdventureSerializer.fromNbt(authorTag);
+ }
+ }
+ return new StaticPaintingVariant(data, width, height, assetId, title, author);
}
static NBT encode(PaintingVariant variant, ClientVersion version) {
@@ -65,6 +100,14 @@ static NBT encode(PaintingVariant variant, ClientVersion version) {
compound.setTag("width", new NBTInt(variant.getWidth()));
compound.setTag("height", new NBTInt(variant.getHeight()));
compound.setTag("asset_id", new NBTString(variant.getAssetId().toString()));
+ if (version.isNewerThanOrEquals(ClientVersion.V_1_21_2)) {
+ if (variant.getTitle() != null) {
+ compound.setTag("title", AdventureSerializer.toNbt(variant.getTitle()));
+ }
+ if (variant.getAuthor() != null) {
+ compound.setTag("author", AdventureSerializer.toNbt(variant.getAuthor()));
+ }
+ }
return compound;
}
}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/PaintingVariants.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/PaintingVariants.java
index 178888a19c..2a3407d9a0 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/PaintingVariants.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/PaintingVariants.java
@@ -21,9 +21,14 @@
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
+import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
+import static net.kyori.adventure.text.Component.translatable;
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.YELLOW;
+
public final class PaintingVariants {
private static final VersionedRegistry REGISTRY = new VersionedRegistry<>(
@@ -40,6 +45,17 @@ public static PaintingVariant define(String key, int width, int height) {
@ApiStatus.Internal
public static PaintingVariant define(String key, int width, int height, ResourceLocation assetId) {
+ String i18nPrefix = "painting." + assetId.getNamespace() + "." + assetId.getKey() + ".";
+ return define(key, width, height, assetId,
+ translatable(i18nPrefix + ".title", YELLOW),
+ translatable(i18nPrefix + ".author", GRAY));
+ }
+
+ @ApiStatus.Internal
+ public static PaintingVariant define(
+ String key, int width, int height, ResourceLocation assetId,
+ @Nullable Component title, @Nullable Component author
+ ) {
return REGISTRY.define(key, data ->
new StaticPaintingVariant(data, width, height, assetId));
}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/StaticPaintingVariant.java b/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/StaticPaintingVariant.java
index 9b6219f2d0..86473b1a73 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/StaticPaintingVariant.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/protocol/world/painting/StaticPaintingVariant.java
@@ -21,6 +21,7 @@
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
+import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
@@ -30,16 +31,28 @@ public class StaticPaintingVariant extends AbstractMappedEntity implements Paint
private final int width;
private final int height;
private final ResourceLocation assetId;
+ private final @Nullable Component title;
+ private final @Nullable Component author;
public StaticPaintingVariant(int width, int height, ResourceLocation assetId) {
- this(null, width, height, assetId);
+ this(null, width, height, assetId, null, null);
}
public StaticPaintingVariant(@Nullable TypesBuilderData data, int width, int height, ResourceLocation assetId) {
+ this(data, width, height, assetId, null, null);
+ }
+
+ public StaticPaintingVariant(int width, int height, ResourceLocation assetId, @Nullable Component title, @Nullable Component author) {
+ this(null, width, height, assetId, author, title);
+ }
+
+ public StaticPaintingVariant(@Nullable TypesBuilderData data, int width, int height, ResourceLocation assetId, @Nullable Component title, @Nullable Component author) {
super(data);
this.width = width;
this.height = height;
this.assetId = assetId;
+ this.title = title;
+ this.author = author;
}
@Override
@@ -62,6 +75,16 @@ public ResourceLocation getAssetId() {
return this.assetId;
}
+ @Override
+ public @Nullable Component getTitle() {
+ return this.title;
+ }
+
+ @Override
+ public @Nullable Component getAuthor() {
+ return this.author;
+ }
+
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
@@ -70,16 +93,18 @@ public boolean deepEquals(Object obj) {
StaticPaintingVariant that = (StaticPaintingVariant) obj;
if (this.width != that.width) return false;
if (this.height != that.height) return false;
- return this.assetId.equals(that.assetId);
+ if (!this.assetId.equals(that.assetId)) return false;
+ if (!Objects.equals(this.title, that.title)) return false;
+ return Objects.equals(this.author, that.author);
}
@Override
public int deepHashCode() {
- return Objects.hash(super.hashCode(), this.width, this.height, this.assetId);
+ return Objects.hash(super.hashCode(), this.width, this.height, this.assetId, this.title, this.author);
}
@Override
public String toString() {
- return "StaticPaintingVariant{width=" + this.width + ", height=" + this.height + ", assetId=" + this.assetId + '}';
+ return "StaticPaintingVariant{width=" + this.width + ", height=" + this.height + ", assetId=" + this.assetId + ", title=" + this.title + ", author=" + this.author + '}';
}
}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/util/Quaternion4f.java b/api/src/main/java/com/github/retrooper/packetevents/util/Quaternion4f.java
index cd0b2b8e1f..7270318edb 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/util/Quaternion4f.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/util/Quaternion4f.java
@@ -18,6 +18,8 @@
package com.github.retrooper.packetevents.util;
+import com.github.retrooper.packetevents.wrapper.PacketWrapper;
+
//PacketEvents is not a math library, we don't plan to have all quaternion functions in here.
// We just store the 4 float components for you.
public class Quaternion4f {
@@ -33,6 +35,18 @@ public Quaternion4f(float x, float y, float z, float w) {
this.w = w;
}
+ public static Quaternion4f read(PacketWrapper> wrapper) {
+ return new Quaternion4f(wrapper.readFloat(), wrapper.readFloat(),
+ wrapper.readFloat(), wrapper.readFloat());
+ }
+
+ public static void write(PacketWrapper> wrapper, Quaternion4f quaternion) {
+ wrapper.writeFloat(quaternion.x);
+ wrapper.writeFloat(quaternion.y);
+ wrapper.writeFloat(quaternion.z);
+ wrapper.writeFloat(quaternion.w);
+ }
+
public float getX() {
return x;
}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/util/Vector3f.java b/api/src/main/java/com/github/retrooper/packetevents/util/Vector3f.java
index d49eb755d6..0c2283137f 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/util/Vector3f.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/util/Vector3f.java
@@ -19,6 +19,7 @@
package com.github.retrooper.packetevents.util;
import com.github.retrooper.packetevents.protocol.world.BlockFace;
+import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
@@ -99,6 +100,16 @@ public Vector3f(float[] array) {
}
}
+ public static Vector3f read(PacketWrapper> wrapper) {
+ return new Vector3f(wrapper.readFloat(), wrapper.readFloat(), wrapper.readFloat());
+ }
+
+ public static void write(PacketWrapper> wrapper, Vector3f vector) {
+ wrapper.writeFloat(vector.x);
+ wrapper.writeFloat(vector.y);
+ wrapper.writeFloat(vector.z);
+ }
+
public float getX() {
return x;
}
diff --git a/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java b/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java
index e8be1176ce..acb94f39aa 100644
--- a/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java
+++ b/api/src/main/java/com/github/retrooper/packetevents/wrapper/PacketWrapper.java
@@ -1434,6 +1434,21 @@ public void writeOptional(@Nullable V value, Writer writer) {
}
}
+ public Optional readRealOptional(Reader reader) {
+ if (this.readBoolean()) {
+ return Optional.of(reader.apply(this));
+ }
+ return Optional.empty();
+ }
+
+ public void writeRealOptional(Optional optional, Writer writer) {
+ if (optional.isPresent()) {
+ this.writeBoolean(true);
+ writer.accept(this, optional.get());
+ } else {
+ this.writeBoolean(false);
+ }
+ }
public > C readCollection(IntFunction function, Reader reader) {
int size = this.readVarInt();
diff --git a/api/src/test/java/com/github/retrooper/packetevents/test/MappingIntegrityTest.java b/api/src/test/java/com/github/retrooper/packetevents/test/MappingIntegrityTest.java
index 57d05173f2..e37a2729eb 100644
--- a/api/src/test/java/com/github/retrooper/packetevents/test/MappingIntegrityTest.java
+++ b/api/src/test/java/com/github/retrooper/packetevents/test/MappingIntegrityTest.java
@@ -1,6 +1,8 @@
package com.github.retrooper.packetevents.test;
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
+import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
+import com.github.retrooper.packetevents.protocol.entity.data.IEntityDataType;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.biome.Biomes;
@@ -16,6 +18,9 @@
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MappingIntegrityTest extends BaseDummyAPITest {
@@ -90,4 +95,21 @@ public void testBlockStateMapping() {
state.setAxis(Axis.Z);
assertEquals(159, state.getGlobalId());
}
+
+ @Test
+ @DisplayName("Test entity data type mapping loading")
+ public void testEntityDataTypeMappingLoading() throws IllegalAccessException {
+ for (Field field : EntityDataTypes.class.getFields()) {
+ if (!Modifier.isStatic(field.getModifiers())
+ || field.getDeclaredAnnotations().length != 0) {
+ continue;
+ }
+ IEntityDataType> type = (IEntityDataType>) field.get(null);
+ if (type == EntityDataTypes.TYPE_SHORT) {
+ continue; // ignore legacy types
+ }
+ assertEquals(type, EntityDataTypes.getRegistry().getByName(type.getName()), type.getName().toString());
+ assertEquals(type, EntityDataTypes.getRegistry().getById(ClientVersion.V_1_21_2, type.getId(ClientVersion.V_1_21_2)), type.getName().toString());
+ }
+ }
}
diff --git a/mappings/entity/cat_variant_mappings.json b/mappings/entity/cat_variant_mappings.json
new file mode 100644
index 0000000000..8a6c1f6ebc
--- /dev/null
+++ b/mappings/entity/cat_variant_mappings.json
@@ -0,0 +1,15 @@
+{
+ "V_1_14": [
+ "tabby",
+ "black",
+ "red",
+ "siamese",
+ "british_shorthair",
+ "calico",
+ "persian",
+ "ragdoll",
+ "white",
+ "jellie",
+ "all_black"
+ ]
+}
diff --git a/mappings/entity/entity_data_type_mappings.json b/mappings/entity/entity_data_type_mappings.json
index 2c9d0cda36..85a7cff2c3 100644
--- a/mappings/entity/entity_data_type_mappings.json
+++ b/mappings/entity/entity_data_type_mappings.json
@@ -7,29 +7,29 @@
"string",
"component",
"optional_component",
- "itemstack",
+ "item_stack",
"boolean",
- "rotation",
- "block_position",
- "optional_block_position",
- "block_face",
+ "rotations",
+ "block_pos",
+ "optional_block_pos",
+ "direction",
"optional_uuid",
"block_state",
"optional_block_state",
- "nbt",
+ "compound_tag",
"particle",
"particles",
"villager_data",
- "optional_int",
- "entity_pose",
- "cat_variant_type",
- "wolf_variant_type",
- "frog_variant_type",
- "optional_global_position",
- "painting_variant_type",
+ "optional_unsigned_int",
+ "pose",
+ "cat_variant",
+ "wolf_variant",
+ "frog_variant",
+ "optional_global_pos",
+ "painting_variant",
"sniffer_state",
"armadillo_state",
- "vector3f",
+ "vector3",
"quaternion"
],
"V_1_19_4": [
@@ -40,26 +40,26 @@
"string",
"component",
"optional_component",
- "itemstack",
+ "item_stack",
"boolean",
- "rotation",
- "block_position",
- "optional_block_position",
- "block_face",
+ "rotations",
+ "block_pos",
+ "optional_block_pos",
+ "direction",
"optional_uuid",
"block_state",
"optional_block_state",
- "nbt",
+ "compound_tag",
"particle",
"villager_data",
- "optional_int",
- "entity_pose",
- "cat_variant_type",
- "frog_variant_type",
- "optional_global_position",
- "painting_variant_type",
+ "optional_unsigned_int",
+ "pose",
+ "cat_variant",
+ "frog_variant",
+ "optional_global_pos",
+ "painting_variant",
"sniffer_state",
- "vector3f",
+ "vector3",
"quaternion"
],
"V_1_19_3": [
@@ -70,23 +70,23 @@
"string",
"component",
"optional_component",
- "itemstack",
+ "item_stack",
"boolean",
- "rotation",
- "block_position",
- "optional_block_position",
- "block_face",
+ "rotations",
+ "block_pos",
+ "optional_block_pos",
+ "direction",
"optional_uuid",
"optional_block_state",
- "nbt",
+ "compound_tag",
"particle",
"villager_data",
- "optional_int",
- "entity_pose",
- "cat_variant_type",
- "frog_variant_type",
- "optional_global_position",
- "painting_variant_type"
+ "optional_unsigned_int",
+ "pose",
+ "cat_variant",
+ "frog_variant",
+ "optional_global_pos",
+ "painting_variant"
],
"V_1_19": [
"byte",
@@ -95,23 +95,23 @@
"string",
"component",
"optional_component",
- "itemstack",
+ "item_stack",
"boolean",
- "rotation",
- "block_position",
- "optional_block_position",
- "block_face",
+ "rotations",
+ "block_pos",
+ "optional_block_pos",
+ "direction",
"optional_uuid",
"optional_block_state",
- "nbt",
+ "compound_tag",
"particle",
"villager_data",
- "optional_int",
- "entity_pose",
- "cat_variant_type",
- "frog_variant_type",
- "optional_global_position",
- "painting_variant_type"
+ "optional_unsigned_int",
+ "pose",
+ "cat_variant",
+ "frog_variant",
+ "optional_global_pos",
+ "painting_variant"
],
"V_1_14": [
"byte",
@@ -120,19 +120,19 @@
"string",
"component",
"optional_component",
- "itemstack",
+ "item_stack",
"boolean",
- "rotation",
- "block_position",
- "optional_block_position",
- "block_face",
+ "rotations",
+ "block_pos",
+ "optional_block_pos",
+ "direction",
"optional_uuid",
"optional_block_state",
- "nbt",
+ "compound_tag",
"particle",
"villager_data",
- "optional_int",
- "entity_pose"
+ "optional_unsigned_int",
+ "pose"
],
"V_1_13": [
"byte",
@@ -141,15 +141,15 @@
"string",
"component",
"optional_component",
- "itemstack",
+ "item_stack",
"boolean",
- "rotation",
- "block_position",
- "optional_block_position",
- "block_face",
+ "rotations",
+ "block_pos",
+ "optional_block_pos",
+ "direction",
"optional_uuid",
"optional_block_state",
- "nbt",
+ "compound_tag",
"particle"
],
"V_1_11": [
@@ -158,15 +158,15 @@
"float",
"string",
"component",
- "itemstack",
+ "item_stack",
"boolean",
- "rotation",
- "block_position",
- "optional_block_position",
- "block_face",
+ "rotations",
+ "block_pos",
+ "optional_block_pos",
+ "direction",
"optional_uuid",
"optional_block_state",
- "nbt"
+ "compound_tag"
],
"V_1_9": [
"byte",
@@ -174,12 +174,12 @@
"float",
"string",
"component",
- "optional_itemstack",
+ "item_stack",
"boolean",
- "rotation",
- "block_position",
- "optional_block_position",
- "block_face",
+ "rotations",
+ "block_pos",
+ "optional_block_pos",
+ "direction",
"optional_uuid",
"optional_block_state"
],
@@ -189,8 +189,8 @@
"int",
"float",
"string",
- "itemstack",
- "block_position",
- "rotation"
+ "item_stack",
+ "block_pos",
+ "rotations"
]
}
diff --git a/mappings/entity/frog_variant_mappings.json b/mappings/entity/frog_variant_mappings.json
new file mode 100644
index 0000000000..d67f13e598
--- /dev/null
+++ b/mappings/entity/frog_variant_mappings.json
@@ -0,0 +1,7 @@
+{
+ "V_1_19": [
+ "temperate",
+ "warm",
+ "cold"
+ ]
+}