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:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user