1
0
Fork 0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-04-17 19:12:14 +02:00

Hashing of attribute modifiers, blocks attacks, wolf sound variants, and chicken variants

This commit is contained in:
Eclipse 2025-03-28 17:53:38 +00:00
parent 01354f2401
commit ea10a512b3
No known key found for this signature in database
GPG key ID: 95E6998F82EC938A
9 changed files with 114 additions and 21 deletions

View file

@ -27,13 +27,12 @@ package org.geysermc.geyser.entity.type.living.animal;
import net.kyori.adventure.key.Key;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.RegistryCache;
import org.geysermc.geyser.session.cache.registry.JavaRegistryKey;
import org.geysermc.geyser.session.cache.registry.RegistryEntryContext;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import java.util.Locale;
import java.util.function.Function;
/**
* Interface to help set up data-driven entity variants for mobs.
@ -77,7 +76,7 @@ public interface VariantHolder<BedrockVariant extends VariantHolder.BuiltIn> {
*
* <p>This reader simply matches the identifiers of registry entries with built-in variants. If no built-in variant matches, the fallback/default is returned.</p>
*/
static <BuiltInVariant extends Enum<? extends BuiltIn>> Function<RegistryEntryContext, BuiltInVariant> reader(Class<BuiltInVariant> clazz, BuiltInVariant fallback) {
static <BuiltInVariant extends Enum<? extends BuiltIn>> RegistryCache.RegistryReader<BuiltInVariant> reader(Class<BuiltInVariant> clazz, BuiltInVariant fallback) {
BuiltInVariant[] variants = clazz.getEnumConstants();
if (variants == null) {
throw new IllegalArgumentException("Class is not an enum");

View file

@ -32,15 +32,14 @@ import org.geysermc.geyser.entity.properties.VanillaEntityProperties;
import org.geysermc.geyser.entity.type.living.animal.AnimalEntity;
import org.geysermc.geyser.entity.type.living.animal.VariantHolder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.registry.RegistryEntryContext;
import org.geysermc.geyser.session.cache.RegistryCache;
import java.util.Locale;
import java.util.UUID;
import java.util.function.Function;
public abstract class TemperatureVariantAnimal extends AnimalEntity implements VariantHolder<TemperatureVariantAnimal.BuiltInVariant> {
public static final Function<RegistryEntryContext, BuiltInVariant> VARIANT_READER = VariantHolder.reader(BuiltInVariant.class, BuiltInVariant.TEMPERATE);
public static final RegistryCache.RegistryReader<BuiltInVariant> VARIANT_READER = VariantHolder.reader(BuiltInVariant.class, BuiltInVariant.TEMPERATE);
public TemperatureVariantAnimal(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition,
Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {

View file

@ -39,6 +39,7 @@ import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.components.Rarity;
import org.geysermc.geyser.level.block.Blocks;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.registry.JavaRegistries;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect;
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
@ -46,6 +47,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos;
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BlockStateProperties;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BlocksAttacks;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Consumable;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ConsumeEffect;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.CustomModelData;
@ -57,6 +59,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.Fireworks;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.FoodProperties;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.IntComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectDetails;
@ -95,7 +98,7 @@ public class DataComponentHashers {
register(DataComponentTypes.ENCHANTMENTS, RegistryHasher.ITEM_ENCHANTMENTS);
// TODO can place on/can break on, complicated
// TODO attribute modifiers, attribute registry and equipment slot group hashers
register(DataComponentTypes.ATTRIBUTE_MODIFIERS, RegistryHasher.ATTRIBUTE_MODIFIER_ENTRY.list().convert(ItemAttributeModifiers::getModifiers)); // TODO needs tests
registerMap(DataComponentTypes.CUSTOM_MODEL_DATA, builder -> builder
.optionalList("floats", MinecraftHasher.FLOAT, CustomModelData::floats)
@ -158,7 +161,14 @@ public class DataComponentHashers {
registerMap(DataComponentTypes.DEATH_PROTECTION, builder -> builder
.optionalList("death_effects", RegistryHasher.CONSUME_EFFECT, Function.identity()));
registerMap(DataComponentTypes.BLOCKS_ATTACKS, builder -> builder); // TODO needs damage types, add a way to cache identifiers without reading objects in registrycache
registerMap(DataComponentTypes.BLOCKS_ATTACKS, builder -> builder
.optional("block_delay_seconds", MinecraftHasher.FLOAT, BlocksAttacks::blockDelaySeconds, 0.0F)
.optional("disable_cooldown_scale", MinecraftHasher.FLOAT, BlocksAttacks::disableCooldownScale, 1.0F)
.optional("damage_reductions", RegistryHasher.BLOCKS_ATTACKS_DAMAGE_REDUCTION.list(), BlocksAttacks::damageReductions, List.of(new BlocksAttacks.DamageReduction(90.0F, null, 0.0F, 1.0F)))
.optional("item_damage", RegistryHasher.BLOCKS_ATTACKS_ITEM_DAMAGE_FUNCTION, BlocksAttacks::itemDamage, new BlocksAttacks.ItemDamageFunction(1.0F, 0.0F, 1.0F))
.optionalNullable("bypassed_by", MinecraftHasher.TAG, BlocksAttacks::bypassedBy)
.optionalNullable("block_sound", RegistryHasher.SOUND_EVENT, BlocksAttacks::blockSound)
.optionalNullable("disabled_sound", RegistryHasher.SOUND_EVENT, BlocksAttacks::disableSound)); // TODO needs tests
register(DataComponentTypes.STORED_ENCHANTMENTS, RegistryHasher.ITEM_ENCHANTMENTS);
registerInt(DataComponentTypes.DYED_COLOR);
@ -226,7 +236,7 @@ public class DataComponentHashers {
register(DataComponentTypes.VILLAGER_VARIANT, RegistryHasher.VILLAGER_TYPE);
register(DataComponentTypes.WOLF_VARIANT, RegistryHasher.WOLF_VARIANT);
//register(DataComponentTypes.WOLF_SOUND_VARIANT, ); // TODO same issue as damage type
register(DataComponentTypes.WOLF_SOUND_VARIANT, RegistryHasher.WOLF_SOUND_VARIANT);
register(DataComponentTypes.WOLF_COLLAR, MinecraftHasher.DYE_COLOR);
register(DataComponentTypes.FOX_VARIANT, RegistryHasher.FOX_VARIANT);
register(DataComponentTypes.SALMON_SIZE, RegistryHasher.SALMON_VARIANT);
@ -238,7 +248,8 @@ public class DataComponentHashers {
register(DataComponentTypes.RABBIT_VARIANT, RegistryHasher.RABBIT_VARIANT);
register(DataComponentTypes.PIG_VARIANT, RegistryHasher.PIG_VARIANT);
register(DataComponentTypes.COW_VARIANT, RegistryHasher.COW_VARIANT);
// register(DataComponentTypes.CHICKEN_VARIANT,); // TODO requires change in MCPL?
register(DataComponentTypes.CHICKEN_VARIANT, MinecraftHasher.KEY
.sessionConvert((session, holder) -> holder.getOrCompute(id -> JavaRegistries.CHICKEN_VARIANT.keyFromNetworkId(session, id)))); // Why, Mojang?
register(DataComponentTypes.FROG_VARIANT, RegistryHasher.FROG_VARIANT);
register(DataComponentTypes.HORSE_VARIANT, RegistryHasher.HORSE_VARIANT);
register(DataComponentTypes.PAINTING_VARIANT, RegistryHasher.PAINTING_VARIANT);

View file

@ -40,6 +40,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Consumable;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Filterable;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Unit;
import java.util.List;
@ -108,7 +109,30 @@ public interface MinecraftHasher<T> {
MinecraftHasher<Consumable.ItemUseAnimation> ITEM_USE_ANIMATION = fromEnum();
MinecraftHasher<EquipmentSlot> EQUIPMENT_SLOT = fromEnum(); // FIXME MCPL enum constants aren't right
MinecraftHasher<EquipmentSlot> EQUIPMENT_SLOT = fromEnum(slot -> switch (slot) {
case MAIN_HAND -> "mainhand";
case OFF_HAND -> "offhand";
case BOOTS -> "feet";
case LEGGINGS -> "legs";
case CHESTPLATE -> "chest";
case HELMET -> "head";
case BODY -> "body";
case SADDLE -> "saddle";
});
MinecraftHasher<ItemAttributeModifiers.EquipmentSlotGroup> EQUIPMENT_SLOT_GROUP = fromEnum(group -> switch (group) {
case ANY -> "any";
case MAIN_HAND -> "mainhand";
case OFF_HAND -> "offhand";
case HAND -> "hand";
case FEET -> "feet";
case LEGS -> "legs";
case CHEST -> "chest";
case HEAD -> "head";
case ARMOR -> "armor";
case BODY -> "body";
case SADDLE -> "saddle";
});
MinecraftHasher<GlobalPos> GLOBAL_POS = mapBuilder(builder -> builder
.accept("dimension", KEY, GlobalPos::getDimension)
@ -165,7 +189,11 @@ public interface MinecraftHasher<T> {
// TODO: note that this only works correctly if enum constants are named appropriately
static <T extends Enum<T>> MinecraftHasher<T> fromEnum() {
return STRING.convert(t -> t.name().toLowerCase());
return fromEnum(t -> t.name().toLowerCase());
}
static <T extends Enum<T>> MinecraftHasher<T> fromEnum(Function<T, String> toName) {
return STRING.convert(toName);
}
static <T> MinecraftHasher<T> mapBuilder(MapBuilder<T> builder) {

View file

@ -45,12 +45,15 @@ import org.geysermc.geyser.session.cache.registry.JavaRegistryKey;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect;
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType;
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.PaintingVariant;
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ArmorTrim;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BeehiveOccupant;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BlocksAttacks;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ConsumeEffect;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponent;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
@ -58,6 +61,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Fireworks;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.InstrumentComponent;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.JukeboxPlayable;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectInstance;
@ -72,6 +76,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.IntStream;
public interface RegistryHasher extends MinecraftHasher<Integer> {
@ -84,6 +89,10 @@ public interface RegistryHasher extends MinecraftHasher<Integer> {
RegistryHasher ENCHANTMENT = registry(JavaRegistries.ENCHANTMENT);
RegistryHasher ATTRIBUTE = enumIdRegistry(AttributeType.Builtin.values(), AttributeType.Builtin::getIdentifier);
RegistryHasher DAMAGE_TYPE = registry(JavaRegistries.DAMAGE_TYPE);
MinecraftHasher<DataComponentType<?>> DATA_COMPONENT_TYPE = KEY.convert(DataComponentType::getKey);
@SuppressWarnings({"unchecked", "rawtypes"}) // Java generics :(
@ -144,6 +153,19 @@ public interface RegistryHasher extends MinecraftHasher<Integer> {
MinecraftHasher<ItemEnchantments> ITEM_ENCHANTMENTS = MinecraftHasher.map(RegistryHasher.ENCHANTMENT, MinecraftHasher.INT).convert(ItemEnchantments::getEnchantments);
MinecraftHasher<ModifierOperation> ATTRIBUTE_MODIFIER_OPERATION = MinecraftHasher.fromEnum(operation -> switch (operation) {
case ADD -> "add_value";
case ADD_MULTIPLIED_BASE -> "add_multiplied_base";
case ADD_MULTIPLIED_TOTAL -> "add_multiplied_total";
});
MinecraftHasher<ItemAttributeModifiers.Entry> ATTRIBUTE_MODIFIER_ENTRY = MinecraftHasher.mapBuilder(builder -> builder
.accept("type", RegistryHasher.ATTRIBUTE, ItemAttributeModifiers.Entry::getAttribute)
.accept("id", KEY, entry -> entry.getModifier().getId())
.accept("amount", DOUBLE, entry -> entry.getModifier().getAmount())
.accept("operation", ATTRIBUTE_MODIFIER_OPERATION, entry -> entry.getModifier().getOperation())
.optional("slot", EQUIPMENT_SLOT_GROUP, ItemAttributeModifiers.Entry::getSlot, ItemAttributeModifiers.EquipmentSlotGroup.ANY));
MinecraftHasher<ConsumeEffectType> CONSUME_EFFECT_TYPE = enumRegistry();
MinecraftHasher<ConsumeEffect> CONSUME_EFFECT = CONSUME_EFFECT_TYPE.dispatch(ConsumeEffectType::fromEffect, type -> type.getBuilder().cast());
@ -163,6 +185,17 @@ public interface RegistryHasher extends MinecraftHasher<Integer> {
.optionalNullable("speed", MinecraftHasher.FLOAT, ToolData.Rule::getSpeed)
.optionalNullable("correct_for_drops", MinecraftHasher.BOOL, ToolData.Rule::getCorrectForDrops));
MinecraftHasher<BlocksAttacks.DamageReduction> BLOCKS_ATTACKS_DAMAGE_REDUCTION = MinecraftHasher.mapBuilder(builder -> builder
.optional("horizontal_blocking_angle", FLOAT, BlocksAttacks.DamageReduction::horizontalBlockingAngle, 90.0F)
.optionalNullable("type", DAMAGE_TYPE.holderSet(), BlocksAttacks.DamageReduction::type)
.accept("base", FLOAT, BlocksAttacks.DamageReduction::base)
.accept("factor", FLOAT, BlocksAttacks.DamageReduction::factor));
MinecraftHasher<BlocksAttacks.ItemDamageFunction> BLOCKS_ATTACKS_ITEM_DAMAGE_FUNCTION = MinecraftHasher.mapBuilder(builder -> builder
.accept("threshold", FLOAT, BlocksAttacks.ItemDamageFunction::threshold)
.accept("base", FLOAT, BlocksAttacks.ItemDamageFunction::base)
.accept("factor", FLOAT, BlocksAttacks.ItemDamageFunction::factor));
MinecraftHasher<Map<Key, String>> TRIM_MATERIAL_ASSET_OVERRIDES = MinecraftHasher.map(KEY, STRING);
MinecraftHasher<ArmorTrim.TrimMaterial> DIRECT_TRIM_MATERIAL = MinecraftHasher.mapBuilder(builder -> builder
@ -221,6 +254,8 @@ public interface RegistryHasher extends MinecraftHasher<Integer> {
RegistryHasher WOLF_VARIANT = registry(JavaRegistries.WOLF_VARIANT);
RegistryHasher WOLF_SOUND_VARIANT = registry(JavaRegistries.WOLF_SOUND_VARIANT);
MinecraftHasher<Integer> FOX_VARIANT = MinecraftHasher.fromIdEnum(FoxVariant.values());
MinecraftHasher<Integer> SALMON_VARIANT = MinecraftHasher.fromIdEnum(SalmonVariant.values());
@ -278,7 +313,11 @@ public interface RegistryHasher extends MinecraftHasher<Integer> {
}
static <T extends Enum<T>> RegistryHasher enumIdRegistry(T[] values) {
MinecraftHasher<Integer> hasher = KEY.convert(i -> MinecraftKey.key(values[i].name().toLowerCase()));
return enumIdRegistry(values, t -> MinecraftKey.key(t.name().toLowerCase()));
}
static <T extends Enum<T>> RegistryHasher enumIdRegistry(T[] values, Function<T, Key> toKey) {
MinecraftHasher<Integer> hasher = KEY.convert(i -> toKey.apply(values[i]));
return hasher::hash;
}

View file

@ -51,6 +51,7 @@ import org.geysermc.geyser.session.cache.registry.JavaRegistry;
import org.geysermc.geyser.session.cache.registry.JavaRegistryKey;
import org.geysermc.geyser.session.cache.registry.RegistryEntryContext;
import org.geysermc.geyser.session.cache.registry.RegistryEntryData;
import org.geysermc.geyser.session.cache.registry.RegistryUnit;
import org.geysermc.geyser.session.cache.registry.SimpleJavaRegistry;
import org.geysermc.geyser.text.ChatDecoration;
import org.geysermc.geyser.translator.level.BiomeTranslator;
@ -63,7 +64,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
* Stores any information sent via Java registries. May not contain all data in a given registry - we'll strip what's
@ -73,7 +73,7 @@ import java.util.function.Function;
*/
public final class RegistryCache {
private static final Map<JavaRegistryKey<?>, Map<Key, NbtMap>> DEFAULTS;
private static final Map<JavaRegistryKey<?>, RegistryEntryReader<?>> READERS = new HashMap<>();
private static final Map<JavaRegistryKey<?>, RegistryLoader<?>> READERS = new HashMap<>();
static {
register(JavaRegistries.CHAT_TYPE, ChatDecoration::readChatType);
@ -86,10 +86,12 @@ public final class RegistryCache {
register(JavaRegistries.PAINTING_VARIANT, context -> PaintingType.getByName(context.id()));
register(JavaRegistries.TRIM_MATERIAL, TrimRecipe::readTrimMaterial);
register(JavaRegistries.TRIM_PATTERN, TrimRecipe::readTrimPattern);
register(JavaRegistries.DAMAGE_TYPE, RegistryReader.UNIT);
register(JavaRegistries.CAT_VARIANT, VariantHolder.reader(CatEntity.BuiltInVariant.class, CatEntity.BuiltInVariant.BLACK));
register(JavaRegistries.FROG_VARIANT, VariantHolder.reader(FrogEntity.BuiltInVariant.class, FrogEntity.BuiltInVariant.TEMPERATE));
register(JavaRegistries.WOLF_VARIANT, VariantHolder.reader(WolfEntity.BuiltInVariant.class, WolfEntity.BuiltInVariant.PALE));
register(JavaRegistries.WOLF_SOUND_VARIANT, RegistryReader.UNIT);
register(JavaRegistries.PIG_VARIANT, TemperatureVariantAnimal.VARIANT_READER);
register(JavaRegistries.COW_VARIANT, TemperatureVariantAnimal.VARIANT_READER);
@ -131,7 +133,7 @@ public final class RegistryCache {
JavaRegistryKey<?> registryKey = JavaRegistries.fromKey(packet.getRegistry());
if (registryKey != null) {
// Java generic mess - we're sure we're putting the current readers for the correct registry types in the READERS map, so we use raw objects here to let it compile
RegistryEntryReader reader = READERS.get(registryKey);
RegistryLoader reader = READERS.get(registryKey);
if (reader != null) {
reader.load(session, registries.get(registryKey), packet.getEntries());
} else {
@ -154,7 +156,7 @@ public final class RegistryCache {
* @param reader converts the RegistryEntry NBT into an object. Should never return null, rather return a default value!
* @param <T> the class that represents these entries.
*/
private static <T> void register(JavaRegistryKey<T> registryKey, Function<RegistryEntryContext, T> reader) {
private static <T> void register(JavaRegistryKey<T> registryKey, RegistryReader<T> reader) {
register(registryKey, (session, registry, entries) -> {
Map<Key, NbtMap> localRegistry = null;
@ -180,7 +182,7 @@ public final class RegistryCache {
RegistryEntryContext context = new RegistryEntryContext(entry, entryIdMap, session);
// This is what Geyser wants to keep as a value for this registry.
T cacheEntry = reader.apply(context);
T cacheEntry = reader.read(context);
if (cacheEntry == null) {
// Registry readers should never return null, rather return a default value
throw new IllegalStateException("Registry reader returned null for an entry!");
@ -191,7 +193,7 @@ public final class RegistryCache {
});
}
private static <T> void register(JavaRegistryKey<T> registryKey, RegistryEntryReader<T> reader) {
private static <T> void register(JavaRegistryKey<T> registryKey, RegistryLoader<T> reader) {
READERS.put(registryKey, reader);
}
@ -200,7 +202,15 @@ public final class RegistryCache {
}
@FunctionalInterface
interface RegistryEntryReader<T> {
public interface RegistryReader<T> {
RegistryReader<RegistryUnit> UNIT = context -> RegistryUnit.INSTANCE;
T read(RegistryEntryContext context);
}
@FunctionalInterface
private interface RegistryLoader<T> {
void load(GeyserSession session, JavaRegistry<T> registry, List<RegistryEntry> entries);
}

View file

@ -69,10 +69,12 @@ public class JavaRegistries {
public static final JavaRegistryKey<PaintingType> PAINTING_VARIANT = create("painting_variant");
public static final JavaRegistryKey<TrimMaterial> TRIM_MATERIAL = create("trim_material");
public static final JavaRegistryKey<TrimPattern> TRIM_PATTERN = create("trim_pattern");
public static final JavaRegistryKey<RegistryUnit> DAMAGE_TYPE = create("damage_type");
public static final JavaRegistryKey<CatEntity.BuiltInVariant> CAT_VARIANT = create("cat_variant");
public static final JavaRegistryKey<FrogEntity.BuiltInVariant> FROG_VARIANT = create("frog_variant");
public static final JavaRegistryKey<WolfEntity.BuiltInVariant> WOLF_VARIANT = create("wolf_variant");
public static final JavaRegistryKey<RegistryUnit> WOLF_SOUND_VARIANT = create("wolf_sound_variant");
public static final JavaRegistryKey<TemperatureVariantAnimal.BuiltInVariant> PIG_VARIANT = create("pig_variant");
public static final JavaRegistryKey<TemperatureVariantAnimal.BuiltInVariant> COW_VARIANT = create("cow_variant");

View file

@ -25,6 +25,11 @@
package org.geysermc.geyser.session.cache.registry;
/**
* Used with {@link org.geysermc.geyser.session.cache.RegistryCache.RegistryReader#UNIT} to load registries without loading any data.
*
* <p>This is usually done when registries need to be loaded to make ID->key or key->ID conversions, but actual data isn't needed.</p>
*/
public enum RegistryUnit {
INSTANCE
}

View file

@ -15,7 +15,7 @@ protocol-common = "3.0.0.Beta6-20250324.162731-5"
protocol-codec = "3.0.0.Beta6-20250324.162731-5"
raknet = "1.0.0.CR3-20250218.160705-18"
minecraftauth = "4.1.1"
mcprotocollib = "1.21.5-20250325.093126-16"
mcprotocollib = "1.21.5-20250328.173210-19"
adventure = "4.14.0"
adventure-platform = "4.3.0"
junit = "5.9.2"