Merge branch '2.0' into feat/1.21.5-support
This commit is contained in:
190 files changed
+2136213
-2135450
No files matched your search
+13
-66
@@ -1,6 +1,6 @@
|
||||
import com.github.retrooper.compression.strategy.JsonArrayCompressionStrategy
|
||||
import com.github.retrooper.compression.strategy.JsonObjectCompressionStrategy
|
||||
import com.github.retrooper.compression.strategy.JsonToNbtStrategy
|
||||
import com.github.retrooper.compression.strategy.dir.JsonBase64DataDirStrategy
|
||||
import com.github.retrooper.compression.strategy.dir.JsonRegistryCompressionDirStrategy
|
||||
import com.github.retrooper.compression.strategy.dir.JsonToNbtDirStrategy
|
||||
import com.github.retrooper.excludeAdventure
|
||||
|
||||
plugins {
|
||||
@@ -39,76 +39,21 @@ dependencies {
|
||||
testImplementation(testlibs.slf4j)
|
||||
testImplementation(testlibs.bundles.junit)
|
||||
testImplementation(libs.netty)
|
||||
testImplementation(libs.classgraph)
|
||||
}
|
||||
|
||||
mappingCompression {
|
||||
mappingDirectory = rootDir.resolve("mappings")
|
||||
outDirectory = project.layout.buildDirectory.dir("mappings/generated/assets/mappings")
|
||||
|
||||
with<JsonToNbtStrategy> {
|
||||
compress("block/legacy_block_mappings.json")
|
||||
compress("block/modern_block_mappings.json")
|
||||
|
||||
compress("enchantment/enchantment_type_data.json")
|
||||
|
||||
compress("item/item_base_components.json")
|
||||
|
||||
compress("stats/statistics.json")
|
||||
|
||||
compress("world/biome_data.json")
|
||||
with<JsonToNbtDirStrategy> {
|
||||
compress("data")
|
||||
}
|
||||
|
||||
with<JsonArrayCompressionStrategy> {
|
||||
compress("attribute/attribute_mappings.json")
|
||||
|
||||
compress("block/block_entity_type_mappings.json")
|
||||
compress("block/block_type_mappings.json")
|
||||
|
||||
compress("chat/chat_type_mappings.json")
|
||||
|
||||
compress("command/argument_parser_mappings.json")
|
||||
|
||||
compress("damage/damagetype_mappings.json")
|
||||
|
||||
compress("enchantment/effect_component_type.json")
|
||||
|
||||
compress("entity/entity_data_type_mappings.json")
|
||||
compress("entity/painting_mappings.json")
|
||||
compress("entity/wolf_variant_mappings.json")
|
||||
|
||||
compress("item/consume_effect_type_mappings.json")
|
||||
compress("item/equipment_asset_mappings.json")
|
||||
compress("item/item_banner_pattern_mappings.json")
|
||||
compress("item/item_component_mappings.json")
|
||||
compress("item/item_instrument_mappings.json")
|
||||
compress("item/item_jukebox_song_mappings.json")
|
||||
compress("item/item_map_decoration_type_mappings.json")
|
||||
compress("item/item_potion_mappings.json")
|
||||
compress("item/item_trim_material_mappings.json")
|
||||
compress("item/item_trim_pattern_mappings.json")
|
||||
compress("item/recipe_book_category.json")
|
||||
compress("item/recipe_display_types.json")
|
||||
compress("item/recipe_serializer_mappings.json")
|
||||
compress("item/recipe_slot_display_types.json")
|
||||
|
||||
compress("particle/particle_type_mappings.json")
|
||||
|
||||
compress("sound/sound_mappings.json")
|
||||
|
||||
compress("world/biome_mappings.json")
|
||||
compress("world/world_position_source_mappings.json")
|
||||
with<JsonBase64DataDirStrategy> {
|
||||
compress("item_base_components")
|
||||
}
|
||||
|
||||
with<JsonObjectCompressionStrategy> {
|
||||
compress("enchantment/enchantment_type_mappings.json")
|
||||
|
||||
compress("entity/entity_effect_mappings.json")
|
||||
compress("entity/entity_type_mappings.json")
|
||||
compress("entity/legacy_entity_type_mappings.json")
|
||||
|
||||
compress("item/item_type_mappings.json")
|
||||
|
||||
compress("world/dimension_type_mappings.json")
|
||||
with<JsonRegistryCompressionDirStrategy> {
|
||||
compress("registries")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +90,9 @@ tasks {
|
||||
shadowJar {
|
||||
exclude {
|
||||
val path = it.path
|
||||
path.startsWith("net/kyori") && !path.startsWith("net/kyori/adventure/text/serializer") && !path.startsWith("net/kyori/option")
|
||||
path.startsWith("net/kyori") && !path.startsWith("net/kyori/adventure/text/serializer") && !path.startsWith(
|
||||
"net/kyori/option"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -31,4 +31,6 @@ public interface ByteBufAllocationOperator {
|
||||
|
||||
Object compositeBuffer();
|
||||
Object compositeBuffer(int maxNumComponents);
|
||||
|
||||
Object emptyBuffer();
|
||||
}
|
||||
+4
@@ -52,4 +52,8 @@ public class UnpooledByteBufAllocationHelper {
|
||||
public static Object compositeBuffer(int maxNumComponents) {
|
||||
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().compositeBuffer(maxNumComponents);
|
||||
}
|
||||
|
||||
public static Object emptyBuffer() {
|
||||
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().emptyBuffer();
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -26,8 +26,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class Attributes {
|
||||
|
||||
private static final VersionedRegistry<Attribute> REGISTRY = new VersionedRegistry<>(
|
||||
"attribute", "attribute/attribute_mappings");
|
||||
private static final VersionedRegistry<Attribute> REGISTRY = new VersionedRegistry<>("attribute");
|
||||
|
||||
private Attributes() {
|
||||
}
|
||||
|
||||
+8
-4
@@ -22,6 +22,7 @@ import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticAttribute extends AbstractMappedEntity implements Attribute {
|
||||
@@ -31,21 +32,24 @@ public class StaticAttribute extends AbstractMappedEntity implements Attribute {
|
||||
private final double minValue;
|
||||
private final double maxValue;
|
||||
|
||||
StaticAttribute(
|
||||
TypesBuilderData data, String legacyPrefix,
|
||||
@ApiStatus.Internal
|
||||
public StaticAttribute(
|
||||
@Nullable TypesBuilderData data, String legacyPrefix,
|
||||
double defaultValue, double minValue, double maxValue
|
||||
) {
|
||||
super(data);
|
||||
this.defaultValue = defaultValue;
|
||||
this.minValue = minValue;
|
||||
this.maxValue = maxValue;
|
||||
this.legacyName = legacyPrefix == null ? null : new ResourceLocation(
|
||||
this.legacyName = legacyPrefix == null || data == null ? null : new ResourceLocation(
|
||||
data.getName().getNamespace(), legacyPrefix + "." + data.getName().getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName(ClientVersion version) {
|
||||
assert this.data != null; // not marked as nullable in ctor
|
||||
if (this.data == null) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
return version.isNewerThanOrEquals(ClientVersion.V_1_21_2) || this.legacyName == null
|
||||
? this.data.getName() : this.legacyName;
|
||||
}
|
||||
|
||||
@@ -31,8 +31,7 @@ import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration
|
||||
|
||||
public final class ChatTypes {
|
||||
|
||||
private static final VersionedRegistry<ChatType> REGISTRY = new VersionedRegistry<>(
|
||||
"chat_type", "chat/chat_type_mappings");
|
||||
private static final VersionedRegistry<ChatType> REGISTRY = new VersionedRegistry<>("chat_type");
|
||||
|
||||
private ChatTypes() {
|
||||
}
|
||||
|
||||
@@ -19,58 +19,54 @@
|
||||
package com.github.retrooper.packetevents.protocol.chat;
|
||||
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
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 org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Parsers {
|
||||
public final class Parsers {
|
||||
|
||||
private static final List<Parser> ALL_PARSERS = new ArrayList<>(); // support for old methods
|
||||
private static final Map<String, Parser> PARSER_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, Parser>> PARSER_ID_MAP = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("command/argument_parser_mappings");
|
||||
private static final VersionedRegistry<Parser> REGISTRY = new VersionedRegistry<>("argument_type");
|
||||
|
||||
private Parsers() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static Parser define(String key) {
|
||||
return define(key, null, null);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static Parser define(String key, @Nullable Reader reader, @Nullable Writer writer) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
Parser parser = new Parser(data, reader, writer);
|
||||
|
||||
ALL_PARSERS.add(parser);
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, PARSER_MAP, PARSER_ID_MAP, parser);
|
||||
return parser;
|
||||
return REGISTRY.define(key, data -> new Parser(data, reader, writer));
|
||||
}
|
||||
|
||||
// with key
|
||||
public static Parser getByName(String name) {
|
||||
return PARSER_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static Parser getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, Parser> idMap = PARSER_ID_MAP.get((byte) index);
|
||||
return idMap.get(id);
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static List<Parser> getParsers() {
|
||||
return Collections.unmodifiableList(ALL_PARSERS);
|
||||
return new ArrayList<>(REGISTRY.getEntries());
|
||||
}
|
||||
|
||||
public static VersionedRegistry<Parser> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
public static final Parser BRIGADIER_BOOL = define("brigadier:bool", null, null);
|
||||
@@ -223,7 +219,7 @@ public class Parsers {
|
||||
);
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
@@ -232,9 +228,8 @@ public class Parsers {
|
||||
@FunctionalInterface
|
||||
public interface Writer extends BiConsumer<PacketWrapper<?>, List<Object>> {}
|
||||
|
||||
public static final class Parser implements MappedEntity {
|
||||
public static final class Parser extends AbstractMappedEntity {
|
||||
|
||||
private final TypesBuilderData data;
|
||||
private final Reader reader;
|
||||
private final Writer writer;
|
||||
|
||||
@@ -247,8 +242,9 @@ public class Parsers {
|
||||
);
|
||||
}
|
||||
|
||||
private Parser(TypesBuilderData data, @Nullable Reader reader, Writer writer) {
|
||||
this.data = data;
|
||||
@ApiStatus.Internal
|
||||
public Parser(@Nullable TypesBuilderData data, @Nullable Reader reader, @Nullable Writer writer) {
|
||||
super(data);
|
||||
this.reader = reader;
|
||||
this.writer = writer;
|
||||
}
|
||||
@@ -265,24 +261,5 @@ public class Parsers {
|
||||
this.writer.accept(wrapper, properties);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return this.data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
return this.data.getData()[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Parser) {
|
||||
return this.getName().equals(((Parser) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ package com.github.retrooper.packetevents.protocol.chat;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.UnknownNullability;
|
||||
|
||||
@@ -39,6 +40,7 @@ public class StaticChatType extends AbstractMappedEntity implements ChatType {
|
||||
this(null, chatDecoration, null, narrationDecoration, null);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticChatType(
|
||||
@Nullable TypesBuilderData data,
|
||||
ChatTypeDecoration chatDecoration,
|
||||
@@ -56,6 +58,7 @@ public class StaticChatType extends AbstractMappedEntity implements ChatType {
|
||||
this(null, chatDecoration, overlayDecoration, narrationDecoration, narrationPriority);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticChatType(
|
||||
@Nullable TypesBuilderData data,
|
||||
@UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration,
|
||||
|
||||
+1
-2
@@ -84,8 +84,7 @@ import java.util.Collection;
|
||||
*/
|
||||
public final class ComponentTypes {
|
||||
|
||||
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>(
|
||||
"data_component_type", "item/item_component_mappings");
|
||||
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>("data_component_type");
|
||||
|
||||
private ComponentTypes() {
|
||||
}
|
||||
|
||||
+1
-2
@@ -32,8 +32,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public final class EnchantEffectComponentTypes {
|
||||
|
||||
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>(
|
||||
"enchantment_effect_component_type", "enchantment/effect_component_type");
|
||||
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>("enchantment_effect_component_type");
|
||||
|
||||
private EnchantEffectComponentTypes() {
|
||||
}
|
||||
|
||||
+4
@@ -25,6 +25,7 @@ import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
@@ -36,6 +37,7 @@ public class StaticComponentType<T> extends AbstractMappedEntity implements Comp
|
||||
private final @Nullable Decoder<T> decoder;
|
||||
private final @Nullable Encoder<T> encoder;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticComponentType(
|
||||
@Nullable TypesBuilderData data,
|
||||
@Nullable Reader<T> reader,
|
||||
@@ -44,6 +46,7 @@ public class StaticComponentType<T> extends AbstractMappedEntity implements Comp
|
||||
this(data, reader, writer, null, null);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticComponentType(
|
||||
@Nullable TypesBuilderData data,
|
||||
@Nullable Decoder<T> decoder,
|
||||
@@ -52,6 +55,7 @@ public class StaticComponentType<T> extends AbstractMappedEntity implements Comp
|
||||
this(data, null, null, decoder, encoder);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticComponentType(
|
||||
@Nullable TypesBuilderData data,
|
||||
@Nullable Reader<T> reader,
|
||||
|
||||
+26
-19
@@ -18,39 +18,46 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.data;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class EntityDataType<T> {
|
||||
private final String name;
|
||||
private final int[] ids;
|
||||
private final Function<PacketWrapper<?>, T> dataDeserializer;
|
||||
private final BiConsumer<PacketWrapper<?>, Object> dataSerializer;
|
||||
public class EntityDataType<T> extends AbstractMappedEntity {
|
||||
|
||||
public EntityDataType(String name, int[] ids, Function<PacketWrapper<?>, T> dataDeserializer, BiConsumer<PacketWrapper<?>, Object> dataSerializer) {
|
||||
this.name = name;
|
||||
this.ids = ids;
|
||||
this.dataDeserializer = dataDeserializer;
|
||||
this.dataSerializer = dataSerializer;
|
||||
private final PacketWrapper.Reader<? extends T> reader;
|
||||
private final PacketWrapper.Writer<T> writer;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public EntityDataType(
|
||||
@Nullable TypesBuilderData data,
|
||||
PacketWrapper.Reader<? extends T> reader,
|
||||
PacketWrapper.Writer<T> writer
|
||||
) {
|
||||
super(data);
|
||||
this.reader = reader;
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
public T read(PacketWrapper<?> wrapper) {
|
||||
return this.reader.apply(wrapper);
|
||||
}
|
||||
|
||||
public int getId(ClientVersion version) {
|
||||
int index = EntityDataTypes.TYPES_BUILDER.getDataIndex(version);
|
||||
return ids[index];
|
||||
public void write(PacketWrapper<?> wrapper, T serializer) {
|
||||
this.writer.accept(wrapper, serializer);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Function<PacketWrapper<?>, T> getDataDeserializer() {
|
||||
return dataDeserializer;
|
||||
return this.reader::apply;
|
||||
}
|
||||
|
||||
public BiConsumer<PacketWrapper<?>, Object> getDataSerializer() {
|
||||
return dataSerializer;
|
||||
@Deprecated
|
||||
public BiConsumer<PacketWrapper<?>, T> getDataSerializer() {
|
||||
return this.writer;
|
||||
}
|
||||
}
|
||||
+66
-144
@@ -18,7 +18,6 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.data;
|
||||
|
||||
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.pose.EntityPose;
|
||||
@@ -34,27 +33,23 @@ import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
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 org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
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
|
||||
public final class EntityDataTypes {
|
||||
|
||||
private static final Map<String, EntityDataType<?>> ENTITY_DATA_TYPE_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, EntityDataType<?>>> ENTITY_DATA_TYPE_ID_MAP = new HashMap<>();
|
||||
protected static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_data_type_mappings");
|
||||
private static final VersionedRegistry<EntityDataType<?>> REGISTRY = new VersionedRegistry<>("entity_data_serializer");
|
||||
|
||||
public static final EntityDataType<Byte> BYTE = define("byte", PacketWrapper::readByte, PacketWrapper::writeByte);
|
||||
|
||||
// short was removed in 1.9+
|
||||
public static final EntityDataType<Short> SHORT = define("short", PacketWrapper::readShort, PacketWrapper::writeShort);
|
||||
|
||||
public static final EntityDataType<Integer> INT = define("int", wrapper -> {
|
||||
@@ -91,6 +86,7 @@ public class EntityDataTypes {
|
||||
(PacketWrapper<?> wrapper) -> Optional.of(wrapper.readItemStack()),
|
||||
(PacketWrapper<?> wrapper, Optional<ItemStack> value) -> wrapper.writeItemStack(value.orElse(null)));
|
||||
|
||||
// boolean was added in 1.9
|
||||
public static final EntityDataType<Boolean> BOOLEAN = define("boolean", PacketWrapper::readBoolean, PacketWrapper::writeBoolean);
|
||||
|
||||
public static final EntityDataType<Vector3f> ROTATION = define("rotation",
|
||||
@@ -101,6 +97,7 @@ public class EntityDataTypes {
|
||||
wrapper.writeFloat(value.z);
|
||||
});
|
||||
|
||||
// 1.7 -> 1.18 block_position is just 3 ints, not serialized with a long
|
||||
public static final EntityDataType<Vector3i> BLOCK_POSITION = define("block_position", (PacketWrapper<?> wrapper) -> {
|
||||
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
|
||||
return wrapper.readBlockPosition();
|
||||
@@ -139,6 +136,7 @@ public class EntityDataTypes {
|
||||
|
||||
public static final EntityDataType<Integer> OPTIONAL_BLOCK_STATE = define("optional_block_state", readIntDeserializer(), writeIntSerializer());
|
||||
|
||||
// nbt was added in 1.12
|
||||
public static final EntityDataType<NBTCompound> NBT = define("nbt", PacketWrapper::readNBT, PacketWrapper::writeNBT);
|
||||
|
||||
public static final EntityDataType<Particle<?>> PARTICLE = define("particle", Particle::read, Particle::write);
|
||||
@@ -206,171 +204,95 @@ public class EntityDataTypes {
|
||||
public static final EntityDataType<Integer> WOLF_VARIANT =
|
||||
define("wolf_variant_type", readIntDeserializer(), writeIntSerializer());
|
||||
|
||||
private EntityDataTypes() {
|
||||
}
|
||||
|
||||
public static VersionedRegistry<EntityDataType<?>> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the entity-data types.
|
||||
*
|
||||
* @return Entity-Data Types
|
||||
*/
|
||||
public static Collection<EntityDataType<?>> values() {
|
||||
return Collections.unmodifiableCollection(ENTITY_DATA_TYPE_MAP.values());
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
public static EntityDataType<?> getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, EntityDataType<?>> typeIdMap = ENTITY_DATA_TYPE_ID_MAP.get((byte) index);
|
||||
return typeIdMap.get(id);
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static EntityDataType<?> getByName(String name) {
|
||||
return ENTITY_DATA_TYPE_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static <T> EntityDataType<T> define(String name, Function<PacketWrapper<?>, T> deserializer, BiConsumer<PacketWrapper<?>, T> serializer) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(name);
|
||||
EntityDataType<T> type = new EntityDataType<>(name, data.getData(), deserializer,
|
||||
(BiConsumer<PacketWrapper<?>, 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<Integer, EntityDataType<?>> typeIdMap = ENTITY_DATA_TYPE_ID_MAP
|
||||
.computeIfAbsent((byte) index, k -> new HashMap<>());
|
||||
typeIdMap.put(type.getId(version), type);
|
||||
}
|
||||
return type;
|
||||
@ApiStatus.Internal
|
||||
public static <T, Z extends T> EntityDataType<Z> define(
|
||||
String name, PacketWrapper.Reader<Z> reader, PacketWrapper.Writer<T> writer
|
||||
) {
|
||||
return REGISTRY.define(name, data -> new EntityDataType<>(data, reader, writer::accept));
|
||||
}
|
||||
|
||||
private static <T> Function<PacketWrapper<?>, 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());
|
||||
}
|
||||
private static PacketWrapper.Reader<Integer> readIntDeserializer() {
|
||||
return wrapper -> wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9) ?
|
||||
wrapper.readVarInt() : wrapper.readInt();
|
||||
}
|
||||
|
||||
private static <T> BiConsumer<PacketWrapper<?>, 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);
|
||||
private static PacketWrapper.Writer<Number> writeIntSerializer() {
|
||||
return (wrapper, value) -> {
|
||||
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
|
||||
wrapper.writeVarInt(value.intValue());
|
||||
} else {
|
||||
wrapper.writeInt(output);
|
||||
wrapper.writeInt(value.intValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private static Function<PacketWrapper<?>, Optional<String>> readOptionalComponentJSONDeserializer() {
|
||||
return (PacketWrapper<?> wrapper) -> {
|
||||
if (wrapper.readBoolean()) {
|
||||
return Optional.of(wrapper.readComponentJSON());
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
private static PacketWrapper.Reader<Optional<String>> readOptionalComponentJSONDeserializer() {
|
||||
return wrapper -> wrapper.readJavaOptional(PacketWrapper::readComponentJSON);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private static BiConsumer<PacketWrapper<?>, Optional<String>> writeOptionalComponentJSONSerializer() {
|
||||
return (PacketWrapper<?> wrapper, Optional<String> value) -> {
|
||||
if (value != null && value.isPresent()) {
|
||||
wrapper.writeBoolean(true);
|
||||
wrapper.writeComponentJSON(value.get());
|
||||
} else {
|
||||
wrapper.writeBoolean(false);
|
||||
private static PacketWrapper.Writer<Optional<String>> writeOptionalComponentJSONSerializer() {
|
||||
return (wrapper, value) -> wrapper.writeJavaOptional(value, PacketWrapper::writeComponentJSON);
|
||||
}
|
||||
|
||||
private static PacketWrapper.Reader<Optional<Component>> readOptionalComponentDeserializer() {
|
||||
return wrapper -> wrapper.readJavaOptional(PacketWrapper::readComponent);
|
||||
}
|
||||
|
||||
private static PacketWrapper.Writer<Optional<Component>> writeOptionalComponentSerializer() {
|
||||
return (wrapper, value) -> wrapper.writeJavaOptional(value, PacketWrapper::writeComponent);
|
||||
}
|
||||
|
||||
private static PacketWrapper.Reader<Optional<Vector3i>> readOptionalBlockPositionDeserializer() {
|
||||
return wrapper -> {
|
||||
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
|
||||
return wrapper.readJavaOptional(PacketWrapper::readBlockPosition);
|
||||
}
|
||||
return wrapper.readJavaOptional(ew ->
|
||||
new Vector3i(ew.readInt(), ew.readInt(), ew.readInt()));
|
||||
};
|
||||
}
|
||||
|
||||
private static Function<PacketWrapper<?>, Optional<Component>> readOptionalComponentDeserializer() {
|
||||
return (PacketWrapper<?> wrapper) -> {
|
||||
if (wrapper.readBoolean()) {
|
||||
return Optional.of(wrapper.readComponent());
|
||||
private static PacketWrapper.Writer<Optional<Vector3i>> writeOptionalBlockPositionSerializer() {
|
||||
return (wrapper, value) -> {
|
||||
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
|
||||
wrapper.writeJavaOptional(value, PacketWrapper::writeBlockPosition);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
wrapper.writeJavaOptional(value, (ew, valuee) -> {
|
||||
wrapper.writeInt(valuee.getX());
|
||||
wrapper.writeInt(valuee.getY());
|
||||
wrapper.writeInt(valuee.getZ());
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static BiConsumer<PacketWrapper<?>, Optional<Component>> writeOptionalComponentSerializer() {
|
||||
return (PacketWrapper<?> wrapper, Optional<Component> value) -> {
|
||||
if (value != null && value.isPresent()) {
|
||||
wrapper.writeBoolean(true);
|
||||
wrapper.writeComponent(value.get());
|
||||
} else {
|
||||
wrapper.writeBoolean(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static <T> Function<PacketWrapper<?>, 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();
|
||||
}
|
||||
};
|
||||
} 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();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> BiConsumer<PacketWrapper<?>, 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);
|
||||
}
|
||||
};
|
||||
} 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
|
||||
}
|
||||
+3
@@ -24,5 +24,8 @@ import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface EntityType extends MappedEntity, LegacyMappedEntity {
|
||||
|
||||
boolean isInstanceOf(EntityType parent);
|
||||
|
||||
Optional<EntityType> getParent();
|
||||
}
|
||||
+26
-77
@@ -19,105 +19,54 @@
|
||||
package com.github.retrooper.packetevents.protocol.entity.type;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
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 org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class EntityTypes {
|
||||
private static final Map<String, EntityType> ENTITY_TYPE_MAP = new HashMap<>();
|
||||
//Key - mappings version, value - map with entity type ids and entity types
|
||||
private static final Map<Byte, Map<Integer, EntityType>> ENTITY_TYPE_ID_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, EntityType>> LEGACY_ENTITY_TYPE_ID_MAP = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_type_mappings");
|
||||
private static final TypesBuilder LEGACY_TYPES_BUILDER = new TypesBuilder("entity/legacy_entity_type_mappings");
|
||||
public final class EntityTypes {
|
||||
|
||||
public static EntityType define(String key, @Nullable EntityType parent) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
TypesBuilderData legacyData = LEGACY_TYPES_BUILDER.define(key);
|
||||
Optional<EntityType> optParent = Optional.ofNullable(parent);
|
||||
EntityType entityType = new EntityType() {
|
||||
private final int[] ids = data.getData();
|
||||
private final int[] legacyIds = legacyData.getData();
|
||||
private static final VersionedRegistry<EntityType> REGISTRY = new VersionedRegistry<>("entity_type");
|
||||
private static final VersionedRegistry<EntityType> LEGACY_SPAWN_REGISTRY = new VersionedRegistry<>("legacy_spawn_entity_type");
|
||||
|
||||
@Override
|
||||
public Optional<EntityType> getParent() {
|
||||
return optParent;
|
||||
}
|
||||
private EntityTypes() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLegacyId(ClientVersion version) {
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_14)) {
|
||||
return -1;
|
||||
}
|
||||
int index = LEGACY_TYPES_BUILDER.getDataIndex(version);
|
||||
return legacyIds[index];
|
||||
}
|
||||
public static VersionedRegistry<EntityType> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
@ApiStatus.Obsolete
|
||||
public static VersionedRegistry<EntityType> getLegacySpawnRegistry() {
|
||||
return LEGACY_SPAWN_REGISTRY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
return ids[index];
|
||||
}
|
||||
};
|
||||
ENTITY_TYPE_MAP.put(entityType.getName().toString(), entityType);
|
||||
for (ClientVersion version : TYPES_BUILDER.getVersions()) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, EntityType> typeIdMap = ENTITY_TYPE_ID_MAP.computeIfAbsent((byte) index, k -> new HashMap<>());
|
||||
typeIdMap.put(entityType.getId(version), entityType);
|
||||
}
|
||||
|
||||
for (ClientVersion version : LEGACY_TYPES_BUILDER.getVersions()) {
|
||||
int index = LEGACY_TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, EntityType> legacyTypeIdMap = LEGACY_ENTITY_TYPE_ID_MAP.computeIfAbsent((byte) index, k -> new HashMap<>());
|
||||
legacyTypeIdMap.put(entityType.getLegacyId(version), entityType);
|
||||
}
|
||||
|
||||
return entityType;
|
||||
@ApiStatus.Internal
|
||||
public static EntityType define(String name, @Nullable EntityType parent) {
|
||||
StaticEntityType type = REGISTRY.define(name, data ->
|
||||
new StaticEntityType(data, parent));
|
||||
return LEGACY_SPAWN_REGISTRY.define(name, type::setLegacyData);
|
||||
}
|
||||
|
||||
public static boolean isTypeInstanceOf(EntityType type, EntityType parent) {
|
||||
while (type != null) {
|
||||
if (type == parent) {
|
||||
return true;
|
||||
}
|
||||
if (type.getParent().isPresent()) {
|
||||
type = type.getParent().get();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return type != null && type.isInstanceOf(parent);
|
||||
}
|
||||
|
||||
//with minecraft:key
|
||||
public static EntityType getByName(String name) {
|
||||
return ENTITY_TYPE_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static EntityType getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
return ENTITY_TYPE_ID_MAP.get((byte) index).get(id);
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
@ApiStatus.Obsolete
|
||||
public static EntityType getByLegacyId(ClientVersion version, int id) {
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_14)) {
|
||||
return null;
|
||||
}
|
||||
int index = LEGACY_TYPES_BUILDER.getDataIndex(version);
|
||||
return LEGACY_ENTITY_TYPE_ID_MAP.get((byte) index).get(id);
|
||||
return LEGACY_SPAWN_REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
// Credit to ViaVersion for these categories
|
||||
@@ -340,11 +289,11 @@ public class EntityTypes {
|
||||
* @return Entity Types
|
||||
*/
|
||||
public static Collection<EntityType> values() {
|
||||
return Collections.unmodifiableCollection(ENTITY_TYPE_MAP.values());
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
LEGACY_TYPES_BUILDER.unloadFileMappings();
|
||||
REGISTRY.unloadMappings();
|
||||
LEGACY_SPAWN_REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.type;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class StaticEntityType extends AbstractMappedEntity implements EntityType {
|
||||
|
||||
private final Optional<EntityType> parent;
|
||||
private final Map<EntityType, Boolean> parents;
|
||||
|
||||
private @Nullable TypesBuilderData legacyData;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticEntityType(@Nullable TypesBuilderData data, @Nullable EntityType parent) {
|
||||
super(data);
|
||||
this.parent = Optional.ofNullable(parent);
|
||||
|
||||
// iterate through all parents and save them for faster access
|
||||
this.parents = new IdentityHashMap<>();
|
||||
this.parents.put(this, true);
|
||||
while (parent != null) {
|
||||
this.parents.put(parent, true);
|
||||
parent = parent.getParent().orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
StaticEntityType setLegacyData(@Nullable TypesBuilderData legacyData) {
|
||||
this.legacyData = legacyData;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInstanceOf(EntityType parent) {
|
||||
return parent != null && this.parents.containsKey(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<EntityType> getParent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLegacyId(ClientVersion version) {
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_14)) {
|
||||
return -1;
|
||||
} else if (this.legacyData != null) {
|
||||
return this.legacyData.getId(version);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
+1
@@ -41,6 +41,7 @@ public class VillagerData {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public VillagerData(int typeId, int professionId, int level) {
|
||||
this(VillagerTypes.getById(typeId), VillagerProfessions.getById(professionId), level);
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.villager.profession;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticVillagerProfession extends AbstractMappedEntity implements VillagerProfession {
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticVillagerProfession(@Nullable TypesBuilderData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
|
||||
return this.getId(version.toClientVersion());
|
||||
}
|
||||
}
|
||||
+3
@@ -22,4 +22,7 @@ import com.github.retrooper.packetevents.protocol.mapper.StaticMappedEntity;
|
||||
|
||||
public interface VillagerProfession extends StaticMappedEntity {
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
int getId();
|
||||
}
|
||||
+50
-39
@@ -18,54 +18,65 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.villager.profession;
|
||||
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
public final class VillagerProfessions {
|
||||
|
||||
public class VillagerProfessions {
|
||||
private static final Map<String, VillagerProfession> VILLAGER_PROFESSION_MAP = new HashMap<>();
|
||||
private static final Map<Byte, VillagerProfession> VILLAGER_PROFESSION_ID_MAP = new HashMap<>();
|
||||
private static final VersionedRegistry<VillagerProfession> REGISTRY = new VersionedRegistry<>("villager_profession");
|
||||
|
||||
public static VillagerProfession define(int id, String name) {
|
||||
ResourceLocation location = new ResourceLocation(name);
|
||||
VillagerProfession type = new VillagerProfession() {
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
};
|
||||
VILLAGER_PROFESSION_MAP.put(type.getName().toString(), type);
|
||||
VILLAGER_PROFESSION_ID_MAP.put((byte) type.getId(), type);
|
||||
return type;
|
||||
private VillagerProfessions() {
|
||||
}
|
||||
|
||||
public static VersionedRegistry<VillagerProfession> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.Internal
|
||||
public static VillagerProfession define(int id, String name) {
|
||||
return define(name);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static VillagerProfession define(String name) {
|
||||
return REGISTRY.define(name, StaticVillagerProfession::new);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static VillagerProfession getById(int id) {
|
||||
return VILLAGER_PROFESSION_ID_MAP.get((byte)id);
|
||||
ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
|
||||
return getById(version.toClientVersion(), id);
|
||||
}
|
||||
|
||||
public static VillagerProfession getById(ClientVersion version, int id) {
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static VillagerProfession getByName(String name) {
|
||||
return VILLAGER_PROFESSION_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static final VillagerProfession NONE = define(0, "minecraft:none");
|
||||
public static final VillagerProfession ARMORER = define(1, "minecraft:armorer");
|
||||
public static final VillagerProfession BUTCHER = define(2, "minecraft:butcher");
|
||||
public static final VillagerProfession CARTOGRAPHER = define(3, "minecraft:cartographer");
|
||||
public static final VillagerProfession CLERIC = define(4, "minecraft:cleric");
|
||||
public static final VillagerProfession FARMER = define(5, "minecraft:farmer");
|
||||
public static final VillagerProfession FISHERMAN = define(6, "minecraft:fisherman");
|
||||
public static final VillagerProfession FLETCHER = define(7, "minecraft:fletcher");
|
||||
public static final VillagerProfession LEATHERWORKER = define(8, "minecraft:leatherworker");
|
||||
public static final VillagerProfession LIBRARIAN = define(9, "minecraft:librarian");
|
||||
public static final VillagerProfession MASON = define(10, "minecraft:mason");
|
||||
public static final VillagerProfession NITWIT = define(11, "minecraft:nitwit");
|
||||
public static final VillagerProfession SHEPHERD = define(12, "minecraft:shepherd");
|
||||
public static final VillagerProfession TOOLSMITH = define(13, "minecraft:toolsmith");
|
||||
public static final VillagerProfession WEAPONSMITH = define(14, "minecraft:weaponsmith");
|
||||
public static final VillagerProfession NONE = define("none");
|
||||
public static final VillagerProfession ARMORER = define("armorer");
|
||||
public static final VillagerProfession BUTCHER = define("butcher");
|
||||
public static final VillagerProfession CARTOGRAPHER = define("cartographer");
|
||||
public static final VillagerProfession CLERIC = define("cleric");
|
||||
public static final VillagerProfession FARMER = define("farmer");
|
||||
public static final VillagerProfession FISHERMAN = define("fisherman");
|
||||
public static final VillagerProfession FLETCHER = define("fletcher");
|
||||
public static final VillagerProfession LEATHERWORKER = define("leatherworker");
|
||||
public static final VillagerProfession LIBRARIAN = define("librarian");
|
||||
public static final VillagerProfession MASON = define("mason");
|
||||
public static final VillagerProfession NITWIT = define("nitwit");
|
||||
public static final VillagerProfession SHEPHERD = define("shepherd");
|
||||
public static final VillagerProfession TOOLSMITH = define("toolsmith");
|
||||
public static final VillagerProfession WEAPONSMITH = define("weaponsmith");
|
||||
|
||||
static {
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.villager.type;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticVillagerType extends AbstractMappedEntity implements VillagerType {
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticVillagerType(@Nullable TypesBuilderData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
|
||||
return this.getId(version.toClientVersion());
|
||||
}
|
||||
}
|
||||
+3
@@ -22,4 +22,7 @@ import com.github.retrooper.packetevents.protocol.mapper.StaticMappedEntity;
|
||||
|
||||
public interface VillagerType extends StaticMappedEntity {
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
int getId();
|
||||
}
|
||||
+42
-32
@@ -18,58 +18,68 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.villager.type;
|
||||
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class VillagerTypes {
|
||||
private static final Map<String, VillagerType> VILLAGER_TYPE_MAP = new HashMap<>();
|
||||
private static final Map<Byte, VillagerType> VILLAGER_TYPE_ID_MAP = new HashMap<>();
|
||||
public final class VillagerTypes {
|
||||
|
||||
private static final VersionedRegistry<VillagerType> REGISTRY = new VersionedRegistry<>("villager_type");
|
||||
|
||||
private VillagerTypes() {
|
||||
}
|
||||
|
||||
public static VersionedRegistry<VillagerType> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.Internal
|
||||
public static VillagerType define(int id, String name) {
|
||||
ResourceLocation location = new ResourceLocation(name);
|
||||
VillagerType type = new VillagerType() {
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
};
|
||||
VILLAGER_TYPE_MAP.put(type.getName().toString(), type);
|
||||
VILLAGER_TYPE_ID_MAP.put((byte)type.getId(), type);
|
||||
return type;
|
||||
return define(name);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static VillagerType define(String name) {
|
||||
return REGISTRY.define(name, StaticVillagerType::new);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static VillagerType getById(int id) {
|
||||
return VILLAGER_TYPE_ID_MAP.get((byte)id);
|
||||
ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
|
||||
return getById(version.toClientVersion(), id);
|
||||
}
|
||||
|
||||
public static VillagerType getById(ClientVersion version, int id) {
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static VillagerType getByName(String name) {
|
||||
return VILLAGER_TYPE_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static final VillagerType DESERT = define(0, "minecraft:desert");
|
||||
public static final VillagerType JUNGLE = define(1, "minecraft:jungle");
|
||||
public static final VillagerType PLAINS = define(2, "minecraft:plains");
|
||||
public static final VillagerType SAVANNA = define(3, "minecraft:savanna");
|
||||
public static final VillagerType SNOW = define(4, "minecraft:snow");
|
||||
public static final VillagerType SWAMP = define(5, "minecraft:swamp");
|
||||
public static final VillagerType TAIGA = define(6, "minecraft:taiga");
|
||||
public static final VillagerType DESERT = define("desert");
|
||||
public static final VillagerType JUNGLE = define("jungle");
|
||||
public static final VillagerType PLAINS = define("plains");
|
||||
public static final VillagerType SAVANNA = define("savanna");
|
||||
public static final VillagerType SNOW = define("snow");
|
||||
public static final VillagerType SWAMP = define("swamp");
|
||||
public static final VillagerType TAIGA = define("taiga");
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the villager types.
|
||||
*
|
||||
* @return Villager Types
|
||||
*/
|
||||
public static Collection<VillagerType> values() {
|
||||
return Collections.unmodifiableCollection(VILLAGER_TYPE_MAP.values());
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
static {
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
+2
@@ -23,6 +23,7 @@ import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
|
||||
import com.github.retrooper.packetevents.protocol.world.biome.Biome;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -43,6 +44,7 @@ public class StaticWolfVariant extends AbstractMappedEntity implements WolfVaria
|
||||
this(null, wildTexture, tameTexture, angryTexture, biomes);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticWolfVariant(
|
||||
@Nullable TypesBuilderData data,
|
||||
ResourceLocation wildTexture,
|
||||
|
||||
+14
-15
@@ -25,37 +25,36 @@ import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
public final class WolfVariants {
|
||||
|
||||
private static final VersionedRegistry<WolfVariant> REGISTRY = new VersionedRegistry<>(
|
||||
"wolf_variant", "entity/wolf_variant_mappings");
|
||||
private static final VersionedRegistry<WolfVariant> REGISTRY = new VersionedRegistry<>("wolf_variant");
|
||||
|
||||
private WolfVariants() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static WolfVariant define(String key, MappedEntitySet<Biome> biomes) {
|
||||
return define(key, "wolf_" + key, biomes);
|
||||
public static WolfVariant define(String name, MappedEntitySet<Biome> biomes) {
|
||||
return define(name, "wolf_" + name, biomes);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static WolfVariant define(String key, String assetId, MappedEntitySet<Biome> biomes) {
|
||||
return define(key, ResourceLocation.minecraft("entity/wolf/" + assetId),
|
||||
public static WolfVariant define(String name, String assetId, MappedEntitySet<Biome> biomes) {
|
||||
return define(name, ResourceLocation.minecraft("entity/wolf/" + assetId),
|
||||
ResourceLocation.minecraft("entity/wolf/" + assetId + "_tame"),
|
||||
ResourceLocation.minecraft("entity/wolf/" + assetId + "_angry"), biomes);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static WolfVariant define(
|
||||
String key,
|
||||
String name,
|
||||
ResourceLocation wildTexture,
|
||||
ResourceLocation tameTexture,
|
||||
ResourceLocation angryTexture,
|
||||
MappedEntitySet<Biome> biomes
|
||||
) {
|
||||
return REGISTRY.define(key, data -> new StaticWolfVariant(
|
||||
return REGISTRY.define(name, data -> new StaticWolfVariant(
|
||||
data, wildTexture, tameTexture, angryTexture, biomes));
|
||||
}
|
||||
|
||||
@@ -64,21 +63,21 @@ public final class WolfVariants {
|
||||
}
|
||||
|
||||
public static final WolfVariant PALE = define("pale", "wolf",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.TAIGA)));
|
||||
new MappedEntitySet<>(Collections.singletonList(Biomes.TAIGA)));
|
||||
public static final WolfVariant SPOTTED = define("spotted",
|
||||
new MappedEntitySet<>(ResourceLocation.minecraft("is_savanna")));
|
||||
public static final WolfVariant SNOWY = define("snowy",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.GROVE)));
|
||||
new MappedEntitySet<>(Collections.singletonList(Biomes.GROVE)));
|
||||
public static final WolfVariant BLACK = define("black",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.OLD_GROWTH_PINE_TAIGA)));
|
||||
new MappedEntitySet<>(Collections.singletonList(Biomes.OLD_GROWTH_PINE_TAIGA)));
|
||||
public static final WolfVariant ASHEN = define("ashen",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.SNOWY_TAIGA)));
|
||||
new MappedEntitySet<>(Collections.singletonList(Biomes.SNOWY_TAIGA)));
|
||||
public static final WolfVariant RUSTY = define("rusty",
|
||||
new MappedEntitySet<>(ResourceLocation.minecraft("is_jungle")));
|
||||
public static final WolfVariant WOODS = define("woods",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.FOREST)));
|
||||
new MappedEntitySet<>(Collections.singletonList(Biomes.FOREST)));
|
||||
public static final WolfVariant CHESTNUT = define("chestnut",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.OLD_GROWTH_SPRUCE_TAIGA)));
|
||||
new MappedEntitySet<>(Collections.singletonList(Biomes.OLD_GROWTH_SPRUCE_TAIGA)));
|
||||
public static final WolfVariant STRIPED = define("striped",
|
||||
new MappedEntitySet<>(ResourceLocation.minecraft("is_badlands")));
|
||||
|
||||
|
||||
+1
-2
@@ -40,8 +40,7 @@ public final class ArmorMaterials {
|
||||
DFU.put("minecraft:armadillo", "minecraft:armadillo_scute");
|
||||
}
|
||||
|
||||
private static final VersionedRegistry<ArmorMaterial> REGISTRY = new VersionedRegistry<>(
|
||||
"equipment_asset", "item/equipment_asset_mappings");
|
||||
private static final VersionedRegistry<ArmorMaterial> REGISTRY = new VersionedRegistry<>("equipment_asset");
|
||||
|
||||
private ArmorMaterials() {
|
||||
}
|
||||
|
||||
+2
@@ -20,10 +20,12 @@ package com.github.retrooper.packetevents.protocol.item.armormaterial;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticArmorMaterial extends AbstractMappedEntity implements ArmorMaterial {
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticArmorMaterial(@Nullable TypesBuilderData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
+1
-2
@@ -27,8 +27,7 @@ import java.util.Collection;
|
||||
|
||||
public final class BannerPatterns {
|
||||
|
||||
private static final VersionedRegistry<BannerPattern> REGISTRY = new VersionedRegistry<>(
|
||||
"banner_pattern", "item/item_banner_pattern_mappings");
|
||||
private static final VersionedRegistry<BannerPattern> REGISTRY = new VersionedRegistry<>("banner_pattern");
|
||||
|
||||
private BannerPatterns() {
|
||||
}
|
||||
|
||||
+2
@@ -21,6 +21,7 @@ package com.github.retrooper.packetevents.protocol.item.banner;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -34,6 +35,7 @@ public class StaticBannerPattern extends AbstractMappedEntity implements BannerP
|
||||
this(null, assetId, translationKey);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticBannerPattern(@Nullable TypesBuilderData data, ResourceLocation assetId, String translationKey) {
|
||||
super(data);
|
||||
this.assetId = assetId;
|
||||
|
||||
+1
-2
@@ -30,8 +30,7 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public final class ConsumeEffectTypes {
|
||||
|
||||
private static final VersionedRegistry<ConsumeEffectType<?>> REGISTRY = new VersionedRegistry<>(
|
||||
"consume_effect_type", "item/consume_effect_type_mappings");
|
||||
private static final VersionedRegistry<ConsumeEffectType<?>> REGISTRY = new VersionedRegistry<>("consume_effect_type");
|
||||
|
||||
private ConsumeEffectTypes() {
|
||||
}
|
||||
|
||||
+2
@@ -23,6 +23,7 @@ import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticConsumeEffectType<T extends ConsumeEffect<?>> extends AbstractMappedEntity implements ConsumeEffectType<T> {
|
||||
@@ -30,6 +31,7 @@ public class StaticConsumeEffectType<T extends ConsumeEffect<?>> extends Abstrac
|
||||
private final Reader<T> reader;
|
||||
private final Writer<T> writer;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticConsumeEffectType(
|
||||
@Nullable TypesBuilderData data,
|
||||
Reader<T> reader,
|
||||
|
||||
+7
-8
@@ -46,12 +46,9 @@ public final class EnchantmentTypes {
|
||||
|
||||
static {
|
||||
ENCHANTMENT_DATA = new HashMap<>();
|
||||
try (SequentialNBTReader.Compound dataTag = MappingHelper.decompress("mappings/enchantment/enchantment_type_data")) {
|
||||
while (dataTag.hasNext()) {
|
||||
Map.Entry<String, NBT> entry = dataTag.next();
|
||||
if (entry.getKey().equals("version")) {
|
||||
continue; // skip version field
|
||||
}
|
||||
try (SequentialNBTReader.Compound dataTag = MappingHelper.decompress("mappings/data/enchantment")) {
|
||||
dataTag.skipOne(); // skip version
|
||||
for (Map.Entry<String, NBT> entry : (SequentialNBTReader.Compound) dataTag.next().getValue()) {
|
||||
ResourceLocation enchantKey = new ResourceLocation(entry.getKey());
|
||||
ENCHANTMENT_DATA.put(enchantKey, ((SequentialNBTReader.Compound) entry.getValue()).readFully());
|
||||
}
|
||||
@@ -60,8 +57,10 @@ public final class EnchantmentTypes {
|
||||
}
|
||||
}
|
||||
|
||||
private static final VersionedRegistry<EnchantmentType> REGISTRY = new VersionedRegistry<>(
|
||||
"enchantment", "enchantment/enchantment_type_mappings");
|
||||
private static final VersionedRegistry<EnchantmentType> REGISTRY = new VersionedRegistry<>("enchantment");
|
||||
|
||||
private EnchantmentTypes() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static EnchantmentType define(String key) {
|
||||
|
||||
+2
@@ -24,6 +24,7 @@ import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -44,6 +45,7 @@ public class StaticEnchantmentType extends AbstractMappedEntity implements Encha
|
||||
this(null, description, definition, exclusiveSet, effects);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticEnchantmentType(
|
||||
@Nullable TypesBuilderData data,
|
||||
Component description,
|
||||
|
||||
+2
-2
@@ -27,12 +27,12 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public final class Instruments {
|
||||
|
||||
private static final VersionedRegistry<Instrument> REGISTRY = new VersionedRegistry<>(
|
||||
"instrument", "item/item_instrument_mappings");
|
||||
private static final VersionedRegistry<Instrument> REGISTRY = new VersionedRegistry<>("instrument");
|
||||
|
||||
private Instruments() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static Instrument define(String key, Sound sound) {
|
||||
// vanilla defaults for goat horns
|
||||
return define(key, sound, 20 * 7, 256f);
|
||||
|
||||
+2
@@ -22,6 +22,7 @@ import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.sound.Sound;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -42,6 +43,7 @@ public class StaticInstrument extends AbstractMappedEntity implements Instrument
|
||||
this(null, sound, useSeconds, range, description);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticInstrument(@Nullable TypesBuilderData data, Sound sound, float useSeconds, float range, Component description) {
|
||||
super(data);
|
||||
this.sound = sound;
|
||||
|
||||
+10
-2
@@ -23,11 +23,13 @@ import com.github.retrooper.packetevents.protocol.sound.Sound;
|
||||
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.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class JukeboxSong extends AbstractMappedEntity implements IJukeboxSong {
|
||||
|
||||
private Sound sound;
|
||||
private Component description;
|
||||
private float lengthInSeconds;
|
||||
@@ -37,8 +39,14 @@ public class JukeboxSong extends AbstractMappedEntity implements IJukeboxSong {
|
||||
this(null, sound, description, lengthInSeconds, comparatorOutput);
|
||||
}
|
||||
|
||||
public JukeboxSong(@Nullable TypesBuilderData data, Sound sound, Component description, float lengthInSeconds,
|
||||
int comparatorOutput) {
|
||||
@ApiStatus.Internal
|
||||
public JukeboxSong(
|
||||
@Nullable TypesBuilderData data,
|
||||
Sound sound,
|
||||
Component description,
|
||||
float lengthInSeconds,
|
||||
int comparatorOutput
|
||||
) {
|
||||
super(data);
|
||||
this.sound = sound;
|
||||
this.description = description;
|
||||
|
||||
+3
-3
@@ -29,9 +29,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class JukeboxSongs {
|
||||
private static final VersionedRegistry<IJukeboxSong> REGISTRY = new VersionedRegistry<>("jukebox_song",
|
||||
"item/item_jukebox_song_mappings");
|
||||
public final class JukeboxSongs {
|
||||
|
||||
private static final VersionedRegistry<IJukeboxSong> REGISTRY = new VersionedRegistry<>("jukebox_song");
|
||||
|
||||
private JukeboxSongs() {
|
||||
}
|
||||
|
||||
+15
-46
@@ -21,21 +21,26 @@ package com.github.retrooper.packetevents.protocol.item.mapdecoration;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.github.retrooper.packetevents.resources.ResourceLocation.minecraft;
|
||||
|
||||
public class MapDecorationTypes {
|
||||
public final class MapDecorationTypes {
|
||||
|
||||
private static final VersionedRegistry<MapDecorationType> REGISTRY =
|
||||
new VersionedRegistry<>("map_decoration_type", "item/item_map_decoration_type_mappings");
|
||||
private static final VersionedRegistry<MapDecorationType> REGISTRY = new VersionedRegistry<>("map_decoration_type");
|
||||
|
||||
private MapDecorationTypes() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static MapDecorationType define(String key, boolean showOnItemFrame, boolean trackCount) {
|
||||
return define(key, minecraft(key), showOnItemFrame, trackCount);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static MapDecorationType define(
|
||||
String key, ResourceLocation assetId,
|
||||
boolean showOnItemFrame, boolean trackCount
|
||||
@@ -44,6 +49,7 @@ public class MapDecorationTypes {
|
||||
-1, false, trackCount);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static MapDecorationType define(
|
||||
String key,
|
||||
boolean showOnItemFrame, int mapColor,
|
||||
@@ -53,55 +59,18 @@ public class MapDecorationTypes {
|
||||
showOnItemFrame, mapColor, explorationMapElement, trackCount);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static MapDecorationType define(
|
||||
String key, ResourceLocation assetId,
|
||||
boolean showOnItemFrame, int mapColor,
|
||||
boolean explorationMapElement, boolean trackCount
|
||||
) {
|
||||
return REGISTRY.define(key, data -> new MapDecorationType() {
|
||||
@Override
|
||||
public ResourceLocation getAssetId() {
|
||||
return assetId;
|
||||
}
|
||||
return REGISTRY.define(key, data -> new StaticMapDecorationType(data,
|
||||
assetId, showOnItemFrame, mapColor, explorationMapElement, trackCount));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowOnItemFrame() {
|
||||
return showOnItemFrame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMapColor() {
|
||||
return mapColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExplorationMapElement() {
|
||||
return explorationMapElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrackCount() {
|
||||
return trackCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
return data.getId(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof MapDecorationType) {
|
||||
return this.getName().equals(((MapDecorationType) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
public static VersionedRegistry<MapDecorationType> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
public static @Nullable MapDecorationType getByName(String name) {
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.item.mapdecoration;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticMapDecorationType extends AbstractMappedEntity implements MapDecorationType {
|
||||
|
||||
private final ResourceLocation assetId;
|
||||
private final boolean showOnItemFrame;
|
||||
private final int mapColor;
|
||||
private final boolean explorationMapElement;
|
||||
private final boolean trackCount;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticMapDecorationType(
|
||||
@Nullable TypesBuilderData data,
|
||||
ResourceLocation assetId, boolean showOnItemFrame, int mapColor,
|
||||
boolean explorationMapElement, boolean trackCount
|
||||
) {
|
||||
super(data);
|
||||
this.assetId = assetId;
|
||||
this.showOnItemFrame = showOnItemFrame;
|
||||
this.mapColor = mapColor;
|
||||
this.explorationMapElement = explorationMapElement;
|
||||
this.trackCount = trackCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAssetId() {
|
||||
return this.assetId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowOnItemFrame() {
|
||||
return this.showOnItemFrame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMapColor() {
|
||||
return this.mapColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExplorationMapElement() {
|
||||
return this.explorationMapElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrackCount() {
|
||||
return this.trackCount;
|
||||
}
|
||||
}
|
||||
+3
@@ -23,6 +23,7 @@ import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -43,6 +44,7 @@ public class StaticTrimMaterial extends AbstractMappedEntity implements TrimMate
|
||||
this(null, assetName, ingredient, FALLBACK_ITEM_MODEL_INDEX, overrideArmorMaterials, description);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticTrimMaterial(
|
||||
@Nullable TypesBuilderData data,
|
||||
String assetName, ItemType ingredient,
|
||||
@@ -58,6 +60,7 @@ public class StaticTrimMaterial extends AbstractMappedEntity implements TrimMate
|
||||
this(null, assetName, ingredient, itemModelIndex, overrideArmorMaterials, description);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticTrimMaterial(
|
||||
@Nullable TypesBuilderData data,
|
||||
String assetName, ItemType ingredient, float itemModelIndex,
|
||||
|
||||
+1
-2
@@ -37,8 +37,7 @@ import static net.kyori.adventure.text.format.TextColor.color;
|
||||
|
||||
public final class TrimMaterials {
|
||||
|
||||
private static final VersionedRegistry<TrimMaterial> REGISTRY = new VersionedRegistry<>(
|
||||
"trim_material", "item/item_trim_material_mappings");
|
||||
private static final VersionedRegistry<TrimMaterial> REGISTRY = new VersionedRegistry<>("trim_material");
|
||||
|
||||
private TrimMaterials() {
|
||||
}
|
||||
|
||||
+2
@@ -23,6 +23,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.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -41,6 +42,7 @@ public class StaticTrimPattern extends AbstractMappedEntity implements TrimPatte
|
||||
this(null, assetId, templateItem, description, decal);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticTrimPattern(
|
||||
@Nullable TypesBuilderData data,
|
||||
ResourceLocation assetId, ItemType templateItem,
|
||||
|
||||
+7
-8
@@ -28,27 +28,26 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public final class TrimPatterns {
|
||||
|
||||
private static final VersionedRegistry<TrimPattern> REGISTRY = new VersionedRegistry<>(
|
||||
"trim_pattern", "item/item_trim_pattern_mappings");
|
||||
private static final VersionedRegistry<TrimPattern> REGISTRY = new VersionedRegistry<>("trim_pattern");
|
||||
|
||||
private TrimPatterns() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static TrimPattern define(String key) {
|
||||
ResourceLocation assetId = ResourceLocation.minecraft(key);
|
||||
public static TrimPattern define(String name) {
|
||||
ResourceLocation assetId = ResourceLocation.minecraft(name);
|
||||
ItemType templateItem = ItemTypes.getByName(assetId + "_armor_trim_smithing_template");
|
||||
Component description = Component.translatable("trim_pattern.minecraft." + key);
|
||||
Component description = Component.translatable("trim_pattern.minecraft." + name);
|
||||
boolean decal = false;
|
||||
return define(key, assetId, templateItem, description, decal);
|
||||
return define(name, assetId, templateItem, description, decal);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static TrimPattern define(
|
||||
String key, ResourceLocation assetId, ItemType templateItem,
|
||||
String name, ResourceLocation assetId, ItemType templateItem,
|
||||
Component description, boolean decal
|
||||
) {
|
||||
return REGISTRY.define(key, data ->
|
||||
return REGISTRY.define(name, data ->
|
||||
new StaticTrimPattern(data, assetId, templateItem, description, decal));
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ public interface ItemType extends MappedEntity {
|
||||
return this.getAttributes().contains(attribute);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
default StaticComponentMap getComponents() {
|
||||
return this.getComponents(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
||||
}
|
||||
|
||||
+56
-31
@@ -18,12 +18,13 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.item.type;
|
||||
|
||||
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
|
||||
import com.github.retrooper.packetevents.netty.buffer.UnpooledByteBufAllocationHelper;
|
||||
import com.github.retrooper.packetevents.protocol.component.ComponentType;
|
||||
import com.github.retrooper.packetevents.protocol.component.ComponentTypes;
|
||||
import com.github.retrooper.packetevents.protocol.component.StaticComponentMap;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTByteArray;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.serializer.SequentialNBTReader;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
@@ -32,11 +33,11 @@ import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -46,10 +47,9 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ItemTypes {
|
||||
public final class ItemTypes {
|
||||
|
||||
private static final VersionedRegistry<ItemType> REGISTRY = new VersionedRegistry<>(
|
||||
"item", "item/item_type_mappings");
|
||||
private static final VersionedRegistry<ItemType> REGISTRY = new VersionedRegistry<>("item");
|
||||
private static final Map<StateType, ItemType> HELD_TO_PLACED_MAP = new HashMap<>();
|
||||
|
||||
// <editor-fold desc="item type definitions" defaultstate="collapsed">
|
||||
@@ -1504,6 +1504,9 @@ public class ItemTypes {
|
||||
|
||||
// </editor-fold>
|
||||
|
||||
private ItemTypes() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static StaticComponentMap.Builder parseComponents(
|
||||
ClientVersion version,
|
||||
@@ -1514,52 +1517,73 @@ public class ItemTypes {
|
||||
if (base != null) {
|
||||
components.setAll(base);
|
||||
}
|
||||
// TODO release buffer helper
|
||||
// allocate a buffer once and use it for parsing everything
|
||||
Object byteBuf = UnpooledByteBufAllocationHelper.buffer();
|
||||
PacketWrapper<?> wrapper = PacketWrapper.createUniversalPacketWrapper(byteBuf, version.toServerVersion());
|
||||
|
||||
for (Map.Entry<String, NBT> entry : nbt) {
|
||||
ComponentType<?> compType = ComponentTypes.getByName(entry.getKey());
|
||||
if (compType == null) {
|
||||
continue;
|
||||
}
|
||||
byte[] encodedValue = Base64.getDecoder().decode(
|
||||
((NBTString) entry.getValue()).getValue());
|
||||
Object byteBuf = UnpooledByteBufAllocationHelper.wrappedBuffer(encodedValue);
|
||||
PacketWrapper<?> wrapper = PacketWrapper.createUniversalPacketWrapper(byteBuf);
|
||||
wrapper.setClientVersion(version);
|
||||
wrapper.setServerVersion(version.toServerVersion());
|
||||
|
||||
// reset to start of buffer
|
||||
ByteBufHelper.resetReaderIndex(byteBuf);
|
||||
|
||||
// empty values are serialized as a single byte (smaller than an empty byte array),
|
||||
// so just parse byte array tag values
|
||||
if (entry.getValue() instanceof NBTByteArray) {
|
||||
byte[] bytes = ((NBTByteArray) entry.getValue()).getValue();
|
||||
// write bytes at beginning of buffer
|
||||
ByteBufHelper.resetWriterIndex(byteBuf);
|
||||
ByteBufHelper.writeBytes(byteBuf, bytes);
|
||||
}
|
||||
|
||||
// read from shared buffer
|
||||
Object compValue = compType.read(wrapper);
|
||||
components.set((ComponentType<Object>) compType, compValue);
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
static {
|
||||
try (SequentialNBTReader.Compound compound = MappingHelper.decompress("mappings/item/item_base_components")) {
|
||||
private static void parseAllComponents(ClientVersion version) {
|
||||
String path = "mappings/item_base_components/" + version.name();
|
||||
try (SequentialNBTReader.Compound compound = MappingHelper.decompress(path)) {
|
||||
compound.skipOne(); // skip version
|
||||
for (Map.Entry<String, NBT> entry : compound) {
|
||||
ClientVersion version = ClientVersion.valueOf(entry.getKey());
|
||||
SequentialNBTReader.Compound items = (SequentialNBTReader.Compound) entry.getValue();
|
||||
StaticComponentMap defaults = parseComponents(
|
||||
version, null, (SequentialNBTReader.Compound) items.next().getValue()).build();
|
||||
SequentialNBTReader.Compound items = (SequentialNBTReader.Compound) compound.next().getValue();
|
||||
StaticComponentMap defaults = parseComponents(
|
||||
version, null, (SequentialNBTReader.Compound) items.next().getValue()).build();
|
||||
|
||||
for (Map.Entry<String, NBT> item : items) {
|
||||
ItemType itemType = REGISTRY.getByName(new ResourceLocation(item.getKey()));
|
||||
if (!(itemType instanceof StaticItemType)) {
|
||||
((SequentialNBTReader.Compound) item.getValue()).skip();
|
||||
continue; // somehow unknown item
|
||||
}
|
||||
StaticComponentMap.Builder components = parseComponents(version, defaults,
|
||||
(SequentialNBTReader.Compound) item.getValue());
|
||||
((StaticItemType) itemType).setComponents(version, components.build());
|
||||
for (Map.Entry<String, NBT> item : items) {
|
||||
ItemType itemType = REGISTRY.getByName(new ResourceLocation(item.getKey()));
|
||||
if (!(itemType instanceof StaticItemType)) {
|
||||
((SequentialNBTReader.Compound) item.getValue()).skip();
|
||||
continue; // somehow unknown item
|
||||
}
|
||||
for (ItemType type : REGISTRY.getEntries()) {
|
||||
if (type instanceof StaticItemType && !((StaticItemType) type).hasComponents(version)) {
|
||||
((StaticItemType) type).setComponents(version, defaults);
|
||||
}
|
||||
StaticComponentMap.Builder components = parseComponents(version, defaults,
|
||||
(SequentialNBTReader.Compound) item.getValue());
|
||||
((StaticItemType) itemType).setComponents(version, components.build());
|
||||
}
|
||||
for (ItemType type : REGISTRY.getEntries()) {
|
||||
if (type instanceof StaticItemType && !((StaticItemType) type).hasComponents(version)) {
|
||||
((StaticItemType) type).setComponents(version, defaults);
|
||||
}
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
throw new RuntimeException("Error while parsing item base component data", exception);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
// all versions where base components were changed TODO UPDATE
|
||||
ClientVersion[] versions = new ClientVersion[]{
|
||||
ClientVersion.V_1_20_5, ClientVersion.V_1_21, ClientVersion.V_1_21_2,
|
||||
ClientVersion.V_1_21_4,
|
||||
};
|
||||
for (ClientVersion version : versions) {
|
||||
parseAllComponents(version);
|
||||
}
|
||||
for (ItemType type : REGISTRY.getEntries()) {
|
||||
if (type instanceof StaticItemType) {
|
||||
((StaticItemType) type).fillComponents();
|
||||
@@ -1579,6 +1603,7 @@ public class ItemTypes {
|
||||
return new Builder(key.toLowerCase());
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static ItemType define(int maxAmount, String key, ItemType craftRemainder, StateType placedType, int maxDurability, List<ItemAttribute> attributesArr) {
|
||||
// Creates an immutable set
|
||||
Set<ItemAttribute> attributes = attributesArr == null ? Collections.emptySet() :
|
||||
|
||||
+4
-2
@@ -24,6 +24,7 @@ import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.EnumMap;
|
||||
@@ -39,8 +40,9 @@ public class StaticItemType extends AbstractMappedEntity implements ItemType {
|
||||
private final Set<ItemAttribute> attributes;
|
||||
private final Map<ClientVersion, StaticComponentMap> components;
|
||||
|
||||
StaticItemType(
|
||||
TypesBuilderData data,
|
||||
@ApiStatus.Internal
|
||||
public StaticItemType(
|
||||
@Nullable TypesBuilderData data,
|
||||
int maxAmount,
|
||||
int maxDurability,
|
||||
ItemType craftRemainder,
|
||||
|
||||
+1
@@ -22,6 +22,7 @@ import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
@Deprecated
|
||||
public class GenericMappedEntity implements StaticMappedEntity {
|
||||
|
||||
private final int id;
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public interface ParticleType<T extends ParticleData> extends MappedEntity {
|
||||
|
||||
T decodeData(NBTCompound compound, ClientVersion version);
|
||||
|
||||
void encodeData(T data, ClientVersion version, NBTCompound compound);
|
||||
void encodeData(T value, ClientVersion version, NBTCompound compound);
|
||||
|
||||
@Deprecated
|
||||
default Function<PacketWrapper<?>, ParticleData> readDataFunction() {
|
||||
|
||||
+21
-72
@@ -30,101 +30,50 @@ import com.github.retrooper.packetevents.protocol.particle.data.ParticleShriekDa
|
||||
import com.github.retrooper.packetevents.protocol.particle.data.ParticleTrailData;
|
||||
import com.github.retrooper.packetevents.protocol.particle.data.ParticleVibrationData;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ParticleTypes {
|
||||
public final class ParticleTypes {
|
||||
|
||||
private static final Map<String, ParticleType<?>> PARTICLE_TYPE_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, ParticleType<?>>> PARTICLE_TYPE_ID_MAP = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("particle/particle_type_mappings");
|
||||
private static final VersionedRegistry<ParticleType<?>> REGISTRY = new VersionedRegistry<>("particle_type");
|
||||
|
||||
public static ParticleType<ParticleData> define(String key) {
|
||||
private ParticleTypes() {
|
||||
}
|
||||
|
||||
public static VersionedRegistry<ParticleType<?>> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static ParticleType<ParticleData> define(String name) {
|
||||
return define(
|
||||
key,
|
||||
name,
|
||||
wrapper -> ParticleData.emptyData(), null,
|
||||
(nbt, version) -> ParticleData.emptyData(), null
|
||||
);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static <T extends ParticleData> ParticleType<T> define(
|
||||
String key,
|
||||
String name,
|
||||
Reader<T> reader, @Nullable Writer<T> writer,
|
||||
Decoder<T> decoder, @Nullable Encoder<T> encoder
|
||||
) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
ParticleType<T> particleType = new ParticleType<T>() {
|
||||
@Override
|
||||
public T readData(PacketWrapper<?> wrapper) {
|
||||
return reader.apply(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(PacketWrapper<?> wrapper, T data) {
|
||||
if (writer != null) {
|
||||
writer.accept(wrapper, data);
|
||||
} else if (!data.isEmpty()) {
|
||||
throw new UnsupportedOperationException("Trying to write non-empty data for " + this.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T decodeData(NBTCompound compound, ClientVersion version) {
|
||||
return decoder.decode(compound, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeData(T data, ClientVersion version, NBTCompound compound) {
|
||||
if (encoder != null) {
|
||||
encoder.encode(data, version, compound);
|
||||
} else if (!data.isEmpty()) {
|
||||
throw new UnsupportedOperationException("Trying to encode non-empty data for " + this.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
return MappingHelper.getId(version, TYPES_BUILDER, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ParticleType<?>) {
|
||||
return this.getName().equals(((ParticleType<?>) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, PARTICLE_TYPE_MAP, PARTICLE_TYPE_ID_MAP, particleType);
|
||||
return particleType;
|
||||
return REGISTRY.define(name, data ->
|
||||
new StaticParticleType<>(data, reader, writer, decoder, encoder));
|
||||
}
|
||||
|
||||
//with minecraft:key
|
||||
public static ParticleType<?> getByName(String name) {
|
||||
return PARTICLE_TYPE_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static ParticleType<?> getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, ParticleType<?>> typeIdMap = PARTICLE_TYPE_ID_MAP.get((byte) index);
|
||||
return typeIdMap.get(id);
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
@Deprecated // Removed in 1.20.5
|
||||
@@ -291,11 +240,11 @@ public class ParticleTypes {
|
||||
* @return Particle Types
|
||||
*/
|
||||
public static Collection<ParticleType<?>> values() {
|
||||
return Collections.unmodifiableCollection(PARTICLE_TYPE_MAP.values());
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.particle.type;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.particle.data.ParticleData;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticParticleType<T extends ParticleData> extends AbstractMappedEntity implements ParticleType<T> {
|
||||
|
||||
private final PacketWrapper.Reader<T> reader;
|
||||
private final PacketWrapper.Writer<T> writer;
|
||||
private final ParticleTypes.Decoder<T> decoder;
|
||||
private final ParticleTypes.Encoder<T> encoder;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticParticleType(
|
||||
@Nullable TypesBuilderData data,
|
||||
PacketWrapper.Reader<T> reader,
|
||||
PacketWrapper.Writer<T> writer,
|
||||
ParticleTypes.Decoder<T> decoder,
|
||||
ParticleTypes.Encoder<T> encoder
|
||||
) {
|
||||
super(data);
|
||||
this.reader = reader;
|
||||
this.writer = writer;
|
||||
this.decoder = decoder;
|
||||
this.encoder = encoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T readData(PacketWrapper<?> wrapper) {
|
||||
return this.reader.apply(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeData(PacketWrapper<?> wrapper, T data) {
|
||||
if (this.writer != null) {
|
||||
this.writer.accept(wrapper, data);
|
||||
} else if (!data.isEmpty()) {
|
||||
throw new UnsupportedOperationException("Trying to write non-empty data for " + this.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T decodeData(NBTCompound compound, ClientVersion version) {
|
||||
return this.decoder.decode(compound, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeData(T value, ClientVersion version, NBTCompound compound) {
|
||||
if (this.encoder != null) {
|
||||
this.encoder.encode(value, version, compound);
|
||||
} else if (!value.isEmpty()) {
|
||||
throw new UnsupportedOperationException("Trying to encode non-empty data for " + this.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
-47
@@ -21,16 +21,11 @@ package com.github.retrooper.packetevents.protocol.potion;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
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 org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Potion types are the individually applied potion effects.<br>
|
||||
@@ -38,46 +33,29 @@ import java.util.Map;
|
||||
* <p>
|
||||
* For potions brewable in survival, see {@link Potions}.
|
||||
*/
|
||||
public class PotionTypes {
|
||||
public final class PotionTypes {
|
||||
|
||||
private static final Map<String, PotionType> POTION_TYPE_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, PotionType>> POTION_TYPE_ID_MAP = new HashMap<>();
|
||||
private static final VersionedRegistry<PotionType> REGISTRY = new VersionedRegistry<>("mob_effect");
|
||||
|
||||
// initial mappings based upon https://minecraft.wiki/w/Effect#History
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_effect_mappings");
|
||||
|
||||
@Deprecated
|
||||
public static PotionType define(String key, int ignoredId) {
|
||||
return define(key);
|
||||
private PotionTypes() {
|
||||
}
|
||||
|
||||
public static PotionType define(String key) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
PotionType potionType = new PotionType() {
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
public static VersionedRegistry<PotionType> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
return MappingHelper.getId(version, TYPES_BUILDER, data);
|
||||
}
|
||||
@Deprecated
|
||||
public static PotionType define(String name, int ignoredId) {
|
||||
return define(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof PotionType) {
|
||||
return this.getName().equals(((PotionType) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, POTION_TYPE_MAP, POTION_TYPE_ID_MAP, potionType);
|
||||
return potionType;
|
||||
@ApiStatus.Internal
|
||||
public static PotionType define(String name) {
|
||||
return REGISTRY.define(name, StaticPotionType::new);
|
||||
}
|
||||
|
||||
public static @Nullable PotionType getByName(String name) {
|
||||
return POTION_TYPE_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@@ -85,20 +63,21 @@ public class PotionTypes {
|
||||
return getById(id, PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static @Nullable PotionType getById(int id, ServerVersion version) {
|
||||
return getById(id, version.toClientVersion());
|
||||
}
|
||||
|
||||
public static @Nullable PotionType getById(ClientVersion version, int id) {
|
||||
return getById(id, version);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static @Nullable PotionType getById(int id, ClientVersion version) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, PotionType> idMap = POTION_TYPE_ID_MAP.get((byte) index);
|
||||
return idMap.get(id);
|
||||
return getById(version, id);
|
||||
}
|
||||
|
||||
public static @Nullable PotionType getById(ClientVersion version, int id) {
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
// initial mappings based upon https://minecraft.wiki/w/Effect#History
|
||||
// Added in b1.8
|
||||
public static final PotionType SPEED = define("speed");
|
||||
public static final PotionType SLOWNESS = define("slowness");
|
||||
@@ -156,13 +135,14 @@ public class PotionTypes {
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the potion types.
|
||||
*
|
||||
* @return Potion Types
|
||||
*/
|
||||
public static Collection<PotionType> values() {
|
||||
return Collections.unmodifiableCollection(POTION_TYPE_MAP.values());
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
@@ -19,65 +19,42 @@
|
||||
package com.github.retrooper.packetevents.protocol.potion;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
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 org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Potions are all possible brewable drinks.<br>
|
||||
* Some examples are the potion of leaping, the extended potion of leaping
|
||||
* or the strong potion of leaping.
|
||||
* <p>
|
||||
* For individual potion effects, see {@link PotionTypes}.
|
||||
* For individual potion effects (also called "mob effects"), see {@link PotionTypes}.
|
||||
*/
|
||||
public class Potions {
|
||||
public final class Potions {
|
||||
|
||||
private static final Map<String, Potion> POTION_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, Potion>> POTION_ID_MAP = new HashMap<>();
|
||||
private static final VersionedRegistry<Potion> REGISTRY = new VersionedRegistry<>("potion");
|
||||
|
||||
// initial mappings based upon https://minecraft.wiki/w/Potion#History
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_potion_mappings");
|
||||
private Potions() {
|
||||
}
|
||||
|
||||
public static Potion define(String key) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
Potion potion = new Potion() {
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
public static VersionedRegistry<Potion> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
return MappingHelper.getId(version, TYPES_BUILDER, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof PotionType) {
|
||||
return getName().equals(((PotionType) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, POTION_MAP, POTION_ID_MAP, potion);
|
||||
return potion;
|
||||
@ApiStatus.Internal
|
||||
public static Potion define(String name) {
|
||||
return REGISTRY.define(name, StaticPotion::new);
|
||||
}
|
||||
|
||||
public static @Nullable Potion getByName(String name) {
|
||||
return POTION_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static @Nullable Potion getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, Potion> idMap = POTION_ID_MAP.get((byte) index);
|
||||
return idMap.get(id);
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
// initial mappings based upon https://minecraft.wiki/w/Potion#History
|
||||
public static final Potion WATER = define("water");
|
||||
public static final Potion MUNDANE = define("mundane");
|
||||
public static final Potion THICK = define("thick");
|
||||
@@ -126,6 +103,6 @@ public class Potions {
|
||||
public static final Potion INFESTED = define("infested");
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.potion;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticPotion extends AbstractMappedEntity implements Potion {
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticPotion(@Nullable TypesBuilderData data) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.potion;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticPotionType extends AbstractMappedEntity implements PotionType {
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticPotionType(@Nullable TypesBuilderData data) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
+22
-62
@@ -27,94 +27,54 @@ import com.github.retrooper.packetevents.protocol.recipe.data.SimpleRecipeData;
|
||||
import com.github.retrooper.packetevents.protocol.recipe.data.SmithingRecipeData;
|
||||
import com.github.retrooper.packetevents.protocol.recipe.data.SmithingTrimRecipeData;
|
||||
import com.github.retrooper.packetevents.protocol.recipe.data.StoneCuttingRecipeData;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
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 org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
public class RecipeSerializers {
|
||||
public final class RecipeSerializers {
|
||||
|
||||
private static final Map<String, RecipeSerializer<?>> PATTERN_TYPE_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, RecipeSerializer<?>>> PATTERN_TYPE_ID_MAP = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/recipe_serializer_mappings");
|
||||
private static final VersionedRegistry<RecipeSerializer<?>> REGISTRY = new VersionedRegistry<>("legacy_recipe_serializer");
|
||||
|
||||
private RecipeSerializers() {
|
||||
}
|
||||
|
||||
public static VersionedRegistry<RecipeSerializer<?>> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static <T extends RecipeData> RecipeSerializer<T> define(
|
||||
String key,
|
||||
String name,
|
||||
PacketWrapper.Reader<T> reader,
|
||||
PacketWrapper.Writer<T> writer
|
||||
) {
|
||||
return define(key, reader, writer, null);
|
||||
return define(name, reader, writer, null);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static <T extends RecipeData> RecipeSerializer<T> define(
|
||||
String key,
|
||||
String name,
|
||||
PacketWrapper.Reader<T> reader,
|
||||
PacketWrapper.Writer<T> writer,
|
||||
@Nullable RecipeType recipeType
|
||||
@Nullable RecipeType legacyType
|
||||
) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
RecipeSerializer<T> pattern = new RecipeSerializer<T>() {
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
return MappingHelper.getId(version, TYPES_BUILDER, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType getLegacyType() {
|
||||
if (recipeType == null) {
|
||||
throw new UnsupportedOperationException("No legacy type found for " + this.getName());
|
||||
}
|
||||
return recipeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(PacketWrapper<?> wrapper) {
|
||||
return reader.apply(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper<?> wrapper, T data) {
|
||||
writer.accept(wrapper, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof RecipeSerializer<?>) {
|
||||
return this.getName().equals(((RecipeSerializer<?>) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, PATTERN_TYPE_MAP, PATTERN_TYPE_ID_MAP, pattern);
|
||||
return pattern;
|
||||
return REGISTRY.define(name, data -> new StaticRecipeSerializer<>(
|
||||
data, reader, writer, legacyType));
|
||||
}
|
||||
|
||||
// with key
|
||||
public static RecipeSerializer<?> getByName(String name) {
|
||||
return PATTERN_TYPE_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static RecipeSerializer<?> getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, RecipeSerializer<?>> idMap = PATTERN_TYPE_ID_MAP.get((byte) index);
|
||||
return idMap.get(id);
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static final RecipeSerializer<ShapedRecipeData> CRAFTING_SHAPED = define("crafting_shaped",
|
||||
@@ -175,10 +135,10 @@ public class RecipeSerializers {
|
||||
* @return Banner Patterns
|
||||
*/
|
||||
public static Collection<RecipeSerializer<?>> values() {
|
||||
return Collections.unmodifiableCollection(PATTERN_TYPE_MAP.values());
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.recipe;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.recipe.data.RecipeData;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticRecipeSerializer<T extends RecipeData> extends AbstractMappedEntity implements RecipeSerializer<T> {
|
||||
|
||||
private final PacketWrapper.Reader<T> reader;
|
||||
private final PacketWrapper.Writer<T> writer;
|
||||
private final @Nullable RecipeType legacyType;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticRecipeSerializer(
|
||||
@Nullable TypesBuilderData data,
|
||||
PacketWrapper.Reader<T> reader,
|
||||
PacketWrapper.Writer<T> writer,
|
||||
@Nullable RecipeType legacyType
|
||||
) {
|
||||
super(data);
|
||||
this.reader = reader;
|
||||
this.writer = writer;
|
||||
this.legacyType = legacyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType getLegacyType() {
|
||||
return this.legacyType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(PacketWrapper<?> wrapper) {
|
||||
return this.reader.apply(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper<?> wrapper, T data) {
|
||||
this.writer.accept(wrapper, data);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -22,8 +22,7 @@ import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
|
||||
public final class RecipeBookCategories {
|
||||
|
||||
private static final VersionedRegistry<RecipeBookCategory> REGISTRY = new VersionedRegistry<>(
|
||||
"recipe_book_category", "item/recipe_book_category");
|
||||
private static final VersionedRegistry<RecipeBookCategory> REGISTRY = new VersionedRegistry<>("recipe_book_category");
|
||||
|
||||
private RecipeBookCategories() {
|
||||
}
|
||||
|
||||
+4
-1
@@ -20,10 +20,13 @@ package com.github.retrooper.packetevents.protocol.recipe.category;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticRecipeBookCategory extends AbstractMappedEntity implements RecipeBookCategory {
|
||||
|
||||
public StaticRecipeBookCategory(TypesBuilderData data) {
|
||||
@ApiStatus.Internal
|
||||
public StaticRecipeBookCategory(@Nullable TypesBuilderData data) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -23,8 +23,7 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
public final class RecipeDisplayTypes {
|
||||
|
||||
private static final VersionedRegistry<RecipeDisplayType<?>> REGISTRY = new VersionedRegistry<>(
|
||||
"recipe_display", "item/recipe_display_types");
|
||||
private static final VersionedRegistry<RecipeDisplayType<?>> REGISTRY = new VersionedRegistry<>("recipe_display");
|
||||
|
||||
private RecipeDisplayTypes() {
|
||||
}
|
||||
|
||||
+2
@@ -21,6 +21,7 @@ package com.github.retrooper.packetevents.protocol.recipe.display;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticRecipeDisplayType<T extends RecipeDisplay<?>> extends AbstractMappedEntity implements RecipeDisplayType<T> {
|
||||
@@ -28,6 +29,7 @@ public class StaticRecipeDisplayType<T extends RecipeDisplay<?>> extends Abstrac
|
||||
private final PacketWrapper.Reader<T> reader;
|
||||
private final PacketWrapper.Writer<T> writer;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticRecipeDisplayType(
|
||||
@Nullable TypesBuilderData data,
|
||||
PacketWrapper.Reader<T> reader,
|
||||
|
||||
+1
-2
@@ -23,8 +23,7 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
public final class SlotDisplayTypes {
|
||||
|
||||
private static final VersionedRegistry<SlotDisplayType<?>> REGISTRY = new VersionedRegistry<>(
|
||||
"slot_display", "item/recipe_slot_display_types");
|
||||
private static final VersionedRegistry<SlotDisplayType<?>> REGISTRY = new VersionedRegistry<>("slot_display");
|
||||
|
||||
private SlotDisplayTypes() {
|
||||
}
|
||||
|
||||
+2
@@ -21,6 +21,7 @@ package com.github.retrooper.packetevents.protocol.recipe.display.slot;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticSlotDisplayType<T extends SlotDisplay<?>> extends AbstractMappedEntity implements SlotDisplayType<T> {
|
||||
@@ -28,6 +29,7 @@ public class StaticSlotDisplayType<T extends SlotDisplay<?>> extends AbstractMap
|
||||
private final PacketWrapper.Reader<T> reader;
|
||||
private final PacketWrapper.Writer<T> writer;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticSlotDisplayType(
|
||||
@Nullable TypesBuilderData data,
|
||||
PacketWrapper.Reader<T> reader,
|
||||
|
||||
+10
-1
@@ -18,6 +18,7 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.score;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
public final class BlankScoreFormat implements ScoreFormat {
|
||||
@@ -27,13 +28,21 @@ public final class BlankScoreFormat implements ScoreFormat {
|
||||
private BlankScoreFormat() {
|
||||
}
|
||||
|
||||
public static BlankScoreFormat read(PacketWrapper<?> wrapper) {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, BlankScoreFormat format) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component format(int score) {
|
||||
return Component.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoreFormatType getType() {
|
||||
public ScoreFormatType<BlankScoreFormat> getType() {
|
||||
return ScoreFormatTypes.BLANK;
|
||||
}
|
||||
}
|
||||
+12
-3
@@ -18,6 +18,7 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.score;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
public final class FixedScoreFormat implements ScoreFormat {
|
||||
@@ -28,9 +29,12 @@ public final class FixedScoreFormat implements ScoreFormat {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoreFormatType getType() {
|
||||
return ScoreFormatTypes.FIXED;
|
||||
public static FixedScoreFormat read(PacketWrapper<?> wrapper) {
|
||||
return new FixedScoreFormat(wrapper.readComponent());
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, FixedScoreFormat format) {
|
||||
wrapper.writeComponent(format.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,6 +42,11 @@ public final class FixedScoreFormat implements ScoreFormat {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoreFormatType<FixedScoreFormat> getType() {
|
||||
return ScoreFormatTypes.FIXED;
|
||||
}
|
||||
|
||||
public Component getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
+12
-1
@@ -18,6 +18,7 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.score;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -37,7 +38,17 @@ public interface ScoreFormat {
|
||||
return new FixedScoreFormat(value);
|
||||
}
|
||||
|
||||
static ScoreFormat readTyped(PacketWrapper<?> wrapper) {
|
||||
return wrapper.readMappedEntity(ScoreFormatTypes.getRegistry()).read(wrapper);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // no
|
||||
static <T extends ScoreFormat> void writeTyped(PacketWrapper<?> wrapper, T format) {
|
||||
wrapper.writeMappedEntity(format.getType());
|
||||
((ScoreFormatType<T>) format.getType()).write(wrapper, format);
|
||||
}
|
||||
|
||||
Component format(int score);
|
||||
|
||||
ScoreFormatType getType();
|
||||
ScoreFormatType<?> getType();
|
||||
}
|
||||
+7
-3
@@ -21,9 +21,13 @@ package com.github.retrooper.packetevents.protocol.score;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.StaticMappedEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
public interface ScoreFormatType extends StaticMappedEntity {
|
||||
public interface ScoreFormatType<T extends ScoreFormat> extends StaticMappedEntity {
|
||||
|
||||
ScoreFormat read(PacketWrapper<?> wrapper);
|
||||
@Deprecated
|
||||
@Override
|
||||
int getId();
|
||||
|
||||
void write(PacketWrapper<?> wrapper, ScoreFormat format);
|
||||
T read(PacketWrapper<?> wrapper);
|
||||
|
||||
void write(PacketWrapper<?> wrapper, T format);
|
||||
}
|
||||
+50
-64
@@ -20,97 +20,83 @@ package com.github.retrooper.packetevents.protocol.score;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class ScoreFormatTypes {
|
||||
|
||||
private static final Map<String, ScoreFormatType> SCORE_FORMAT_TYPE_MAP = new HashMap<>();
|
||||
private static final Map<Byte, ScoreFormatType> SCORE_FORMAT_TYPE_ID_MAP = new HashMap<>();
|
||||
private static final VersionedRegistry<ScoreFormatType<?>> REGISTRY = new VersionedRegistry<>("number_format_type");
|
||||
|
||||
public static final ScoreFormatType BLANK = define(0, "blank", BlankScoreFormat.class,
|
||||
wrapper -> ScoreFormat.blankScore(),
|
||||
(wrapper, format) -> { /**/ });
|
||||
public static final ScoreFormatType STYLED = define(1, "styled", StyledScoreFormat.class,
|
||||
wrapper -> ScoreFormat.styledScore(wrapper.readStyle()),
|
||||
(wrapper, format) -> wrapper.writeStyle(format.getStyle()));
|
||||
public static final ScoreFormatType FIXED = define(2, "fixed", FixedScoreFormat.class,
|
||||
wrapper -> ScoreFormat.fixedScore(wrapper.readComponent()),
|
||||
(wrapper, format) -> wrapper.writeComponent(format.getValue()));
|
||||
public static final ScoreFormatType<BlankScoreFormat> BLANK = define("blank",
|
||||
BlankScoreFormat::read, BlankScoreFormat::write);
|
||||
public static final ScoreFormatType<StyledScoreFormat> STYLED = define("styled",
|
||||
StyledScoreFormat::read, StyledScoreFormat::write);
|
||||
public static final ScoreFormatType<FixedScoreFormat> FIXED = define("fixed",
|
||||
FixedScoreFormat::read, FixedScoreFormat::write);
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the score format types.
|
||||
* @return Score Format Types
|
||||
*/
|
||||
public static Collection<ScoreFormatType> values() {
|
||||
return Collections.unmodifiableCollection(SCORE_FORMAT_TYPE_MAP.values());
|
||||
static {
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
|
||||
private ScoreFormatTypes() {
|
||||
}
|
||||
|
||||
public static VersionedRegistry<ScoreFormatType<?>> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the score format types.
|
||||
*
|
||||
* @return Score Format Types
|
||||
*/
|
||||
public static Collection<ScoreFormatType<?>> values() {
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static ScoreFormat read(PacketWrapper<?> wrapper) {
|
||||
int formatTypeId = wrapper.readVarInt();
|
||||
ScoreFormatType formatType = getById(wrapper.getServerVersion().toClientVersion(), formatTypeId);
|
||||
if (formatType == null) {
|
||||
throw new NullPointerException("Can't resolve format type " + formatTypeId);
|
||||
}
|
||||
return formatType.read(wrapper);
|
||||
return ScoreFormat.readTyped(wrapper);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void write(PacketWrapper<?> wrapper, ScoreFormat format) {
|
||||
int formatTypeId = format.getType().getId(wrapper.getServerVersion().toClientVersion());
|
||||
wrapper.writeVarInt(formatTypeId);
|
||||
format.getType().write(wrapper, format);
|
||||
ScoreFormat.writeTyped(wrapper, format);
|
||||
}
|
||||
|
||||
public static <T extends ScoreFormat> ScoreFormatType define(int id, String name,
|
||||
Class<T> formatClass,
|
||||
Function<PacketWrapper<?>, T> reader,
|
||||
BiConsumer<PacketWrapper<?>, T> writer) {
|
||||
ResourceLocation location = new ResourceLocation(name);
|
||||
ScoreFormatType type = new ScoreFormatType() {
|
||||
@Override
|
||||
public ScoreFormat read(PacketWrapper<?> wrapper) {
|
||||
return reader.apply(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper<?> wrapper, ScoreFormat format) {
|
||||
writer.accept(wrapper, formatClass.cast(format));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
};
|
||||
SCORE_FORMAT_TYPE_MAP.put(location.toString(), type);
|
||||
SCORE_FORMAT_TYPE_ID_MAP.put((byte) id, type);
|
||||
return type;
|
||||
@Deprecated
|
||||
@ApiStatus.Internal
|
||||
public static <T extends ScoreFormat> ScoreFormatType<T> define(
|
||||
int id, String name, Class<T> formatClass,
|
||||
Function<PacketWrapper<?>, T> reader,
|
||||
BiConsumer<PacketWrapper<?>, T> writer
|
||||
) {
|
||||
return define(name, reader::apply, writer::accept);
|
||||
}
|
||||
|
||||
public static @Nullable ScoreFormatType getById(ClientVersion version, int id) {
|
||||
return SCORE_FORMAT_TYPE_ID_MAP.get((byte) id);
|
||||
@ApiStatus.Internal
|
||||
public static <T extends ScoreFormat> ScoreFormatType<T> define(
|
||||
String name, PacketWrapper.Reader<T> reader, PacketWrapper.Writer<T> writer
|
||||
) {
|
||||
return REGISTRY.define(name, data ->
|
||||
new StaticScoreFormatType<>(data, reader, writer));
|
||||
}
|
||||
|
||||
public static @Nullable ScoreFormatType getByName(String name) {
|
||||
return getByName(new ResourceLocation(name));
|
||||
public static @Nullable ScoreFormatType<?> getById(ClientVersion version, int id) {
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static @Nullable ScoreFormatType getByName(ResourceLocation name) {
|
||||
return SCORE_FORMAT_TYPE_MAP.get(name.toString());
|
||||
public static @Nullable ScoreFormatType<?> getByName(String name) {
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static @Nullable ScoreFormatType<?> getByName(ResourceLocation name) {
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.score;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticScoreFormatType<T extends ScoreFormat> extends AbstractMappedEntity implements ScoreFormatType<T> {
|
||||
|
||||
private final PacketWrapper.Reader<T> reader;
|
||||
private final PacketWrapper.Writer<T> writer;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticScoreFormatType(
|
||||
@Nullable TypesBuilderData data,
|
||||
PacketWrapper.Reader<T> reader,
|
||||
PacketWrapper.Writer<T> writer
|
||||
) {
|
||||
super(data);
|
||||
this.reader = reader;
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
|
||||
return this.getId(version.toClientVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(PacketWrapper<?> wrapper) {
|
||||
return this.reader.apply(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper<?> wrapper, T format) {
|
||||
this.writer.accept(wrapper, format);
|
||||
}
|
||||
}
|
||||
+13
-7
@@ -18,6 +18,7 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.score;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
|
||||
@@ -29,16 +30,21 @@ public final class StyledScoreFormat implements ScoreFormat {
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component format(int score) {
|
||||
return Component.text()
|
||||
.content(Integer.toString(score))
|
||||
.style(this.style)
|
||||
.build();
|
||||
public static StyledScoreFormat read(PacketWrapper<?> wrapper) {
|
||||
return new StyledScoreFormat(wrapper.readStyle());
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, StyledScoreFormat format) {
|
||||
wrapper.writeStyle(format.style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoreFormatType getType() {
|
||||
public Component format(int score) {
|
||||
return Component.text(Integer.toString(score), this.style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoreFormatType<StyledScoreFormat> getType() {
|
||||
return ScoreFormatTypes.STYLED;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,61 +20,31 @@ package com.github.retrooper.packetevents.protocol.sound;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
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 org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Sounds {
|
||||
public final class Sounds {
|
||||
|
||||
private static final Map<String, Sound> SOUND_TYPE_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, Sound>> SOUND_TYPE_ID_MAP = new HashMap<>();
|
||||
private static final VersionedRegistry<Sound> REGISTRY = new VersionedRegistry<>("sound_event");
|
||||
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("sound/sound_mappings");
|
||||
|
||||
public static Sound define(String key) {
|
||||
return define(key, new ResourceLocation(key), null);
|
||||
private Sounds() {
|
||||
}
|
||||
|
||||
public static Sound define(String key, ResourceLocation soundId, @Nullable Float range) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
Sound soundType = new Sound() {
|
||||
@Override
|
||||
public ResourceLocation getSoundId() {
|
||||
return soundId;
|
||||
}
|
||||
public static VersionedRegistry<Sound> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Float getRange() {
|
||||
return range;
|
||||
}
|
||||
@ApiStatus.Internal
|
||||
public static Sound define(String name) {
|
||||
return define(name, new ResourceLocation(name), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
return MappingHelper.getId(version, TYPES_BUILDER, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Sound) {
|
||||
return getName().equals(((Sound) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, SOUND_TYPE_MAP, SOUND_TYPE_ID_MAP, soundType);
|
||||
return soundType;
|
||||
@ApiStatus.Internal
|
||||
public static Sound define(String name, ResourceLocation soundId, @Nullable Float range) {
|
||||
return REGISTRY.define(name, data -> new StaticSound(data, soundId, range));
|
||||
}
|
||||
|
||||
public static Sound getByNameOrCreate(String name) {
|
||||
@@ -86,13 +56,11 @@ public class Sounds {
|
||||
}
|
||||
|
||||
public static @Nullable Sound getByName(String name) {
|
||||
return SOUND_TYPE_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static @Nullable Sound getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, Sound> idMap = SOUND_TYPE_ID_MAP.get((byte) index);
|
||||
return idMap.get(id);
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static final Sound ENTITY_ALLAY_AMBIENT_WITH_ITEM = define("entity.allay.ambient_with_item");
|
||||
@@ -1779,10 +1747,10 @@ public class Sounds {
|
||||
* @return Sounds
|
||||
*/
|
||||
public static Collection<Sound> values() {
|
||||
return Collections.unmodifiableCollection(SOUND_TYPE_MAP.values());
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
+14
-18
@@ -18,18 +18,26 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.sound;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class StaticSound implements Sound {
|
||||
public class StaticSound extends AbstractMappedEntity implements Sound {
|
||||
|
||||
private final ResourceLocation soundId;
|
||||
private final @Nullable Float range;
|
||||
|
||||
public StaticSound(ResourceLocation soundId, @Nullable Float range) {
|
||||
this(null, soundId, range);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticSound(@Nullable TypesBuilderData data, ResourceLocation soundId, @Nullable Float range) {
|
||||
super(data);
|
||||
this.soundId = soundId;
|
||||
this.range = range;
|
||||
}
|
||||
@@ -44,32 +52,20 @@ public class StaticSound implements Sound {
|
||||
return this.range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegistered() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof StaticSound)) return false;
|
||||
StaticSound that = (StaticSound) obj;
|
||||
if (this.isRegistered()) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
if (!this.soundId.equals(that.soundId)) return false;
|
||||
return Objects.equals(this.range, that.range);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.soundId, this.range);
|
||||
return this.isRegistered() ? super.hashCode() : Objects.hash(this.soundId, this.range);
|
||||
}
|
||||
}
|
||||
@@ -44,14 +44,15 @@ public class Statistics {
|
||||
|
||||
if (version.isOlderThan(ServerVersion.V_1_12_2)) {
|
||||
|
||||
try (final SequentialNBTReader.Compound mapping = MappingHelper.decompress("mappings/stats/statistics")) {
|
||||
mapping.skipOne(); //Skip version
|
||||
try (final SequentialNBTReader.Compound rootMapping = MappingHelper.decompress("mappings/data/statistics")) {
|
||||
rootMapping.skipOne(); //Skip version
|
||||
SequentialNBTReader.Compound mapping = (SequentialNBTReader.Compound) rootMapping.next().getValue();
|
||||
|
||||
if (version.isOlderThanOrEquals(ServerVersion.V_1_8_3)) {
|
||||
mapping.skipOne(); // Skip to version 1.8
|
||||
}
|
||||
|
||||
SequentialNBTReader.Compound toLoad = (SequentialNBTReader.Compound) mapping.next();
|
||||
SequentialNBTReader.Compound toLoad = (SequentialNBTReader.Compound) mapping.next().getValue();
|
||||
|
||||
for (Map.Entry<String, NBT> entry : toLoad) {
|
||||
String value = ((NBTString) entry.getValue()).getValue();
|
||||
|
||||
@@ -101,16 +101,16 @@ public class Dimension {
|
||||
|
||||
public com.github.retrooper.packetevents.protocol.world.dimension.DimensionType asDimensionType(
|
||||
@Nullable User user, @Nullable ClientVersion version) {
|
||||
IRegistry<com.github.retrooper.packetevents.protocol.world.dimension.DimensionType> registry = user != null
|
||||
? user.getRegistryOr(DimensionTypes.getRegistry()) : DimensionTypes.getRegistry();
|
||||
String dimName = this.getDimensionName();
|
||||
if (!dimName.isEmpty()) {
|
||||
return registry.getByName(new ResourceLocation(dimName));
|
||||
}
|
||||
if (version == null) {
|
||||
version = user != null && PacketEvents.getAPI().getInjector().isProxy() ? user.getClientVersion() :
|
||||
PacketEvents.getAPI().getServerManager().getVersion().toClientVersion();
|
||||
}
|
||||
IRegistry<com.github.retrooper.packetevents.protocol.world.dimension.DimensionType> registry = user != null
|
||||
? user.getRegistryOr(DimensionTypes.getRegistry(), version) : DimensionTypes.getRegistry();
|
||||
String dimName = this.getDimensionName();
|
||||
if (!dimName.isEmpty()) {
|
||||
return registry.getByName(new ResourceLocation(dimName));
|
||||
}
|
||||
return registry.getById(version, this.id);
|
||||
}
|
||||
|
||||
|
||||
+4
-8
@@ -33,20 +33,16 @@ import java.util.Map;
|
||||
|
||||
public final class Biomes {
|
||||
|
||||
private static final VersionedRegistry<Biome> REGISTRY = new VersionedRegistry<>(
|
||||
"worldgen/biome", "world/biome_mappings");
|
||||
private static final VersionedRegistry<Biome> REGISTRY = new VersionedRegistry<>("worldgen/biome");
|
||||
|
||||
// load data from file, biomes are too complex to define in code here
|
||||
private static final Map<ResourceLocation, NBTCompound> BIOME_DATA;
|
||||
|
||||
static {
|
||||
BIOME_DATA = new HashMap<>();
|
||||
try (SequentialNBTReader.Compound dataTag = MappingHelper.decompress("mappings/world/biome_data")) {
|
||||
while (dataTag.hasNext()) {
|
||||
Map.Entry<String, NBT> entry = dataTag.next();
|
||||
if (entry.getKey().equals("version")) {
|
||||
continue; // skip version field
|
||||
}
|
||||
try (SequentialNBTReader.Compound dataTag = MappingHelper.decompress("mappings/data/worldgen/biome")) {
|
||||
dataTag.skipOne(); // skip version
|
||||
for (Map.Entry<String, NBT> entry : (SequentialNBTReader.Compound) dataTag.next().getValue()) {
|
||||
ResourceLocation biomeKey = new ResourceLocation(entry.getKey());
|
||||
BIOME_DATA.put(biomeKey, ((SequentialNBTReader.Compound) entry.getValue()).readFully());
|
||||
}
|
||||
|
||||
+4
@@ -43,12 +43,14 @@ public class StaticBiome extends AbstractMappedEntity implements Biome {
|
||||
this(null, precipitation, temperature, temperatureModifier, downfall, effects);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
@ApiStatus.Obsolete
|
||||
public StaticBiome(@Nullable TypesBuilderData data, Precipitation precipitation, float temperature,
|
||||
TemperatureModifier temperatureModifier, float downfall, BiomeEffects effects) {
|
||||
this(data, precipitation != Precipitation.NONE, temperature, temperatureModifier, downfall, effects);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticBiome(
|
||||
@Nullable TypesBuilderData data, boolean precipitation,
|
||||
float temperature, TemperatureModifier temperatureModifier,
|
||||
@@ -67,6 +69,7 @@ public class StaticBiome extends AbstractMappedEntity implements Biome {
|
||||
category, depth, scale, effects);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
@ApiStatus.Obsolete
|
||||
public StaticBiome(@Nullable TypesBuilderData data, Precipitation precipitation, float temperature,
|
||||
TemperatureModifier temperatureModifier, float downfall, @Nullable Category category,
|
||||
@@ -75,6 +78,7 @@ public class StaticBiome extends AbstractMappedEntity implements Biome {
|
||||
downfall, category, depth, scale, effects);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticBiome(
|
||||
@Nullable TypesBuilderData data, boolean precipitation,
|
||||
float temperature, TemperatureModifier temperatureModifier,
|
||||
|
||||
+1
-2
@@ -25,8 +25,7 @@ import java.util.Collection;
|
||||
|
||||
public final class BlockEntityTypes {
|
||||
|
||||
private static final VersionedRegistry<BlockEntityType> REGISTRY = new VersionedRegistry<>(
|
||||
"block_entity_type", "block/block_entity_type_mappings");
|
||||
private static final VersionedRegistry<BlockEntityType> REGISTRY = new VersionedRegistry<>("block_entity_type");
|
||||
|
||||
private BlockEntityTypes() {
|
||||
}
|
||||
|
||||
+4
-1
@@ -20,10 +20,13 @@ package com.github.retrooper.packetevents.protocol.world.blockentity;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticBlockEntityType extends AbstractMappedEntity implements BlockEntityType {
|
||||
|
||||
StaticBlockEntityType(TypesBuilderData data) {
|
||||
@ApiStatus.Internal
|
||||
public StaticBlockEntityType(@Nullable TypesBuilderData data) {
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -24,9 +24,9 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class DamageTypes {
|
||||
private static final VersionedRegistry<DamageType> REGISTRY = new VersionedRegistry<>("damage_type",
|
||||
"damage/damagetype_mappings");
|
||||
public final class DamageTypes {
|
||||
|
||||
private static final VersionedRegistry<DamageType> REGISTRY = new VersionedRegistry<>("damage_type");
|
||||
|
||||
private DamageTypes() {
|
||||
}
|
||||
|
||||
+12
-8
@@ -20,21 +20,25 @@ package com.github.retrooper.packetevents.protocol.world.damagetype;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class StaticDamageType extends AbstractMappedEntity implements DamageType {
|
||||
private String messageId;
|
||||
private DamageScaling scaling;
|
||||
private float exhaustion;
|
||||
private DamageEffects effects;
|
||||
private DeathMessageType deathMessageType;
|
||||
|
||||
protected StaticDamageType(@Nullable TypesBuilderData data, String messageId, DamageScaling scaling,
|
||||
float exhaustion, DamageEffects effects, DeathMessageType deathMessageType) {
|
||||
private final String messageId;
|
||||
private final DamageScaling scaling;
|
||||
private final float exhaustion;
|
||||
private final DamageEffects effects;
|
||||
private final DeathMessageType deathMessageType;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticDamageType(
|
||||
@Nullable TypesBuilderData data, String messageId, DamageScaling scaling,
|
||||
float exhaustion, DamageEffects effects, DeathMessageType deathMessageType
|
||||
) {
|
||||
super(data);
|
||||
|
||||
this.messageId = messageId;
|
||||
this.scaling = scaling;
|
||||
this.exhaustion = exhaustion;
|
||||
|
||||
+1
-2
@@ -29,8 +29,7 @@ import java.util.OptionalLong;
|
||||
|
||||
public final class DimensionTypes {
|
||||
|
||||
private static final VersionedRegistry<DimensionType> REGISTRY = new VersionedRegistry<>(
|
||||
"dimension_type", "world/dimension_type_mappings");
|
||||
private static final VersionedRegistry<DimensionType> REGISTRY = new VersionedRegistry<>("dimension_type");
|
||||
|
||||
private DimensionTypes() {
|
||||
}
|
||||
|
||||
+2
@@ -23,6 +23,7 @@ import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -61,6 +62,7 @@ public class StaticDimensionType extends AbstractMappedEntity implements Dimensi
|
||||
monsterSpawnLightLevel, monsterSpawnBlockLightLimit);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticDimensionType(
|
||||
@Nullable TypesBuilderData data, OptionalLong fixedTime, boolean hasSkyLight, boolean hasCeiling,
|
||||
boolean ultraWarm, boolean natural, double coordinateScale, boolean bedWorking, boolean respawnAnchorWorking,
|
||||
|
||||
+1
-2
@@ -26,8 +26,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class PaintingVariants {
|
||||
|
||||
private static final VersionedRegistry<PaintingVariant> REGISTRY = new VersionedRegistry<>(
|
||||
"painting_variant", "entity/painting_mappings");
|
||||
private static final VersionedRegistry<PaintingVariant> REGISTRY = new VersionedRegistry<>("painting_variant");
|
||||
|
||||
private PaintingVariants() {
|
||||
}
|
||||
|
||||
+2
@@ -21,6 +21,7 @@ package com.github.retrooper.packetevents.protocol.world.painting;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -35,6 +36,7 @@ public class StaticPaintingVariant extends AbstractMappedEntity implements Paint
|
||||
this(null, width, height, assetId);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticPaintingVariant(@Nullable TypesBuilderData data, int width, int height, ResourceLocation assetId) {
|
||||
super(data);
|
||||
this.width = width;
|
||||
|
||||
+16
-62
@@ -22,85 +22,39 @@ import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.positionsource.builtin.BlockPositionSource;
|
||||
import com.github.retrooper.packetevents.protocol.world.positionsource.builtin.EntityPositionSource;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
public final class PositionSourceTypes {
|
||||
|
||||
public class PositionSourceTypes {
|
||||
private static final VersionedRegistry<PositionSourceType<?>> REGISTRY = new VersionedRegistry<>("position_source_type");
|
||||
|
||||
private static final Map<String, PositionSourceType<?>> POS_SOURCE_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, PositionSourceType<?>>> POS_SOURCE_ID_MAP = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("world/world_position_source_mappings");
|
||||
private PositionSourceTypes() {
|
||||
}
|
||||
|
||||
public static VersionedRegistry<PositionSourceType<?>> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static <T extends PositionSource> PositionSourceType<T> define(
|
||||
String key,
|
||||
String name,
|
||||
Reader<T> reader, Writer<T> writer,
|
||||
Decoder<T> decoder, Encoder<T> encoder
|
||||
) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
PositionSourceType<T> sourceType = new PositionSourceType<T>() {
|
||||
@Override
|
||||
public T read(PacketWrapper<?> wrapper) {
|
||||
return reader.apply(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper<?> wrapper, T source) {
|
||||
writer.accept(wrapper, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T decode(NBTCompound compound, ClientVersion version) {
|
||||
return decoder.decode(compound, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(T source, ClientVersion version, NBTCompound compound) {
|
||||
encoder.encode(source, version, compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
return MappingHelper.getId(version, TYPES_BUILDER, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof PositionSourceType<?>) {
|
||||
return this.getName().equals(((PositionSourceType<?>) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, POS_SOURCE_MAP, POS_SOURCE_ID_MAP, sourceType);
|
||||
return sourceType;
|
||||
return REGISTRY.define(name, data -> new StaticPositionSourceType<>(
|
||||
data, reader, writer, decoder, encoder));
|
||||
}
|
||||
|
||||
// with minecraft:key
|
||||
@Nullable
|
||||
public static PositionSourceType<?> getByName(String name) {
|
||||
return POS_SOURCE_MAP.get(name);
|
||||
public static @Nullable PositionSourceType<?> getByName(String name) {
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static PositionSourceType<?> getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, PositionSourceType<?>> idMap = POS_SOURCE_ID_MAP.get((byte) index);
|
||||
return idMap.get(id);
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static final PositionSourceType<BlockPositionSource> BLOCK = define("block",
|
||||
@@ -111,7 +65,7 @@ public class PositionSourceTypes {
|
||||
EntityPositionSource::decodeSource, EntityPositionSource::encodeSource);
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.world.positionsource;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticPositionSourceType<T extends PositionSource> extends AbstractMappedEntity implements PositionSourceType<T> {
|
||||
|
||||
private final PacketWrapper.Reader<T> reader;
|
||||
private final PacketWrapper.Writer<T> writer;
|
||||
private final PositionSourceTypes.Decoder<T> decoder;
|
||||
private final PositionSourceTypes.Encoder<T> encoder;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StaticPositionSourceType(
|
||||
@Nullable TypesBuilderData data,
|
||||
PacketWrapper.Reader<T> reader,
|
||||
PacketWrapper.Writer<T> writer,
|
||||
PositionSourceTypes.Decoder<T> decoder,
|
||||
PositionSourceTypes.Encoder<T> encoder
|
||||
) {
|
||||
super(data);
|
||||
this.reader = reader;
|
||||
this.writer = writer;
|
||||
this.decoder = decoder;
|
||||
this.encoder = encoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(PacketWrapper<?> wrapper) {
|
||||
return this.reader.apply(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper<?> wrapper, T source) {
|
||||
this.writer.accept(wrapper, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T decode(NBTCompound compound, ClientVersion version) {
|
||||
return this.decoder.decode(compound, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(T source, ClientVersion version, NBTCompound compound) {
|
||||
this.encoder.encode(source, version, compound);
|
||||
}
|
||||
}
|
||||
+261
-197
@@ -5,10 +5,8 @@ import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTByte;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTLimiter;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.serializer.DefaultNBTSerializer;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.serializer.SequentialNBTReader;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
@@ -38,20 +36,19 @@ import com.github.retrooper.packetevents.protocol.world.states.enums.West;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateValue;
|
||||
import com.github.retrooper.packetevents.util.BinaryNBTCompound;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.github.retrooper.packetevents.util.adventure.AdventureIndexUtil.indexValueOrThrow;
|
||||
|
||||
@@ -68,60 +65,68 @@ import static com.github.retrooper.packetevents.util.adventure.AdventureIndexUti
|
||||
*/
|
||||
public class WrappedBlockState {
|
||||
|
||||
// all versions where block state mappings were changed TODO UPDATE
|
||||
private static final ClientVersion[] MAPPING_VERSION_STEPS = new ClientVersion[]{
|
||||
ClientVersion.V_1_13, ClientVersion.V_1_13_2, ClientVersion.V_1_14, ClientVersion.V_1_15,
|
||||
ClientVersion.V_1_16, ClientVersion.V_1_16_2, ClientVersion.V_1_17, ClientVersion.V_1_19,
|
||||
ClientVersion.V_1_19_3, ClientVersion.V_1_19_4, ClientVersion.V_1_20, ClientVersion.V_1_20_2,
|
||||
ClientVersion.V_1_20_3, ClientVersion.V_1_20_5, ClientVersion.V_1_21_2, ClientVersion.V_1_21_4,
|
||||
};
|
||||
private static final byte[] MAPPING_INDEXES;
|
||||
private static final byte LEGACY_MAPPING_INDEX = 0;
|
||||
private static final ClientVersion[] MAPPING_VERSIONS;
|
||||
|
||||
private static final byte AIR_MAPPING_INDEX = 0;
|
||||
private static final byte LEGACY_MAPPING_INDEX = 1;
|
||||
private static final byte HIGHEST_MAPPING_INDEX;
|
||||
|
||||
private static final String MAPPINGS_ASSETS_PREFIX = "mappings/data/block_state/";
|
||||
private static final String MAPPINGS_ASSETS_LEGACY = MAPPINGS_ASSETS_PREFIX + "legacy";
|
||||
private static final boolean PRELOAD_BLOCK_STATE_MAPPINGS = Boolean.getBoolean("packetevents.mappings.preload");
|
||||
|
||||
static {
|
||||
// all versions where block state mappings were changed TODO UPDATE
|
||||
ClientVersion[] mappingSteps = new ClientVersion[]{
|
||||
ClientVersion.V_1_13, ClientVersion.V_1_13_2, ClientVersion.V_1_14, ClientVersion.V_1_15,
|
||||
ClientVersion.V_1_16, ClientVersion.V_1_16_2, ClientVersion.V_1_17, ClientVersion.V_1_19,
|
||||
ClientVersion.V_1_19_3, ClientVersion.V_1_19_4, ClientVersion.V_1_20, ClientVersion.V_1_20_2,
|
||||
ClientVersion.V_1_20_3, ClientVersion.V_1_20_5, ClientVersion.V_1_21_2, ClientVersion.V_1_21_4,
|
||||
};
|
||||
|
||||
ClientVersion[] versions = ClientVersion.values();
|
||||
MAPPING_INDEXES = new byte[versions.length];
|
||||
MAPPING_VERSIONS = new ClientVersion[versions.length];
|
||||
|
||||
ClientVersion mappingVersion = versions[0];
|
||||
for (int i = 0, j = 0; i < versions.length; i++) {
|
||||
ClientVersion version = versions[i];
|
||||
if (j < mappingSteps.length
|
||||
&& version == mappingSteps[j]) {
|
||||
if (j < MAPPING_VERSION_STEPS.length && version == MAPPING_VERSION_STEPS[j]) {
|
||||
j++;
|
||||
mappingVersion = version;
|
||||
}
|
||||
MAPPING_INDEXES[version.ordinal()] = (byte) (LEGACY_MAPPING_INDEX + j);
|
||||
MAPPING_VERSIONS[version.ordinal()] = mappingVersion;
|
||||
}
|
||||
HIGHEST_MAPPING_INDEX = MAPPING_INDEXES[versions.length - 1];
|
||||
}
|
||||
|
||||
private static final WrappedBlockState AIR = new WrappedBlockState(StateTypes.AIR, new EnumMap<>(StateValue.class), 0, (byte) 0);
|
||||
private static final Map<Byte, Map<String, WrappedBlockState>> BY_STRING = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, WrappedBlockState>> BY_ID = new HashMap<>();
|
||||
private static final Map<Byte, Map<WrappedBlockState, String>> INTO_STRING = new HashMap<>();
|
||||
private static final Map<Byte, Map<WrappedBlockState, Integer>> INTO_ID = new HashMap<>();
|
||||
private static final Map<Byte, Map<StateType, WrappedBlockState>> DEFAULT_STATES = new HashMap<>();
|
||||
private static final WrappedBlockState AIR = new WrappedBlockState(StateTypes.AIR,
|
||||
new EnumMap<>(StateValue.class), 0, AIR_MAPPING_INDEX);
|
||||
private static final Map<String, WrappedBlockState>[] BY_STRING = new Map[HIGHEST_MAPPING_INDEX + 1];
|
||||
private static final Map<Integer, WrappedBlockState>[] BY_ID = new Map[HIGHEST_MAPPING_INDEX + 1];
|
||||
private static final Map<WrappedBlockState, String>[] INTO_STRING = new Map[HIGHEST_MAPPING_INDEX + 1];
|
||||
private static final Map<WrappedBlockState, Integer>[] INTO_ID = new Map[HIGHEST_MAPPING_INDEX + 1];
|
||||
private static final Map<StateType, WrappedBlockState>[] DEFAULT_STATES = new Map[HIGHEST_MAPPING_INDEX + 1];
|
||||
|
||||
private static final Map<String, String> STRING_UPDATER = new HashMap<>();
|
||||
|
||||
static {
|
||||
STRING_UPDATER.put("grass_path", "dirt_path"); // 1.16 -> 1.17
|
||||
|
||||
// Try to reduce memory footprint by re-using hashmaps when they are equal
|
||||
// We do this by setting the key to the NBTCompound of the data and the value to the data
|
||||
// this.data = cache.computeIfAbsent(dataContent, (key) -> { // NBTCompound to data });
|
||||
// This will get an equal value if present, otherwise it will compute the value
|
||||
// Once this is done, we remove this cache to save memory
|
||||
// A HashMap is used instead of another data type because a hashmap is o(1)
|
||||
//
|
||||
// 6160 total combinations, last updated with 1.20.5
|
||||
// This brings total memory usage from 62 MB to 34 MB, a 28 MB reduction
|
||||
// Using a HashMap reduces memory usage to less than a megabyte, I can't get precise numbers because it is hard to see on a heapdump
|
||||
Map<BinaryNBTCompound, Map.Entry<Map<StateValue, Object>, String>> cache = new HashMap<>(6160, 70);
|
||||
Arrays.fill(BY_STRING, Collections.emptyMap());
|
||||
Arrays.fill(BY_ID, Collections.emptyMap());
|
||||
Arrays.fill(INTO_STRING, Collections.emptyMap());
|
||||
Arrays.fill(INTO_ID, Collections.emptyMap());
|
||||
Arrays.fill(DEFAULT_STATES, Collections.emptyMap());
|
||||
|
||||
loadLegacy(cache);
|
||||
loadModern(cache);
|
||||
|
||||
cache.clear();
|
||||
cache = null;
|
||||
// because AIR is a constant, preload all data for this into a separate mapping index
|
||||
String airName = AIR.getType().getMapped().getName().getKey();
|
||||
BY_STRING[AIR_MAPPING_INDEX] = Collections.singletonMap(airName, AIR);
|
||||
BY_ID[AIR_MAPPING_INDEX] = Collections.singletonMap(AIR.getGlobalId(), AIR);
|
||||
INTO_STRING[AIR_MAPPING_INDEX] = Collections.singletonMap(AIR, airName);
|
||||
INTO_ID[AIR_MAPPING_INDEX] = Collections.singletonMap(AIR, AIR.getGlobalId());
|
||||
DEFAULT_STATES[AIR_MAPPING_INDEX] = Collections.singletonMap(AIR.getType(), AIR);
|
||||
}
|
||||
|
||||
int globalID;
|
||||
@@ -158,6 +163,57 @@ public class WrappedBlockState {
|
||||
this.mappingsIndex = mappingsIndex;
|
||||
}
|
||||
|
||||
private static byte loadMappings(ClientVersion version) {
|
||||
byte mappingsIndex = getMappingsIndex(version);
|
||||
if (!PRELOAD_BLOCK_STATE_MAPPINGS && BY_ID[mappingsIndex].isEmpty()) {
|
||||
loadMappings0(getMappingsVersion(version), mappingsIndex); // try to load mappings
|
||||
}
|
||||
return mappingsIndex;
|
||||
}
|
||||
|
||||
private static synchronized void loadMappings0(ClientVersion version, byte mappingsIndex) {
|
||||
if (!BY_ID[mappingsIndex].isEmpty()) {
|
||||
return; // already loaded
|
||||
}
|
||||
PacketEvents.getAPI().getLogger().info("Loading block mappings for " + version + "/" + mappingsIndex + "...");
|
||||
long start = System.nanoTime();
|
||||
|
||||
if (mappingsIndex == LEGACY_MAPPING_INDEX) {
|
||||
loadLegacy(buildStateDataCache());
|
||||
} else {
|
||||
loadModern(buildStateDataCache(), version);
|
||||
}
|
||||
|
||||
double timeDiff = (System.nanoTime() - start) / 1_000_000d;
|
||||
PacketEvents.getAPI().getLogger().info("Finished loading block mappings for "
|
||||
+ version + "/" + mappingsIndex + " in " + timeDiff + "ms");
|
||||
}
|
||||
|
||||
private static Map<Map<StateValue, Object>, StateCacheValue> buildStateDataCache() {
|
||||
// Try to reduce memory footprint by re-using hashmaps when they are equal
|
||||
// We do this by setting the key to the NBTCompound of the data and the value to the data
|
||||
// this.data = cache.computeIfAbsent(dataContent, (key) -> { // NBTCompound to data });
|
||||
// This will get an equal value if present, otherwise it will compute the value
|
||||
// Once this is done, we remove this cache to save memory
|
||||
// A HashMap is used instead of another data type because a hashmap is o(1)
|
||||
//
|
||||
// 6160 total combinations, last updated with 1.20.5
|
||||
// This brings total memory usage from 62 MB to 34 MB, a 28 MB reduction
|
||||
// Using a HashMap reduces memory usage to less than a megabyte, I can't get precise numbers because it is hard to see on a heapdump
|
||||
|
||||
Map<Map<StateValue, Object>, StateCacheValue> cache = new HashMap<>();
|
||||
for (byte i = 0; i < HIGHEST_MAPPING_INDEX; i++) {
|
||||
Map<Integer, WrappedBlockState> map = BY_ID[i];
|
||||
if (map == null) {
|
||||
continue; // not loaded yet
|
||||
}
|
||||
for (WrappedBlockState state : map.values()) {
|
||||
cache.computeIfAbsent(state.data, StateCacheValue::new);
|
||||
}
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
public static WrappedBlockState decode(NBT nbt, ClientVersion version) {
|
||||
if (nbt instanceof NBTString) {
|
||||
StateType type = StateTypes.getByName(((NBTString) nbt).getValue());
|
||||
@@ -241,8 +297,8 @@ public class WrappedBlockState {
|
||||
@NotNull
|
||||
public static WrappedBlockState getByGlobalId(ClientVersion version, int globalID, boolean clone) {
|
||||
if (globalID == 0) return AIR; // Hardcode for performance
|
||||
byte mappingsIndex = getMappingsIndex(version);
|
||||
final WrappedBlockState state = BY_ID.get(mappingsIndex).getOrDefault(globalID, AIR);
|
||||
byte mappingsIndex = loadMappings(version);
|
||||
final WrappedBlockState state = BY_ID[mappingsIndex].getOrDefault(globalID, AIR);
|
||||
return clone ? state.clone() : state;
|
||||
}
|
||||
|
||||
@@ -258,8 +314,8 @@ public class WrappedBlockState {
|
||||
|
||||
@NotNull
|
||||
public static WrappedBlockState getByString(ClientVersion version, String string, boolean clone) {
|
||||
byte mappingsIndex = getMappingsIndex(version);
|
||||
final WrappedBlockState state = BY_STRING.get(mappingsIndex).getOrDefault(string.replace("minecraft:", ""), AIR);
|
||||
byte mappingsIndex = loadMappings(version);
|
||||
final WrappedBlockState state = BY_STRING[mappingsIndex].getOrDefault(string.replace("minecraft:", ""), AIR);
|
||||
return clone ? state.clone() : state;
|
||||
}
|
||||
|
||||
@@ -276,8 +332,8 @@ public class WrappedBlockState {
|
||||
@NotNull
|
||||
public static WrappedBlockState getDefaultState(ClientVersion version, StateType type, boolean clone) {
|
||||
if (type == StateTypes.AIR) return AIR;
|
||||
byte mappingsIndex = getMappingsIndex(version);
|
||||
WrappedBlockState state = DEFAULT_STATES.get(mappingsIndex).get(type);
|
||||
byte mappingsIndex = loadMappings(version);
|
||||
WrappedBlockState state = DEFAULT_STATES[mappingsIndex].get(type);
|
||||
if (state == null) {
|
||||
PacketEvents.getAPI().getLogger().config("Default state for " + type.getName() + " is null. Returning AIR");
|
||||
return AIR;
|
||||
@@ -289,17 +345,21 @@ public class WrappedBlockState {
|
||||
return MAPPING_INDEXES[version.ordinal()];
|
||||
}
|
||||
|
||||
private static void loadLegacy(Map<BinaryNBTCompound, Map.Entry<Map<StateValue, Object>, String>> cache) {
|
||||
private static ClientVersion getMappingsVersion(ClientVersion version) {
|
||||
return MAPPING_VERSIONS[version.ordinal()];
|
||||
}
|
||||
|
||||
private static void loadLegacy(Map<Map<StateValue, Object>, StateCacheValue> cache) {
|
||||
Map<Integer, WrappedBlockState> stateByIdMap = new HashMap<>();
|
||||
Map<WrappedBlockState, Integer> stateToIdMap = new HashMap<>();
|
||||
Map<String, WrappedBlockState> stateByStringMap = new HashMap<>();
|
||||
Map<WrappedBlockState, String> stateToStringMap = new HashMap<>();
|
||||
Map<StateType, WrappedBlockState> stateTypeToBlockStateMap = new HashMap<>();
|
||||
|
||||
try (final SequentialNBTReader.Compound compound = MappingHelper.decompress("mappings/block/legacy_block_mappings")) {
|
||||
try (final SequentialNBTReader.Compound compound = MappingHelper.decompress(MAPPINGS_ASSETS_LEGACY)) {
|
||||
compound.skipOne(); // Skip version
|
||||
|
||||
for (Map.Entry<String, NBT> entry : compound) {
|
||||
for (Map.Entry<String, NBT> entry : (SequentialNBTReader.Compound) compound.next().getValue()) {
|
||||
SequentialNBTReader.Compound inner = (SequentialNBTReader.Compound) entry.getValue();
|
||||
|
||||
StateType type = StateTypes.getByName(entry.getKey());
|
||||
@@ -310,31 +370,23 @@ public class WrappedBlockState {
|
||||
}
|
||||
|
||||
for (Map.Entry<String, NBT> element : inner) {
|
||||
String[] ids = element.getKey().split(":");
|
||||
int id = Integer.parseInt(ids[0]);
|
||||
int data = Integer.parseInt(ids[1]);
|
||||
String elementName = element.getKey();
|
||||
int idIndex = elementName.indexOf(':');
|
||||
int id = Integer.parseInt(elementName.substring(0, idIndex));
|
||||
int data = Integer.parseInt(elementName.substring(idIndex + 1));
|
||||
int combinedID = (id << 4) | data;
|
||||
|
||||
SequentialNBTReader.Compound dataContent = (SequentialNBTReader.Compound) element.getValue();
|
||||
Map.Entry<Map<StateValue, Object>, String> dataEntry = cache.computeIfAbsent(new BinaryNBTCompound(dataContent.readFullyAsBytes()), (bin) -> {
|
||||
NBTCompound key;
|
||||
try (ByteArrayInputStream stream = new ByteArrayInputStream(bin.getData()); DataInputStream in = new DataInputStream(stream)) {
|
||||
key = (NBTCompound) DefaultNBTSerializer.INSTANCE.deserializeTag(NBTLimiter.noop(), in, false);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to load legacy block mappings", e);
|
||||
}
|
||||
|
||||
StringBuilder dataStringBuilder = new StringBuilder();
|
||||
Map<StateValue, Object> dataMap = new HashMap<>(key.size());
|
||||
|
||||
for (Map.Entry<String, NBT> props : key.getTags().entrySet()) {
|
||||
StateCacheValue stateCache;
|
||||
if (dataContent.hasNext()) { // only try to read if there is data available
|
||||
Map<StateValue, Object> dataMap = new HashMap<>(3);
|
||||
for (Map.Entry<String, NBT> props : dataContent) {
|
||||
StateValue state = StateValue.byName(props.getKey());
|
||||
if (state == null) {
|
||||
PacketEvents.getAPI().getLogger().warning("Could not find value for " + props.getKey());
|
||||
continue;
|
||||
}
|
||||
|
||||
dataStringBuilder.append(props.getKey()).append("=");
|
||||
NBT value = props.getValue();
|
||||
Object v;
|
||||
if (value instanceof NBTByte) {
|
||||
@@ -345,26 +397,17 @@ public class WrappedBlockState {
|
||||
v = ((NBTString) value).getValue();
|
||||
} else {
|
||||
PacketEvents.getAPI().getLogger().warning("Unknown NBT type in legacy mapping: " + value.getClass().getSimpleName());
|
||||
dataStringBuilder = new StringBuilder(dataStringBuilder.substring(0, dataStringBuilder.length() - props.getKey().length() - 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
dataStringBuilder.append(v).append(",");
|
||||
dataMap.put(state, state.getParser().apply(v.toString().toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
stateCache = cache.computeIfAbsent(dataMap, StateCacheValue::new);
|
||||
} else {
|
||||
stateCache = StateCacheValue.EMPTY;
|
||||
}
|
||||
|
||||
String dataString;
|
||||
if (dataStringBuilder.length() == 0) {
|
||||
dataString = "";
|
||||
} else {
|
||||
dataString = "[" + dataStringBuilder.substring(0, dataStringBuilder.length() - 1) + "]";
|
||||
}
|
||||
|
||||
return new AbstractMap.SimpleEntry<>(dataMap, dataString);
|
||||
});
|
||||
|
||||
String fullString = entry.getKey() + dataEntry.getValue();
|
||||
WrappedBlockState state = new WrappedBlockState(type, dataEntry.getKey(), combinedID, (byte) 0);
|
||||
String fullString = entry.getKey() + stateCache.getString();
|
||||
WrappedBlockState state = new WrappedBlockState(type, stateCache.map, combinedID, LEGACY_MAPPING_INDEX);
|
||||
|
||||
stateByIdMap.put(combinedID, state);
|
||||
stateToStringMap.put(state, fullString);
|
||||
@@ -380,134 +423,113 @@ public class WrappedBlockState {
|
||||
}
|
||||
}
|
||||
|
||||
BY_ID.put(LEGACY_MAPPING_INDEX, stateByIdMap);
|
||||
INTO_ID.put(LEGACY_MAPPING_INDEX, stateToIdMap);
|
||||
BY_STRING.put(LEGACY_MAPPING_INDEX, stateByStringMap);
|
||||
INTO_STRING.put(LEGACY_MAPPING_INDEX, stateToStringMap);
|
||||
DEFAULT_STATES.put(LEGACY_MAPPING_INDEX, stateTypeToBlockStateMap);
|
||||
BY_ID[LEGACY_MAPPING_INDEX] = stateByIdMap;
|
||||
INTO_ID[LEGACY_MAPPING_INDEX] = stateToIdMap;
|
||||
BY_STRING[LEGACY_MAPPING_INDEX] = stateByStringMap;
|
||||
INTO_STRING[LEGACY_MAPPING_INDEX] = stateToStringMap;
|
||||
DEFAULT_STATES[LEGACY_MAPPING_INDEX] = stateTypeToBlockStateMap;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to load legacy block mappings", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadModern(Map<BinaryNBTCompound, Map.Entry<Map<StateValue, Object>, String>> cache) {
|
||||
try (final SequentialNBTReader.Compound compound = MappingHelper.decompress("mappings/block/modern_block_mappings")) {
|
||||
private static void loadModern(Map<Map<StateValue, Object>, StateCacheValue> cache, ClientVersion version) {
|
||||
try (final SequentialNBTReader.Compound compound = MappingHelper.decompress(MAPPINGS_ASSETS_PREFIX + version.name())) {
|
||||
compound.skipOne(); // Skip version
|
||||
|
||||
for (Map.Entry<String, NBT> versionEntry : compound) {
|
||||
ClientVersion version = ClientVersion.valueOf(versionEntry.getKey());
|
||||
byte mappingIndex = getMappingsIndex(version);
|
||||
SequentialNBTReader.List list = (SequentialNBTReader.List) versionEntry.getValue();
|
||||
byte mappingIndex = getMappingsIndex(version);
|
||||
SequentialNBTReader.List list = (SequentialNBTReader.List) compound.next().getValue();
|
||||
|
||||
Map<Integer, WrappedBlockState> stateByIdMap = new HashMap<>();
|
||||
Map<WrappedBlockState, Integer> stateToIdMap = new HashMap<>();
|
||||
Map<String, WrappedBlockState> stateByStringMap = new HashMap<>();
|
||||
Map<WrappedBlockState, String> stateToStringMap = new HashMap<>();
|
||||
Map<StateType, WrappedBlockState> stateTypeToBlockStateMap = new HashMap<>();
|
||||
Map<Integer, WrappedBlockState> stateByIdMap = new HashMap<>();
|
||||
Map<WrappedBlockState, Integer> stateToIdMap = new HashMap<>();
|
||||
Map<String, WrappedBlockState> stateByStringMap = new HashMap<>();
|
||||
Map<WrappedBlockState, String> stateToStringMap = new HashMap<>();
|
||||
Map<StateType, WrappedBlockState> stateTypeToBlockStateMap = new HashMap<>();
|
||||
|
||||
int id = 0;
|
||||
for (NBT e : list) {
|
||||
SequentialNBTReader.Compound element = (SequentialNBTReader.Compound) e;
|
||||
String typeString = ((NBTString) element.next().getValue()).getValue(); // type
|
||||
StateType type = StateTypes.getByName(typeString);
|
||||
if (type == null) {
|
||||
// Let's update the state type to a modern version
|
||||
for (Map.Entry<String, String> stringEntry : STRING_UPDATER.entrySet()) {
|
||||
typeString = typeString.replace(stringEntry.getKey(), stringEntry.getValue());
|
||||
}
|
||||
|
||||
type = StateTypes.getByName(typeString);
|
||||
|
||||
int id = 0;
|
||||
for (NBT e : list) {
|
||||
SequentialNBTReader.Compound element = (SequentialNBTReader.Compound) e;
|
||||
String typeString = ((NBTString) element.next().getValue()).getValue(); // type
|
||||
StateType type = StateTypes.getByName(typeString);
|
||||
if (type == null) {
|
||||
// Let's update the state type to a modern version
|
||||
for (Map.Entry<String, String> stringEntry : STRING_UPDATER.entrySet()) {
|
||||
typeString = typeString.replace(stringEntry.getKey(), stringEntry.getValue());
|
||||
}
|
||||
|
||||
type = StateTypes.getByName(typeString);
|
||||
|
||||
if (type == null) {
|
||||
PacketEvents.getAPI().getLogger().warning("Unknown block type: " + typeString);
|
||||
element.skip();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Map.Entry<String, NBT> next = element.next(); // def
|
||||
|
||||
int defaultIdx = 0;
|
||||
if (!next.getKey().equals("def")) {
|
||||
PacketEvents.getAPI().getLogger().warning("No default state for " + type + " using 0");
|
||||
} else {
|
||||
defaultIdx = ((NBTNumber) next.getValue()).getAsInt();
|
||||
next = element.next(); // entries
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (NBT nbt : ((SequentialNBTReader.List) next.getValue())) {
|
||||
SequentialNBTReader.Compound dataContent = (SequentialNBTReader.Compound) nbt;
|
||||
Map.Entry<Map<StateValue, Object>, String> dataEntry = cache.computeIfAbsent(new BinaryNBTCompound(dataContent.readFullyAsBytes()), (bin) -> {
|
||||
NBTCompound key;
|
||||
try (ByteArrayInputStream stream = new ByteArrayInputStream(bin.getData()); DataInputStream in = new DataInputStream(stream)) {
|
||||
key = (NBTCompound) DefaultNBTSerializer.INSTANCE.deserializeTag(NBTLimiter.noop(), in, false);
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Failed to load legacy block mappings", ex);
|
||||
}
|
||||
|
||||
StringBuilder dataStringBuilder = new StringBuilder();
|
||||
Map<StateValue, Object> dataMap = new HashMap<>(key.size());
|
||||
|
||||
for (Map.Entry<String, NBT> props : key.getTags().entrySet()) {
|
||||
StateValue state = StateValue.byName(props.getKey());
|
||||
if (state == null) {
|
||||
PacketEvents.getAPI().getLogger().warning("Could not find value for " + props.getKey());
|
||||
continue;
|
||||
}
|
||||
|
||||
dataStringBuilder.append(props.getKey()).append("=");
|
||||
NBT value = props.getValue();
|
||||
Object v;
|
||||
if (value instanceof NBTByte) {
|
||||
v = ((NBTByte) value).getAsInt() == 1;
|
||||
} else if (value instanceof NBTNumber) {
|
||||
v = ((NBTNumber) value).getAsInt();
|
||||
} else if (value instanceof NBTString) {
|
||||
v = ((NBTString) value).getValue();
|
||||
} else {
|
||||
PacketEvents.getAPI().getLogger().warning("Unknown NBT typeString in modern mapping: " + value.getClass().getSimpleName());
|
||||
dataStringBuilder = new StringBuilder(dataStringBuilder.substring(0, dataStringBuilder.length() - props.getKey().length() - 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
dataStringBuilder.append(v).append(",");
|
||||
dataMap.put(state, state.getParser().apply(v.toString().toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
String dataString;
|
||||
if (dataStringBuilder.length() == 0) {
|
||||
dataString = "";
|
||||
} else {
|
||||
dataString = "[" + dataStringBuilder.substring(0, dataStringBuilder.length() - 1) + "]";
|
||||
}
|
||||
|
||||
return new AbstractMap.SimpleEntry<>(dataMap, dataString);
|
||||
});
|
||||
|
||||
String fullString = typeString + dataEntry.getValue();
|
||||
WrappedBlockState state = new WrappedBlockState(type, dataEntry.getKey(), id, mappingIndex);
|
||||
|
||||
if (defaultIdx == index) {
|
||||
stateTypeToBlockStateMap.put(type, state);
|
||||
}
|
||||
|
||||
stateByStringMap.put(fullString, state);
|
||||
stateByIdMap.put(id, state);
|
||||
stateToStringMap.put(state, fullString);
|
||||
stateToIdMap.put(state, id);
|
||||
|
||||
id++;
|
||||
index++;
|
||||
PacketEvents.getAPI().getLogger().warning("Unknown block type: " + typeString);
|
||||
element.skip();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
BY_ID.put(mappingIndex, stateByIdMap);
|
||||
INTO_ID.put(mappingIndex, stateToIdMap);
|
||||
BY_STRING.put(mappingIndex, stateByStringMap);
|
||||
INTO_STRING.put(mappingIndex, stateToStringMap);
|
||||
DEFAULT_STATES.put(mappingIndex, stateTypeToBlockStateMap);
|
||||
Map.Entry<String, NBT> next = element.next(); // def
|
||||
|
||||
int defaultIdx = 0;
|
||||
if (!next.getKey().equals("def")) {
|
||||
PacketEvents.getAPI().getLogger().warning("No default state for " + type + " using 0");
|
||||
} else {
|
||||
defaultIdx = ((NBTNumber) next.getValue()).getAsInt();
|
||||
next = element.next(); // entries
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (NBT nbt : ((SequentialNBTReader.List) next.getValue())) {
|
||||
SequentialNBTReader.Compound dataContent = (SequentialNBTReader.Compound) nbt;
|
||||
StateCacheValue stateCache;
|
||||
if (dataContent.hasNext()) { // only try to read if there is data available
|
||||
Map<StateValue, Object> dataMap = new HashMap<>(3);
|
||||
for (Map.Entry<String, NBT> props : dataContent) {
|
||||
StateValue state = StateValue.byName(props.getKey());
|
||||
if (state == null) {
|
||||
PacketEvents.getAPI().getLogger().warning("Could not find value for " + props.getKey());
|
||||
continue;
|
||||
}
|
||||
|
||||
NBT value = props.getValue();
|
||||
Object v;
|
||||
if (value instanceof NBTByte) {
|
||||
v = ((NBTByte) value).getAsInt() == 1;
|
||||
} else if (value instanceof NBTNumber) {
|
||||
v = ((NBTNumber) value).getAsInt();
|
||||
} else if (value instanceof NBTString) {
|
||||
v = ((NBTString) value).getValue();
|
||||
} else {
|
||||
PacketEvents.getAPI().getLogger().warning("Unknown NBT typeString in modern mapping: " + value.getClass().getSimpleName());
|
||||
continue;
|
||||
}
|
||||
dataMap.put(state, state.getParser().apply(v.toString().toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
stateCache = cache.computeIfAbsent(dataMap, StateCacheValue::new);
|
||||
} else {
|
||||
stateCache = StateCacheValue.EMPTY;
|
||||
}
|
||||
|
||||
String fullString = typeString + stateCache.getString();
|
||||
WrappedBlockState state = new WrappedBlockState(type, stateCache.map, id, mappingIndex);
|
||||
|
||||
if (defaultIdx == index) {
|
||||
stateTypeToBlockStateMap.put(type, state);
|
||||
}
|
||||
|
||||
stateByStringMap.put(fullString, state);
|
||||
stateByIdMap.put(id, state);
|
||||
stateToStringMap.put(state, fullString);
|
||||
stateToIdMap.put(state, id);
|
||||
|
||||
id++;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
BY_ID[mappingIndex] = stateByIdMap;
|
||||
INTO_ID[mappingIndex] = stateToIdMap;
|
||||
BY_STRING[mappingIndex] = stateByStringMap;
|
||||
INTO_STRING[mappingIndex] = stateToStringMap;
|
||||
DEFAULT_STATES[mappingIndex] = stateTypeToBlockStateMap;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to load modern block mappings", e);
|
||||
}
|
||||
@@ -1451,7 +1473,7 @@ public class WrappedBlockState {
|
||||
int oldGlobalID = globalID;
|
||||
globalID = getGlobalIdNoCache();
|
||||
if (globalID == -1) { // -1 maps to no block as negative ID are impossible
|
||||
WrappedBlockState blockState = BY_ID.get(mappingsIndex).getOrDefault(oldGlobalID, AIR).clone();
|
||||
WrappedBlockState blockState = BY_ID[this.mappingsIndex].getOrDefault(oldGlobalID, AIR).clone();
|
||||
this.type = blockState.type;
|
||||
this.globalID = blockState.globalID;
|
||||
this.data = new HashMap<>(blockState.data);
|
||||
@@ -1495,13 +1517,55 @@ public class WrappedBlockState {
|
||||
* Internal method for determining if the block state is still valid
|
||||
*/
|
||||
private int getGlobalIdNoCache() {
|
||||
return INTO_ID.get(mappingsIndex).getOrDefault(this, -1);
|
||||
return INTO_ID[this.mappingsIndex].getOrDefault(this, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return INTO_STRING.get(mappingsIndex).get(this);
|
||||
return INTO_STRING[this.mappingsIndex].get(this);
|
||||
}
|
||||
|
||||
public static void ensureLoad() { /**/ }
|
||||
@ApiStatus.Internal
|
||||
public static void ensureLoad() {
|
||||
if (!PRELOAD_BLOCK_STATE_MAPPINGS) {
|
||||
return;
|
||||
}
|
||||
Logger logger = PacketEvents.getAPI().getLogger();
|
||||
logger.info("Preloading block mappings...");
|
||||
long start = System.nanoTime();
|
||||
|
||||
{
|
||||
Map<Map<StateValue, Object>, StateCacheValue> cache = new HashMap<>();
|
||||
loadLegacy(cache);
|
||||
for (ClientVersion version : MAPPING_VERSION_STEPS) {
|
||||
loadModern(cache, version);
|
||||
}
|
||||
}
|
||||
|
||||
double timeDiff = (System.nanoTime() - start) / 1_000_000d;
|
||||
logger.info("Finish preloading block mappings in " + timeDiff + "ms");
|
||||
}
|
||||
|
||||
private static final class StateCacheValue {
|
||||
|
||||
public static final StateCacheValue EMPTY = new StateCacheValue(Collections.emptyMap());
|
||||
|
||||
private final Map<StateValue, Object> map;
|
||||
private String string;
|
||||
|
||||
public StateCacheValue(Map<StateValue, Object> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
if (this.string == null) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Map.Entry<StateValue, Object> entry : this.map.entrySet()) {
|
||||
builder.append(entry.getKey()).append('=').append(entry.getValue()).append(',');
|
||||
}
|
||||
this.string = builder.length() == 0 ? "" : '[' + builder.substring(0, builder.length() - 1) + ']';
|
||||
}
|
||||
return this.string;
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
-22
@@ -19,22 +19,19 @@
|
||||
package com.github.retrooper.packetevents.protocol.world.states.type;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.MaterialType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class StateType {
|
||||
|
||||
private final TypesBuilder typesBuilder;
|
||||
private final TypesBuilderData typeData;
|
||||
private final Mapped mapped = new Mapped();
|
||||
private final Mapped mapped;
|
||||
|
||||
private final float blastResistance;
|
||||
private final float hardness;
|
||||
@@ -45,14 +42,14 @@ public class StateType {
|
||||
private final boolean exceedsCube;
|
||||
private final MaterialType materialType;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public StateType(
|
||||
TypesBuilder typesBuilder, TypesBuilderData typeData,
|
||||
TypesBuilderData typeData,
|
||||
float blastResistance, float hardness, boolean isSolid,
|
||||
boolean isBlocking, boolean isAir, boolean requiresCorrectTool,
|
||||
boolean isShapeExceedsCube, MaterialType materialType
|
||||
) {
|
||||
this.typesBuilder = typesBuilder;
|
||||
this.typeData = typeData;
|
||||
this.mapped = new Mapped(typeData);
|
||||
this.blastResistance = blastResistance;
|
||||
this.hardness = hardness;
|
||||
this.isSolid = isSolid;
|
||||
@@ -76,7 +73,7 @@ public class StateType {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return typeData.getName().getKey();
|
||||
return this.mapped.getName().getKey();
|
||||
}
|
||||
|
||||
public float getBlastResistance() {
|
||||
@@ -155,20 +152,15 @@ public class StateType {
|
||||
return Objects.hash(getName(), blastResistance, hardness, isSolid, isBlocking, isAir, requiresCorrectTool, exceedsCube, materialType);
|
||||
}
|
||||
|
||||
public final class Mapped implements MappedEntity {
|
||||
public final class Mapped extends AbstractMappedEntity {
|
||||
|
||||
@ApiStatus.Internal
|
||||
public Mapped(@Nullable TypesBuilderData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
public StateType getStateType() {
|
||||
return StateType.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return typeData.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
return MappingHelper.getId(version, typesBuilder, typeData);
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
-24
@@ -21,28 +21,29 @@ package com.github.retrooper.packetevents.protocol.world.states.type;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.MaterialType;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
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 org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class StateTypes {
|
||||
public final class StateTypes {
|
||||
|
||||
private static final List<StateType> ALL_STATE_TYPES = new ArrayList<>();
|
||||
private static final Map<String, StateType.Mapped> BY_NAME = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, StateType.Mapped>> BY_ID = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("block/block_type_mappings");
|
||||
private static final VersionedRegistry<StateType.Mapped> REGISTRY = new VersionedRegistry<>("block");
|
||||
private static final List<StateType> STATE_TYPE_VALUES;
|
||||
|
||||
private StateTypes() {
|
||||
}
|
||||
|
||||
public static VersionedRegistry<StateType.Mapped> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
public static Collection<StateType> values() {
|
||||
return Collections.unmodifiableCollection(ALL_STATE_TYPES);
|
||||
return STATE_TYPE_VALUES;
|
||||
}
|
||||
|
||||
public static @Nullable StateType getByName(String blockString) {
|
||||
@@ -51,7 +52,7 @@ public class StateTypes {
|
||||
}
|
||||
|
||||
public static StateType.@Nullable Mapped getMappedByName(String blockString) {
|
||||
return getMappedByName(new ResourceLocation(blockString));
|
||||
return REGISTRY.getByName(blockString);
|
||||
}
|
||||
|
||||
public static @Nullable StateType getByName(ResourceLocation blockKey) {
|
||||
@@ -60,7 +61,7 @@ public class StateTypes {
|
||||
}
|
||||
|
||||
public static StateType.@Nullable Mapped getMappedByName(ResourceLocation blockKey) {
|
||||
return BY_NAME.get(blockKey.toString());
|
||||
return REGISTRY.getByName(blockKey);
|
||||
}
|
||||
|
||||
public static StateType getById(ClientVersion version, int id) {
|
||||
@@ -68,11 +69,10 @@ public class StateTypes {
|
||||
}
|
||||
|
||||
public static StateType.Mapped getMappedById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, StateType.Mapped> idMap = BY_ID.get((byte) index);
|
||||
return idMap.get(id);
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
// <editor-fold desc="state type definitions" defaultstate="collapsed">
|
||||
public static StateType AIR = StateTypes.builder().name("AIR").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(false).isAir(true).setMaterial(MaterialType.AIR).build();
|
||||
public static StateType STONE = StateTypes.builder().name("STONE").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
|
||||
public static StateType GRANITE = StateTypes.builder().name("GRANITE").blastResistance(6.0f).hardness(1.5f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.STONE).build();
|
||||
@@ -1196,9 +1196,16 @@ public class StateTypes {
|
||||
public static StateType CLOSED_EYEBLOSSOM = StateTypes.builder().name("CLOSED_EYEBLOSSOM").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.PLANT).build();
|
||||
public static StateType POTTED_OPEN_EYEBLOSSOM = StateTypes.builder().name("POTTED_OPEN_EYEBLOSSOM").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.DECORATION).build();
|
||||
public static StateType POTTED_CLOSED_EYEBLOSSOM = StateTypes.builder().name("POTTED_CLOSED_EYEBLOSSOM").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.DECORATION).build();
|
||||
// </editor-fold>
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
REGISTRY.unloadMappings();
|
||||
|
||||
List<StateType> stateTypes = new ArrayList<>(REGISTRY.size());
|
||||
for (StateType.Mapped type : REGISTRY.getEntries()) {
|
||||
stateTypes.add(type.getStateType());
|
||||
}
|
||||
STATE_TYPE_VALUES = Collections.unmodifiableList(stateTypes);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
@@ -1262,13 +1269,11 @@ public class StateTypes {
|
||||
}
|
||||
|
||||
public StateType build() {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(this.name.getKey().toLowerCase(Locale.ROOT));
|
||||
StateType type = new StateType(
|
||||
TYPES_BUILDER, data, blastResistance, hardness, isSolid,
|
||||
isBlocking, isAir, requiresCorrectTool, isShapeExceedsCube, materialType);
|
||||
ALL_STATE_TYPES.add(type);
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, BY_NAME, BY_ID, type.getMapped());
|
||||
return type;
|
||||
String definedName = this.name.getKey().toLowerCase(Locale.ROOT);
|
||||
return REGISTRY.define(definedName, data -> new StateType(
|
||||
data, this.blastResistance, this.hardness, this.isSolid, this.isBlocking, this.isAir,
|
||||
this.requiresCorrectTool, this.isShapeExceedsCube, this.materialType
|
||||
).getMapped()).getStateType();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,7 @@ public class Vector3i {
|
||||
this.z = 0;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Vector3i(long val) {
|
||||
this(val, PacketEvents.getAPI().getServerManager().getVersion());
|
||||
}
|
||||
@@ -156,6 +157,7 @@ public class Vector3i {
|
||||
return ((long) (getX() & 0x3FFFFFF) << 38) | ((long) (getY() & 0xFFF) << 26) | (getZ() & 0x3FFFFFF);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public long getSerializedPosition() {
|
||||
return getSerializedPosition(PacketEvents.getAPI().getServerManager().getVersion());
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ public interface IRegistry<T extends MappedEntity> extends BiFunction<ClientVers
|
||||
*/
|
||||
Collection<T> getEntries();
|
||||
|
||||
int size();
|
||||
|
||||
ResourceLocation getRegistryKey();
|
||||
|
||||
@Override
|
||||
|
||||
@@ -86,6 +86,11 @@ public final class SimpleRegistry<T extends MappedEntity> implements IRegistry<T
|
||||
return Collections.unmodifiableCollection(this.typeMap.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.typeMap.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getRegistryKey() {
|
||||
return this.registryKey;
|
||||
|
||||
@@ -58,8 +58,10 @@ public class TypesBuilder {
|
||||
}
|
||||
|
||||
public void load() {
|
||||
try (final SequentialNBTReader.Compound compound = MappingHelper.decompress("mappings/" + mapPath)) {
|
||||
compound.skipOne(); // skip version tag for now
|
||||
try (final SequentialNBTReader.Compound rootCompound = MappingHelper.decompress("mappings/" + this.mapPath)) {
|
||||
rootCompound.skipOne(); // skip version tag for now
|
||||
SequentialNBTReader.Compound compound = (SequentialNBTReader.Compound) rootCompound.next().getValue();
|
||||
|
||||
int length = ((NBTNumber) compound.next().getValue()).getAsInt(); // Second tag is the length
|
||||
final SequentialNBTReader.Compound entries = (SequentialNBTReader.Compound) compound.next().getValue(); // Third tag are the entries
|
||||
|
||||
@@ -157,6 +159,11 @@ public class TypesBuilder {
|
||||
return versionMapper.getIndex(rawVersion);
|
||||
}
|
||||
|
||||
boolean isMappingDataLoaded() {
|
||||
return this.entries != null;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public void unloadFileMappings() {
|
||||
entries.clear();
|
||||
entries = null;
|
||||
|
||||
+16
@@ -23,6 +23,7 @@ import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -38,6 +39,10 @@ public final class VersionedRegistry<T extends MappedEntity> implements IRegistr
|
||||
private final Map<String, T> typeMap = new HashMap<>();
|
||||
private final Map<Byte, Map<Integer, T>> typeIdMap = new HashMap<>();
|
||||
|
||||
public VersionedRegistry(String registry) {
|
||||
this(registry, "registries/" + registry);
|
||||
}
|
||||
|
||||
public VersionedRegistry(String registry, String mappingsPath) {
|
||||
this(new ResourceLocation(registry), mappingsPath);
|
||||
}
|
||||
@@ -55,6 +60,12 @@ public final class VersionedRegistry<T extends MappedEntity> implements IRegistr
|
||||
return instance;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@ApiStatus.Internal
|
||||
public boolean isMappingDataLoaded() {
|
||||
return this.typesBuilder.isMappingDataLoaded();
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public void unloadMappings() {
|
||||
this.typesBuilder.unloadFileMappings();
|
||||
@@ -91,6 +102,11 @@ public final class VersionedRegistry<T extends MappedEntity> implements IRegistr
|
||||
return Collections.unmodifiableCollection(this.typeMap.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.typeMap.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getRegistryKey() {
|
||||
return this.registryKey;
|
||||
|
||||
@@ -70,6 +70,10 @@ import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityMetadataProvider;
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.profession.VillagerProfession;
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.profession.VillagerProfessions;
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerType;
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerTypes;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
@@ -201,12 +205,16 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
|
||||
this.clientVersion = ClientVersion.UNKNOWN;
|
||||
this.serverVersion = PacketEvents.getAPI().getServerManager().getVersion();
|
||||
this.buffer = null;
|
||||
int id = packetType.getId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
||||
int id = packetType.getId(this.serverVersion.toClientVersion());
|
||||
this.packetTypeData = new PacketTypeData(packetType, id);
|
||||
}
|
||||
|
||||
public static PacketWrapper<?> createUniversalPacketWrapper(Object byteBuf) {
|
||||
PacketWrapper<?> wrapper = new PacketWrapper<>(ClientVersion.UNKNOWN, PacketEvents.getAPI().getServerManager().getVersion(), -2);
|
||||
return createUniversalPacketWrapper(byteBuf, PacketEvents.getAPI().getServerManager().getVersion());
|
||||
}
|
||||
|
||||
public static PacketWrapper<?> createUniversalPacketWrapper(Object byteBuf, ServerVersion version) {
|
||||
PacketWrapper<?> wrapper = new PacketWrapper<>(ClientVersion.UNKNOWN, version, -2);
|
||||
wrapper.buffer = byteBuf;
|
||||
return wrapper;
|
||||
}
|
||||
@@ -448,15 +456,15 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
|
||||
}
|
||||
|
||||
public VillagerData readVillagerData() {
|
||||
int villagerTypeId = readVarInt();
|
||||
int villagerProfessionId = readVarInt();
|
||||
VillagerType type = this.readMappedEntity(VillagerTypes.getRegistry());
|
||||
VillagerProfession profession = this.readMappedEntity(VillagerProfessions.getRegistry());
|
||||
int level = readVarInt();
|
||||
return new VillagerData(villagerTypeId, villagerProfessionId, level);
|
||||
return new VillagerData(type, profession, level);
|
||||
}
|
||||
|
||||
public void writeVillagerData(VillagerData data) {
|
||||
writeVarInt(data.getType().getId());
|
||||
writeVarInt(data.getProfession().getId());
|
||||
this.writeMappedEntity(data.getType());
|
||||
this.writeMappedEntity(data.getProfession());
|
||||
writeVarInt(data.getLevel());
|
||||
}
|
||||
|
||||
@@ -477,7 +485,8 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
|
||||
}
|
||||
|
||||
PatchableComponentMap components = new PatchableComponentMap(
|
||||
itemType.getComponents(), new HashMap<>(4));
|
||||
itemType.getComponents(this.serverVersion.toClientVersion()),
|
||||
new HashMap<>(4));
|
||||
for (int i = 0; i < presentCount; i++) {
|
||||
ComponentType<?> type = this.readMappedEntity(ComponentTypes.getRegistry());
|
||||
components.set((ComponentType<Object>) type, type.read(this));
|
||||
@@ -967,16 +976,14 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
|
||||
if (type == null) {
|
||||
throw new IllegalStateException("Unknown entity metadata type id: " + typeID + " version " + serverVersion.toClientVersion());
|
||||
}
|
||||
Object value = type.getDataDeserializer().apply(this);
|
||||
list.add(new EntityData(index, type, value));
|
||||
list.add(new EntityData(index, type, type.read(this)));
|
||||
}
|
||||
} else {
|
||||
for (byte data = readByte(); data != Byte.MAX_VALUE; data = readByte()) {
|
||||
int typeID = (data & 0xE0) >> 5;
|
||||
int index = data & 0x1F;
|
||||
EntityDataType<?> type = EntityDataTypes.getById(serverVersion.toClientVersion(), typeID);
|
||||
Object value = type.getDataDeserializer().apply(this);
|
||||
EntityData entityData = new EntityData(index, type, value);
|
||||
EntityData entityData = new EntityData(index, type, type.read(this));
|
||||
list.add(entityData);
|
||||
}
|
||||
}
|
||||
@@ -996,7 +1003,7 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
|
||||
} else {
|
||||
writeByte(entityData.getType().getId(serverVersion.toClientVersion()));
|
||||
}
|
||||
entityData.getType().getDataSerializer().accept(this, entityData.getValue());
|
||||
((EntityDataType<? super Object>) entityData.getType()).write(this, entityData.getValue());
|
||||
}
|
||||
writeByte(255); // End of metadata array
|
||||
} else {
|
||||
@@ -1005,7 +1012,7 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
|
||||
int index = entityData.getIndex();
|
||||
int data = (typeID << 5 | index & 31) & 255;
|
||||
writeByte(data);
|
||||
entityData.getType().getDataSerializer().accept(this, entityData.getValue());
|
||||
((EntityDataType<? super Object>) entityData.getType()).write(this, entityData.getValue());
|
||||
}
|
||||
writeByte(127); // End of metadata array
|
||||
}
|
||||
@@ -1437,6 +1444,18 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
|
||||
}
|
||||
}
|
||||
|
||||
public <R> Optional<R> readJavaOptional(Reader<R> reader) {
|
||||
return this.readBoolean() ? Optional.of(reader.apply(this)) : Optional.empty();
|
||||
}
|
||||
|
||||
public <V> void writeJavaOptional(Optional<V> value, Writer<V> writer) {
|
||||
if (value.isPresent()) {
|
||||
this.writeBoolean(true);
|
||||
writer.accept(this, value.get());
|
||||
} else {
|
||||
this.writeBoolean(false);
|
||||
}
|
||||
}
|
||||
|
||||
public <K, C extends Collection<K>> C readCollection(IntFunction<C> function, Reader<K> reader) {
|
||||
int size = this.readVarInt();
|
||||
@@ -1524,12 +1543,12 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
|
||||
}
|
||||
|
||||
public <Z extends MappedEntity> Z readMappedEntity(IRegistry<Z> registry) {
|
||||
IRegistry<Z> replacedRegistry = this.getRegistryHolder().getRegistryOr(registry);
|
||||
IRegistry<Z> replacedRegistry = this.getRegistryHolder().getRegistryOr(registry, this.serverVersion.toClientVersion());
|
||||
return this.readMappedEntity((BiFunction<ClientVersion, Integer, Z>) replacedRegistry);
|
||||
}
|
||||
|
||||
public <Z extends MappedEntity> Z readMappedEntityOrDirect(IRegistry<Z> registry, Reader<Z> directReader) {
|
||||
IRegistry<Z> replacedRegistry = this.getRegistryHolder().getRegistryOr(registry);
|
||||
IRegistry<Z> replacedRegistry = this.getRegistryHolder().getRegistryOr(registry, this.serverVersion.toClientVersion());
|
||||
return this.readMappedEntityOrDirect((BiFunction<ClientVersion, Integer, Z>) replacedRegistry, directReader);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -44,14 +44,14 @@ public class WrapperPlayClientGenerateStructure extends PacketWrapper<WrapperPla
|
||||
|
||||
@Override
|
||||
public void read() {
|
||||
this.blockPosition = new Vector3i(readLong());
|
||||
this.blockPosition = new Vector3i(readLong(), this.serverVersion);
|
||||
this.levels = readVarInt();
|
||||
this.keepJigsaws = readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write() {
|
||||
writeLong(this.blockPosition.getSerializedPosition());
|
||||
writeLong(this.blockPosition.getSerializedPosition(this.serverVersion));
|
||||
writeVarInt(this.levels);
|
||||
writeBoolean(this.keepJigsaws);
|
||||
}
|
||||
|
||||
+2
-2
@@ -54,7 +54,7 @@ public class WrapperPlayClientUpdateCommandBlock extends PacketWrapper<WrapperPl
|
||||
|
||||
@Override
|
||||
public void read() {
|
||||
this.position = new Vector3i(readLong());
|
||||
this.position = new Vector3i(readLong(), this.serverVersion);
|
||||
this.command = readString();
|
||||
this.mode = CommandBlockMode.getById(readVarInt());
|
||||
this.flags = readUnsignedByte();
|
||||
@@ -65,7 +65,7 @@ public class WrapperPlayClientUpdateCommandBlock extends PacketWrapper<WrapperPl
|
||||
|
||||
@Override
|
||||
public void write() {
|
||||
writeLong(position.getSerializedPosition());
|
||||
writeLong(position.getSerializedPosition(this.serverVersion));
|
||||
writeString(command);
|
||||
writeVarInt(mode.ordinal());
|
||||
if (this.doesTrackOutput) {
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ public class WrapperPlayClientUpdateSign extends PacketWrapper<WrapperPlayClient
|
||||
@Override
|
||||
public void read() {
|
||||
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_8)) {
|
||||
this.blockPosition = new Vector3i(readLong());
|
||||
this.blockPosition = new Vector3i(readLong(), this.serverVersion);
|
||||
} else {
|
||||
int x = readInt();
|
||||
int y = readShort();
|
||||
@@ -67,7 +67,7 @@ public class WrapperPlayClientUpdateSign extends PacketWrapper<WrapperPlayClient
|
||||
@Override
|
||||
public void write() {
|
||||
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_8)) {
|
||||
long positionVector = blockPosition.getSerializedPosition();
|
||||
long positionVector = blockPosition.getSerializedPosition(this.serverVersion);
|
||||
writeLong(positionVector);
|
||||
} else {
|
||||
writeInt(blockPosition.x);
|
||||
|
||||
+2
-1
@@ -548,7 +548,8 @@ public class WrapperPlayServerJoinGame extends PacketWrapper<WrapperPlayServerJo
|
||||
}
|
||||
|
||||
public DimensionType getDimensionType() {
|
||||
IRegistry<DimensionType> registry = this.getRegistryHolder().getRegistryOr(DimensionTypes.getRegistry());
|
||||
IRegistry<DimensionType> registry = this.getRegistryHolder().getRegistryOr(
|
||||
DimensionTypes.getRegistry(), this.serverVersion.toClientVersion());
|
||||
return this.dimensionTypeRef.resolve(registry, this.serverVersion.toClientVersion());
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ public class WrapperPlayServerOpenSignEditor extends PacketWrapper<WrapperPlaySe
|
||||
@Override
|
||||
public void read() {
|
||||
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_8)) {
|
||||
this.position = new Vector3i(readLong());
|
||||
this.position = new Vector3i(readLong(), this.serverVersion);
|
||||
} else {
|
||||
int x = readInt();
|
||||
int y = readInt();
|
||||
@@ -58,7 +58,7 @@ public class WrapperPlayServerOpenSignEditor extends PacketWrapper<WrapperPlaySe
|
||||
@Override
|
||||
public void write() {
|
||||
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_8)) {
|
||||
long positionVector = position.getSerializedPosition();
|
||||
long positionVector = position.getSerializedPosition(this.serverVersion);
|
||||
writeLong(positionVector);
|
||||
} else {
|
||||
writeInt(position.x);
|
||||
|
||||
+2
-1
@@ -298,7 +298,8 @@ public class WrapperPlayServerRespawn extends PacketWrapper<WrapperPlayServerRes
|
||||
}
|
||||
|
||||
public DimensionType getDimensionType() {
|
||||
IRegistry<DimensionType> registry = this.getRegistryHolder().getRegistryOr(DimensionTypes.getRegistry());
|
||||
IRegistry<DimensionType> registry = this.getRegistryHolder().getRegistryOr(
|
||||
DimensionTypes.getRegistry(), this.serverVersion.toClientVersion());
|
||||
return this.dimensionTypeRef.resolve(registry, this.serverVersion.toClientVersion());
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 190 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user