1
0
mirror of https://github.com/GeyserMC/Rainbow.git synced 2025-12-19 14:59:16 +00:00

Properly write data component patches/removed components and display name

This commit is contained in:
Eclipse
2025-06-28 15:06:36 +00:00
parent ff82734d6a
commit 80e3f1f591
2 changed files with 24 additions and 18 deletions

View File

@@ -2,24 +2,32 @@ package xyz.eclipseisoffline.geyser;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder; 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.DataComponentType;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
import net.minecraft.core.component.TypedDataComponent;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function; 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<String> displayName,
BedrockOptions bedrockOptions, DataComponentPatch components) {
private static final List<DataComponentType<?>> SUPPORTED_COMPONENTS = List.of(DataComponents.CONSUMABLE, DataComponents.EQUIPPABLE, DataComponents.FOOD, private static final List<DataComponentType<?>> 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); DataComponents.MAX_DAMAGE, DataComponents.MAX_STACK_SIZE, DataComponents.USE_COOLDOWN, DataComponents.ENCHANTABLE, DataComponents.ENCHANTMENT_GLINT_OVERRIDE);
private static final Codec<DataComponentMap> FILTERED_COMPONENT_MAP_CODEC = DataComponentMap.CODEC.xmap(Function.identity(), map -> { private static final Codec<DataComponentPatch> FILTERED_COMPONENT_MAP_CODEC = DataComponentPatch.CODEC.xmap(Function.identity(), patch -> {
DataComponentMap.Builder filtered = DataComponentMap.builder(); DataComponentPatch.Builder filtered = DataComponentPatch.builder();
map.stream().filter(component -> SUPPORTED_COMPONENTS.contains(component.type())) patch.entrySet().stream()
.forEach(component -> setTypedComponent(filtered, component)); .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(); return filtered.build();
}); });
@@ -28,24 +36,21 @@ public record GeyserMapping(ResourceLocation model, ResourceLocation bedrockIden
Codec.STRING.fieldOf("type").forGetter(mapping -> "definition"), Codec.STRING.fieldOf("type").forGetter(mapping -> "definition"),
ResourceLocation.CODEC.fieldOf("model").forGetter(GeyserMapping::model), ResourceLocation.CODEC.fieldOf("model").forGetter(GeyserMapping::model),
ResourceLocation.CODEC.fieldOf("bedrock_identifier").forGetter(GeyserMapping::bedrockIdentifier), ResourceLocation.CODEC.fieldOf("bedrock_identifier").forGetter(GeyserMapping::bedrockIdentifier),
Codec.STRING.optionalFieldOf("display_name").forGetter(GeyserMapping::displayName),
BedrockOptions.CODEC.fieldOf("bedrock_options").forGetter(GeyserMapping::bedrockOptions), BedrockOptions.CODEC.fieldOf("bedrock_options").forGetter(GeyserMapping::bedrockOptions),
FILTERED_COMPONENT_MAP_CODEC.fieldOf("components").forGetter(GeyserMapping::components) FILTERED_COMPONENT_MAP_CODEC.fieldOf("components").forGetter(GeyserMapping::components)
).apply(instance, (type, model, bedrockIdentifier, bedrockOptions, components) ).apply(instance, (type, model, bedrockIdentifier, displayName, bedrockOptions, components)
-> new GeyserMapping(model, bedrockIdentifier, bedrockOptions, components)) -> new GeyserMapping(model, bedrockIdentifier, displayName, bedrockOptions, components))
); );
public record BedrockOptions(Optional<String> icon, boolean allowOffhand, boolean displayHandheld, int protectionValue) { public record BedrockOptions(Optional<String> icon, boolean allowOffhand, boolean displayHandheld, int protectionValue) {
public static final Codec<BedrockOptions> CODEC = RecordCodecBuilder.create(instance -> public static final Codec<BedrockOptions> CODEC = RecordCodecBuilder.create(instance ->
instance.group( instance.group(
Codec.STRING.optionalFieldOf("icon").forGetter(BedrockOptions::icon), Codec.STRING.optionalFieldOf("icon").forGetter(BedrockOptions::icon),
Codec.BOOL.fieldOf("allow_offhand").forGetter(BedrockOptions::allowOffhand), Codec.BOOL.optionalFieldOf("allow_offhand", true).forGetter(BedrockOptions::allowOffhand),
Codec.BOOL.fieldOf("display_handheld").forGetter(BedrockOptions::displayHandheld), Codec.BOOL.optionalFieldOf("display_handheld", false).forGetter(BedrockOptions::displayHandheld),
Codec.INT.fieldOf("protection_value").forGetter(BedrockOptions::protectionValue) Codec.INT.optionalFieldOf("protection_value", 0).forGetter(BedrockOptions::protectionValue)
).apply(instance, BedrockOptions::new) ).apply(instance, BedrockOptions::new)
); );
} }
private static <T> void setTypedComponent(DataComponentMap.Builder builder, TypedDataComponent<T> component) {
builder.set(component.type(), component.value());
}
} }

View File

@@ -51,9 +51,10 @@ public final class PackManager {
} }
ResourceLocation model = patchedModel.get(); 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), new GeyserMapping.BedrockOptions(Optional.empty(), true, false, 0),
stack.getComponentsPatch().split().added()); // TODO removed components stack.getComponentsPatch());
mappings.map(stack.getItemHolder(), mapping); mappings.map(stack.getItemHolder(), mapping);
return true; return true;