diff --git a/src/main/java/xyz/eclipseisoffline/geyser/GeyserMapping.java b/src/main/java/xyz/eclipseisoffline/geyser/GeyserMapping.java index 4ced37b..6bc0e43 100644 --- a/src/main/java/xyz/eclipseisoffline/geyser/GeyserMapping.java +++ b/src/main/java/xyz/eclipseisoffline/geyser/GeyserMapping.java @@ -2,24 +2,32 @@ package xyz.eclipseisoffline.geyser; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.core.component.DataComponentMap; +import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.component.DataComponentType; import net.minecraft.core.component.DataComponents; -import net.minecraft.core.component.TypedDataComponent; import net.minecraft.resources.ResourceLocation; import java.util.List; import java.util.Optional; import java.util.function.Function; -public record GeyserMapping(ResourceLocation model, ResourceLocation bedrockIdentifier, BedrockOptions bedrockOptions, DataComponentMap components) { +// TODO predicates, etc. +public record GeyserMapping(ResourceLocation model, ResourceLocation bedrockIdentifier, Optional displayName, + BedrockOptions bedrockOptions, DataComponentPatch components) { private static final List> SUPPORTED_COMPONENTS = List.of(DataComponents.CONSUMABLE, DataComponents.EQUIPPABLE, DataComponents.FOOD, DataComponents.MAX_DAMAGE, DataComponents.MAX_STACK_SIZE, DataComponents.USE_COOLDOWN, DataComponents.ENCHANTABLE, DataComponents.ENCHANTMENT_GLINT_OVERRIDE); - private static final Codec FILTERED_COMPONENT_MAP_CODEC = DataComponentMap.CODEC.xmap(Function.identity(), map -> { - DataComponentMap.Builder filtered = DataComponentMap.builder(); - map.stream().filter(component -> SUPPORTED_COMPONENTS.contains(component.type())) - .forEach(component -> setTypedComponent(filtered, component)); + private static final Codec FILTERED_COMPONENT_MAP_CODEC = DataComponentPatch.CODEC.xmap(Function.identity(), patch -> { + DataComponentPatch.Builder filtered = DataComponentPatch.builder(); + patch.entrySet().stream() + .filter(entry -> entry.getValue().isEmpty() || SUPPORTED_COMPONENTS.contains(entry.getKey())) + .forEach(entry -> { + if (entry.getValue().isPresent()) { + filtered.set((DataComponentType) entry.getKey(), entry.getValue().orElseThrow()); + } else { + filtered.remove(entry.getKey()); + } + }); return filtered.build(); }); @@ -28,24 +36,21 @@ public record GeyserMapping(ResourceLocation model, ResourceLocation bedrockIden Codec.STRING.fieldOf("type").forGetter(mapping -> "definition"), ResourceLocation.CODEC.fieldOf("model").forGetter(GeyserMapping::model), ResourceLocation.CODEC.fieldOf("bedrock_identifier").forGetter(GeyserMapping::bedrockIdentifier), + Codec.STRING.optionalFieldOf("display_name").forGetter(GeyserMapping::displayName), BedrockOptions.CODEC.fieldOf("bedrock_options").forGetter(GeyserMapping::bedrockOptions), FILTERED_COMPONENT_MAP_CODEC.fieldOf("components").forGetter(GeyserMapping::components) - ).apply(instance, (type, model, bedrockIdentifier, bedrockOptions, components) - -> new GeyserMapping(model, bedrockIdentifier, bedrockOptions, components)) + ).apply(instance, (type, model, bedrockIdentifier, displayName, bedrockOptions, components) + -> new GeyserMapping(model, bedrockIdentifier, displayName, bedrockOptions, components)) ); public record BedrockOptions(Optional icon, boolean allowOffhand, boolean displayHandheld, int protectionValue) { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codec.STRING.optionalFieldOf("icon").forGetter(BedrockOptions::icon), - Codec.BOOL.fieldOf("allow_offhand").forGetter(BedrockOptions::allowOffhand), - Codec.BOOL.fieldOf("display_handheld").forGetter(BedrockOptions::displayHandheld), - Codec.INT.fieldOf("protection_value").forGetter(BedrockOptions::protectionValue) + Codec.BOOL.optionalFieldOf("allow_offhand", true).forGetter(BedrockOptions::allowOffhand), + Codec.BOOL.optionalFieldOf("display_handheld", false).forGetter(BedrockOptions::displayHandheld), + Codec.INT.optionalFieldOf("protection_value", 0).forGetter(BedrockOptions::protectionValue) ).apply(instance, BedrockOptions::new) ); } - - private static void setTypedComponent(DataComponentMap.Builder builder, TypedDataComponent component) { - builder.set(component.type(), component.value()); - } } diff --git a/src/main/java/xyz/eclipseisoffline/geyser/PackManager.java b/src/main/java/xyz/eclipseisoffline/geyser/PackManager.java index 0dd1f7f..7171667 100644 --- a/src/main/java/xyz/eclipseisoffline/geyser/PackManager.java +++ b/src/main/java/xyz/eclipseisoffline/geyser/PackManager.java @@ -51,9 +51,10 @@ public final class PackManager { } ResourceLocation model = patchedModel.get(); - GeyserMapping mapping = new GeyserMapping(model, model, + String displayName = stack.getHoverName().getString(); + GeyserMapping mapping = new GeyserMapping(model, model, Optional.of(displayName), new GeyserMapping.BedrockOptions(Optional.empty(), true, false, 0), - stack.getComponentsPatch().split().added()); // TODO removed components + stack.getComponentsPatch()); mappings.map(stack.getItemHolder(), mapping); return true;