Implement the changes in Geyser part 2

This commit is contained in:
Eclipse 2024-11-30 09:55:50 +00:00
parent efae1f3665
commit 8bbad9ddcd
No known key found for this signature in database
GPG key ID: 95E6998F82EC938A
3 changed files with 33 additions and 18 deletions

View file

@ -29,7 +29,9 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.kyori.adventure.key.Key;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.item.custom.v2.BedrockCreativeTab;
import org.geysermc.geyser.api.item.custom.v2.CustomItemBedrockOptions;
import org.geysermc.geyser.api.item.custom.v2.CustomItemDefinition;
import org.geysermc.geyser.item.exception.InvalidCustomMappingsFileException;
@ -79,13 +81,27 @@ public class MappingsReader_v2 extends MappingsReader {
throw new InvalidCustomMappingsFileException("Invalid item mappings entry");
}
JsonNode bedrockIdentifierNode = node.get("bedrock_identifier");
JsonNode model = node.get("model");
if (bedrockIdentifierNode == null || !bedrockIdentifierNode.isTextual() || bedrockIdentifierNode.asText().isEmpty()) {
throw new InvalidCustomMappingsFileException("An item entry has no bedrock identifier");
}
if (model == null || !model.isTextual() || model.asText().isEmpty()) {
throw new InvalidCustomMappingsFileException("An item entry has no model");
}
CustomItemDefinition.Builder builder = CustomItemDefinition.builder(Key.key(model.asText()));
// TODO name, predicate
Key bedrockIdentifier = Key.key(bedrockIdentifierNode.asText());
if (bedrockIdentifier.namespace().equals(Key.MINECRAFT_NAMESPACE)) {
bedrockIdentifier = Key.key(Constants.GEYSER_CUSTOM_NAMESPACE, bedrockIdentifier.value());
}
CustomItemDefinition.Builder builder = CustomItemDefinition.builder(bedrockIdentifier, Key.key(model.asText()));
if (node.has("display_name")) {
builder.displayName(node.get("display_name").asText());
}
// TODO predicate
builder.bedrockOptions(readBedrockOptions(node.get("bedrock_options")));
@ -116,7 +132,7 @@ public class MappingsReader_v2 extends MappingsReader {
}
if (node.has("creative_category")) {
builder.creativeCategory(node.get("creative_category").asInt());
builder.creativeCategory(BedrockCreativeTab.valueOf(node.get("creative_category").asText().toUpperCase()));
}
if (node.has("creative_group")) {

View file

@ -26,6 +26,7 @@
package org.geysermc.geyser.registry.populator;
import com.google.common.collect.Multimap;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
@ -36,6 +37,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ComponentItemData;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.item.custom.CustomRenderOffsets;
import org.geysermc.geyser.api.item.custom.NonVanillaCustomItemData;
import org.geysermc.geyser.api.item.custom.v2.BedrockCreativeTab;
import org.geysermc.geyser.api.item.custom.v2.CustomItemBedrockOptions;
import org.geysermc.geyser.api.item.custom.v2.CustomItemDefinition;
import org.geysermc.geyser.item.GeyserCustomMappingData;
@ -77,7 +79,6 @@ public class CustomItemRegistryPopulator_v2 {
public static void populate(Map<String, GeyserMappingItem> items, Multimap<String, CustomItemDefinition> customItems, List<NonVanillaCustomItemData> nonVanillaCustomItems /* TODO */) {
// TODO
System.out.println("reading mappings");
MappingsConfigReader mappingsConfigReader = new MappingsConfigReader();
// Load custom items from mappings files
mappingsConfigReader.loadItemMappingsFromJson((id, item) -> {
@ -104,12 +105,9 @@ public class CustomItemRegistryPopulator_v2 {
static boolean initialCheck(CustomItemDefinition item, Map<String, GeyserMappingItem> mappings) {
// TODO check if there's already a same model without predicate and this hasn't a predicate either
String name = item.bedrockIdentifier(); // TODO rename to identifier
if (name.isEmpty()) {
GeyserImpl.getInstance().getLogger().warning("Custom item name is empty?");
} else if (Character.isDigit(name.charAt(0))) {
// As of 1.19.31
GeyserImpl.getInstance().getLogger().warning("Custom item name (" + name + ") begins with a digit. This may cause issues!");
Key name = item.bedrockIdentifier();
if (name.namespace().equals(Key.MINECRAFT_NAMESPACE)) {
GeyserImpl.getInstance().getLogger().warning("Custom item namespace can't be minecraft");
}
return true;
}
@ -124,7 +122,7 @@ public class CustomItemRegistryPopulator_v2 {
NbtMapBuilder componentBuilder = NbtMap.builder();
DataComponents components = patchDataComponents(vanillaJavaItem, customItemDefinition);
setupBasicItemInfo(customItemDefinition.bedrockIdentifier(), customItemDefinition, components, itemProperties, componentBuilder);
setupBasicItemInfo(customItemDefinition, components, itemProperties, componentBuilder);
boolean canDestroyInCreative = true;
if (vanillaMapping.getToolType() != null) { // This is not using the isTool boolean because it is not just a render type here.
@ -166,7 +164,7 @@ public class CustomItemRegistryPopulator_v2 {
return builder;
}
private static void setupBasicItemInfo(String name, CustomItemDefinition definition, DataComponents components, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder) {
private static void setupBasicItemInfo(CustomItemDefinition definition, DataComponents components, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder) {
CustomItemBedrockOptions options = definition.bedrockOptions();
NbtMap iconMap = NbtMap.builder()
.putCompound("textures", NbtMap.builder()
@ -175,15 +173,15 @@ public class CustomItemRegistryPopulator_v2 {
.build();
itemProperties.putCompound("minecraft:icon", iconMap);
if (options.creativeCategory().isPresent()) {
itemProperties.putInt("creative_category", options.creativeCategory().getAsInt());
if (options.creativeCategory() != BedrockCreativeTab.NONE) {
itemProperties.putInt("creative_category", options.creativeCategory().ordinal());
if (options.creativeGroup() != null) {
itemProperties.putString("creative_group", options.creativeGroup());
}
}
componentBuilder.putCompound("minecraft:display_name", NbtMap.builder().putString("value", name).build()); // TODO
componentBuilder.putCompound("minecraft:display_name", NbtMap.builder().putString("value", definition.displayName()).build()); // TODO
// Add a Geyser tag to the item, allowing Molang queries
addItemTag(componentBuilder, "geyser:is_custom");
@ -324,7 +322,7 @@ public class CustomItemRegistryPopulator_v2 {
private static void computeConsumableProperties(Consumable consumable, boolean canAlwaysEat, NbtMapBuilder itemProperties, NbtMapBuilder componentBuilder) {
// this is the duration of the use animation in ticks; note that in behavior packs this is set as a float in seconds, but over the network it is an int in ticks
itemProperties.putInt("use_duration", (int) (consumable.consumeSeconds() * 20)); // TODO check and confirm
itemProperties.putInt("use_duration", (int) (consumable.consumeSeconds() * 20));
itemProperties.putInt("use_animation", BEDROCK_ANIMATIONS.get(consumable.animation()));

View file

@ -62,6 +62,7 @@ import org.geysermc.geyser.api.block.custom.CustomBlockData;
import org.geysermc.geyser.api.block.custom.CustomBlockState;
import org.geysermc.geyser.api.block.custom.NonVanillaCustomBlockData;
import org.geysermc.geyser.api.item.custom.NonVanillaCustomItemData;
import org.geysermc.geyser.api.item.custom.v2.BedrockCreativeTab;
import org.geysermc.geyser.api.item.custom.v2.CustomItemDefinition;
import org.geysermc.geyser.inventory.item.StoredItemMappings;
import org.geysermc.geyser.item.GeyserCustomMappingData;
@ -463,7 +464,7 @@ public class ItemRegistryPopulator {
for (CustomItemDefinition customItem : customItemsToLoad) {
int customProtocolId = nextFreeBedrockId++;
String customItemName = customItem instanceof NonVanillaCustomItemData nonVanillaItem ? nonVanillaItem.identifier() : Constants.GEYSER_CUSTOM_NAMESPACE + ":" + customItem.bedrockIdentifier(); // TODO bedrock identifier + non vanilla stuff
String customItemName = customItem instanceof NonVanillaCustomItemData nonVanillaItem ? nonVanillaItem.identifier() : customItem.bedrockIdentifier().asString(); // TODO non vanilla stuff
if (!registeredItemNames.add(customItemName)) {
if (firstMappingsPass) {
GeyserImpl.getInstance().getLogger().error("Custom item name '" + customItemName + "' already exists and was registered again! Skipping...");
@ -474,7 +475,7 @@ public class ItemRegistryPopulator {
GeyserCustomMappingData customMapping = CustomItemRegistryPopulator_v2.registerCustomItem(
customItemName, javaItem, mappingItem, customItem, customProtocolId);
if (customItem.bedrockOptions().creativeCategory().isPresent()) {
if (customItem.bedrockOptions().creativeCategory() != BedrockCreativeTab.NONE) {
creativeItems.add(ItemData.builder()
.netId(creativeNetId.incrementAndGet())
.definition(customMapping.itemDefinition())