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.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<String> displayName,
BedrockOptions bedrockOptions, DataComponentPatch components) {
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);
private static final Codec<DataComponentMap> 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<DataComponentPatch> 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<String> icon, boolean allowOffhand, boolean displayHandheld, int protectionValue) {
public static final Codec<BedrockOptions> 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 <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();
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;