mirror of
https://github.com/GeyserMC/Geyser.git
synced 2026-01-04 15:31:36 +00:00
More component hashers, also need tests
This commit is contained in:
@@ -45,6 +45,7 @@ public final class TrimRecipe {
|
||||
public static final ItemDescriptorWithCount ADDITION = tagDescriptor("minecraft:trim_materials");
|
||||
public static final ItemDescriptorWithCount TEMPLATE = tagDescriptor("minecraft:trim_templates");
|
||||
|
||||
// TODO this is WRONG. this changed. FIXME in 1.21.5
|
||||
public static TrimMaterial readTrimMaterial(RegistryEntryContext context) {
|
||||
String key = context.id().asMinimalString();
|
||||
|
||||
@@ -65,6 +66,7 @@ public final class TrimRecipe {
|
||||
return new TrimMaterial(key, legacy.substring(2).trim(), itemMapping.getBedrockIdentifier());
|
||||
}
|
||||
|
||||
// TODO this is WRONG. this changed. FIXME in 1.21.5
|
||||
public static TrimPattern readTrimPattern(RegistryEntryContext context) {
|
||||
String key = context.id().asMinimalString();
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.FoodProperti
|
||||
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.ItemEnchantments;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectDetails;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectInstance;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
|
||||
@@ -57,6 +58,8 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.TooltipDispl
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Unit;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.UseCooldown;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Weapon;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.WritableBookContent;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -164,15 +167,35 @@ public class DataComponentHashers {
|
||||
register(DataComponentTypes.POTION_DURATION_SCALE, MinecraftHasher.FLOAT);
|
||||
register(DataComponentTypes.SUSPICIOUS_STEW_EFFECTS, RegistryHasher.SUSPICIOUS_STEW_EFFECT.list());
|
||||
|
||||
// TODO writable book content
|
||||
// TODO written book content
|
||||
// TODO trim
|
||||
registerMap(DataComponentTypes.WRITABLE_BOOK_CONTENT, builder -> builder
|
||||
.optionalList("pages", MinecraftHasher.STRING.filterable(), WritableBookContent::getPages));
|
||||
registerMap(DataComponentTypes.WRITTEN_BOOK_CONTENT, builder -> builder
|
||||
.accept("title", MinecraftHasher.STRING.filterable(), WrittenBookContent::getTitle)
|
||||
.accept("author", MinecraftHasher.STRING, WrittenBookContent::getAuthor)
|
||||
.accept("generation", MinecraftHasher.INT, WrittenBookContent::getGeneration)
|
||||
.optionalList("pages", ComponentHasher.COMPONENT.filterable(), WrittenBookContent::getPages)
|
||||
.optional("resolved", MinecraftHasher.BOOL, WrittenBookContent::isResolved, false));
|
||||
|
||||
register(DataComponentTypes.TRIM, RegistryHasher.ARMOR_TRIM);
|
||||
register(DataComponentTypes.DEBUG_STICK_STATE, MinecraftHasher.NBT_MAP);
|
||||
register(DataComponentTypes.ENTITY_DATA, MinecraftHasher.NBT_MAP);
|
||||
register(DataComponentTypes.BUCKET_ENTITY_DATA, MinecraftHasher.NBT_MAP);
|
||||
register(DataComponentTypes.BLOCK_ENTITY_DATA, MinecraftHasher.NBT_MAP);
|
||||
|
||||
register(DataComponentTypes.INSTRUMENT, RegistryHasher.INSTRUMENT_COMPONENT);
|
||||
register(DataComponentTypes.PROVIDES_TRIM_MATERIAL, RegistryHasher.PROVIDES_TRIM_MATERIAL);
|
||||
|
||||
registerInt(DataComponentTypes.OMINOUS_BOTTLE_AMPLIFIER);
|
||||
|
||||
register(DataComponentTypes.JUKEBOX_PLAYABLE, RegistryHasher.JUKEBOX_PLAYABLE);
|
||||
register(DataComponentTypes.PROVIDES_BANNER_PATTERNS, MinecraftHasher.TAG);
|
||||
register(DataComponentTypes.RECIPES, MinecraftHasher.NBT_LIST);
|
||||
|
||||
registerMap(DataComponentTypes.LODESTONE_TRACKER, builder -> builder
|
||||
.optionalNullable("target", MinecraftHasher.GLOBAL_POS, LodestoneTracker::getPos)
|
||||
.optional("tracked", MinecraftHasher.BOOL, LodestoneTracker::isTracked, true));
|
||||
|
||||
// TODO firework explosion, fireworks
|
||||
}
|
||||
|
||||
private static void registerUnit(DataComponentType<Unit> component) {
|
||||
|
||||
@@ -28,11 +28,15 @@ package org.geysermc.geyser.item.hashing;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.hash.HashCode;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.geyser.item.components.Rarity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
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.Unit;
|
||||
|
||||
import java.util.List;
|
||||
@@ -71,6 +75,10 @@ public interface MinecraftHasher<T> {
|
||||
|
||||
MinecraftHasher<NbtMap> NBT_MAP = (map, encoder) -> encoder.nbtMap(map);
|
||||
|
||||
MinecraftHasher<NbtList<?>> NBT_LIST = (list, encoder) -> encoder.nbtList(list);
|
||||
|
||||
MinecraftHasher<Vector3i> POS = INT_ARRAY.convert(pos -> IntStream.of(pos.getX(), pos.getY(), pos.getZ()));
|
||||
|
||||
MinecraftHasher<Key> KEY = STRING.convert(Key::asString);
|
||||
|
||||
MinecraftHasher<Key> TAG = STRING.convert(key -> "#" + key.asString());
|
||||
@@ -87,12 +95,22 @@ public interface MinecraftHasher<T> {
|
||||
|
||||
MinecraftHasher<EquipmentSlot> EQUIPMENT_SLOT = fromEnum(); // FIXME MCPL enum constants aren't right
|
||||
|
||||
MinecraftHasher<GlobalPos> GLOBAL_POS = mapBuilder(builder -> builder
|
||||
.accept("dimension", KEY, GlobalPos::getDimension)
|
||||
.accept("pos", POS, GlobalPos::getPosition));
|
||||
|
||||
HashCode hash(T value, MinecraftHashEncoder encoder);
|
||||
|
||||
default MinecraftHasher<List<T>> list() {
|
||||
return (list, encoder) -> encoder.list(list.stream().map(element -> hash(element, encoder)).toList());
|
||||
}
|
||||
|
||||
default MinecraftHasher<Filterable<T>> filterable() {
|
||||
return mapBuilder(builder -> builder
|
||||
.accept("raw", this, Filterable::getRaw)
|
||||
.optionalNullable("filtered", this, Filterable::getOptional));
|
||||
}
|
||||
|
||||
default <D> MinecraftHasher<D> dispatch(String typeKey, Function<D, T> typeExtractor, Function<T, MapBuilder<D>> hashDispatch) {
|
||||
return mapBuilder(builder -> builder
|
||||
.accept(typeKey, this, typeExtractor)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.item.hashing;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.geysermc.geyser.inventory.item.Potion;
|
||||
import org.geysermc.geyser.session.cache.registry.JavaRegistries;
|
||||
import org.geysermc.geyser.session.cache.registry.JavaRegistryKey;
|
||||
@@ -33,12 +34,15 @@ 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.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.DataComponent;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
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.JukeboxPlayable;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectInstance;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ProvidesTrimMaterial;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.SuspiciousStewEffect;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ToolData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.sound.BuiltinSound;
|
||||
@@ -46,6 +50,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.sound.CustomSound;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.sound.Sound;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
public interface RegistryHasher extends MinecraftHasher<Integer> {
|
||||
|
||||
@@ -118,12 +123,44 @@ public interface RegistryHasher extends MinecraftHasher<Integer> {
|
||||
.optionalNullable("speed", MinecraftHasher.FLOAT, ToolData.Rule::getSpeed)
|
||||
.optionalNullable("correct_for_drops", MinecraftHasher.BOOL, ToolData.Rule::getCorrectForDrops));
|
||||
|
||||
MinecraftHasher<Map<Key, String>> TRIM_MATERIAL_ASSET_OVERRIDES = MinecraftHasher.map(KEY, STRING);
|
||||
|
||||
MinecraftHasher<ArmorTrim.TrimMaterial> DIRECT_TRIM_MATERIAL = MinecraftHasher.mapBuilder(builder -> builder
|
||||
.accept("asset_name", MinecraftHasher.STRING, ArmorTrim.TrimMaterial::assetBase)
|
||||
.optional("override_armor_assets", TRIM_MATERIAL_ASSET_OVERRIDES, ArmorTrim.TrimMaterial::assetOverrides, Map.of())
|
||||
.accept("description", ComponentHasher.COMPONENT, ArmorTrim.TrimMaterial::description));
|
||||
|
||||
MinecraftHasher<Holder<ArmorTrim.TrimMaterial>> TRIM_MATERIAL = holder(JavaRegistries.TRIM_MATERIAL, DIRECT_TRIM_MATERIAL);
|
||||
|
||||
MinecraftHasher<ProvidesTrimMaterial> PROVIDES_TRIM_MATERIAL = MinecraftHasher.either(TRIM_MATERIAL, ProvidesTrimMaterial::materialHolder, KEY, ProvidesTrimMaterial::materialLocation);
|
||||
|
||||
MinecraftHasher<ArmorTrim.TrimPattern> DIRECT_TRIM_PATTERN = MinecraftHasher.mapBuilder(builder -> builder
|
||||
.accept("asset_id", KEY, ArmorTrim.TrimPattern::assetId)
|
||||
.accept("description", ComponentHasher.COMPONENT, ArmorTrim.TrimPattern::description)
|
||||
.accept("decal", BOOL, ArmorTrim.TrimPattern::decal));
|
||||
|
||||
MinecraftHasher<Holder<ArmorTrim.TrimPattern>> TRIM_PATTERN = holder(JavaRegistries.TRIM_PATTERN, DIRECT_TRIM_PATTERN);
|
||||
|
||||
MinecraftHasher<ArmorTrim> ARMOR_TRIM = MinecraftHasher.mapBuilder(builder -> builder
|
||||
.accept("material", TRIM_MATERIAL, ArmorTrim::material)
|
||||
.accept("pattern", TRIM_PATTERN, ArmorTrim::pattern));
|
||||
|
||||
MinecraftHasher<JukeboxPlayable.JukeboxSong> DIRECT_JUKEBOX_SONG = MinecraftHasher.mapBuilder(builder -> builder
|
||||
.accept("sound_event", SOUND_EVENT, JukeboxPlayable.JukeboxSong::soundEvent)
|
||||
.accept("description", ComponentHasher.COMPONENT, JukeboxPlayable.JukeboxSong::description)
|
||||
.accept("length_in_seconds", FLOAT, JukeboxPlayable.JukeboxSong::lengthInSeconds)
|
||||
.accept("comparator_output", INT, JukeboxPlayable.JukeboxSong::comparatorOutput));
|
||||
|
||||
MinecraftHasher<Holder<JukeboxPlayable.JukeboxSong>> JUKEBOX_SONG = holder(JavaRegistries.JUKEBOX_SONG, DIRECT_JUKEBOX_SONG);
|
||||
|
||||
MinecraftHasher<JukeboxPlayable> JUKEBOX_PLAYABLE = MinecraftHasher.either(JUKEBOX_SONG, JukeboxPlayable::songHolder, KEY, JukeboxPlayable::songLocation);
|
||||
|
||||
static RegistryHasher registry(JavaRegistryKey<?> registry) {
|
||||
MinecraftHasher<Integer> hasher = KEY.sessionConvert(registry::keyFromNetworkId);
|
||||
return hasher::hash;
|
||||
}
|
||||
|
||||
// We don't need the registry generic type, and this works easier for goat horn instruments
|
||||
// We don't need the registry generic type, and this works easier for goat horn instruments and other registries
|
||||
static <T> MinecraftHasher<Holder<T>> holder(JavaRegistryKey<?> registry, MinecraftHasher<T> direct) {
|
||||
RegistryHasher registryHasher = registry(registry);
|
||||
return (value, encoder) -> {
|
||||
|
||||
@@ -91,10 +91,10 @@ public final class RegistryCache {
|
||||
register("dimension_type", cache -> cache.dimensions, JavaDimension::read);
|
||||
register(JavaRegistries.ENCHANTMENT, cache -> cache.enchantments, Enchantment::read);
|
||||
register(JavaRegistries.INSTRUMENT, cache -> cache.instruments, GeyserInstrument::read);
|
||||
register("jukebox_song", cache -> cache.jukeboxSongs, JukeboxSong::read);
|
||||
register(JavaRegistries.JUKEBOX_SONG, cache -> cache.jukeboxSongs, JukeboxSong::read);
|
||||
register("painting_variant", cache -> cache.paintings, context -> PaintingType.getByName(context.id()));
|
||||
register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial);
|
||||
register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern);
|
||||
register(JavaRegistries.TRIM_MATERIAL, cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial);
|
||||
register(JavaRegistries.TRIM_PATTERN, cache -> cache.trimPatterns, TrimRecipe::readTrimPattern);
|
||||
register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome);
|
||||
register("banner_pattern", cache -> cache.bannerPatterns, context -> BannerPattern.getByJavaIdentifier(context.id()));
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ package org.geysermc.geyser.session.cache.registry;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.protocol.bedrock.data.TrimMaterial;
|
||||
import org.cloudburstmc.protocol.bedrock.data.TrimPattern;
|
||||
import org.geysermc.geyser.entity.type.living.animal.FrogEntity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.farm.TemperatureVariantAnimal;
|
||||
import org.geysermc.geyser.entity.type.living.animal.tameable.CatEntity;
|
||||
@@ -35,6 +37,7 @@ import org.geysermc.geyser.inventory.item.BannerPattern;
|
||||
import org.geysermc.geyser.inventory.item.GeyserInstrument;
|
||||
import org.geysermc.geyser.item.enchantment.Enchantment;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.level.JukeboxSong;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.registry.ListRegistry;
|
||||
@@ -57,6 +60,9 @@ public class JavaRegistries {
|
||||
public static final JavaRegistryKey<Enchantment> ENCHANTMENT = create("enchantment", RegistryCache::enchantments);
|
||||
public static final JavaRegistryKey<BannerPattern> BANNER_PATTERN = create("banner_pattern", RegistryCache::bannerPatterns);
|
||||
public static final JavaRegistryKey<GeyserInstrument> INSTRUMENT = create("instrument", RegistryCache::instruments);
|
||||
public static final JavaRegistryKey<JukeboxSong> JUKEBOX_SONG = create("jukebox_song", RegistryCache::jukeboxSongs);
|
||||
public static final JavaRegistryKey<TrimMaterial> TRIM_MATERIAL = create("trim_material", RegistryCache::trimMaterials);
|
||||
public static final JavaRegistryKey<TrimPattern> TRIM_PATTERN = create("trim_pattern", RegistryCache::trimPatterns);
|
||||
|
||||
public static final JavaRegistryKey<CatEntity.BuiltInVariant> CAT_VARIANT = create("cat_variant", RegistryCache::catVariants);
|
||||
public static final JavaRegistryKey<FrogEntity.BuiltInVariant> FROG_VARIANT = create("frog_variant", RegistryCache::frogVariants);
|
||||
|
||||
Reference in New Issue
Block a user