Keep chugging away

This commit is contained in:
Camotoy 2024-04-20 14:55:30 -04:00
parent c1edf20734
commit 909139326d
No known key found for this signature in database
GPG Key ID: 7EEFB66FE798081F
26 changed files with 200 additions and 184 deletions

View File

@ -25,20 +25,21 @@
package org.geysermc.geyser.item;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.mc.protocol.data.game.item.component.DyedItemColor;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public interface DyeableLeatherItem {
static void translateNbtToBedrock(CompoundTag tag) {
CompoundTag displayTag = tag.get("display");
if (displayTag == null) {
static void translateComponentsToBedrock(DataComponents components, BedrockItemBuilder builder) {
DyedItemColor dyedItemColor = components.get(DataComponentType.DYED_COLOR);
if (dyedItemColor == null) {
return;
}
IntTag color = displayTag.remove("color");
if (color != null) {
tag.put(new IntTag("customColor", color.getValue()));
}
builder.putInt("customColor", dyedItemColor.getRgb());
}
static void translateNbtToJava(CompoundTag tag) {

View File

@ -25,14 +25,18 @@
package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.component.ArmorTrim;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.item.ArmorMaterial;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public class ArmorItem extends Item {
private final ArmorMaterial material;
@ -43,23 +47,26 @@ public class ArmorItem extends Item {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
if (tag.get("Trim") instanceof CompoundTag trim) {
StringTag material = trim.remove("material");
StringTag pattern = trim.remove("pattern");
ArmorTrim trim = components.get(DataComponentType.TRIM);
if (trim != null) {
// TODO material IDs
String material = trim.getMaterial().getAssetName();
String pattern = trim.getPattern().getAssetId();
// discard custom trim patterns/materials to prevent visual glitches on bedrock
if (!material.getValue().startsWith("minecraft:")
|| !pattern.getValue().startsWith("minecraft:")) {
tag.remove("Trim");
if (!material.startsWith("minecraft:")
|| !pattern.startsWith("minecraft:")) {
return;
}
NbtMapBuilder trimBuilder = NbtMap.builder();
// bedrock has an uppercase first letter key, and the value is not namespaced
trim.put(new StringTag("Material", stripNamespace(material.getValue())));
trim.put(new StringTag("Pattern", stripNamespace(pattern.getValue())));
trimBuilder.put("Material", stripNamespace(material));
trimBuilder.put("Pattern", stripNamespace(pattern));
builder.putCompound("Trim", trimBuilder.build());
}
}

View File

@ -26,12 +26,10 @@
package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public class AxolotlBucketItem extends Item {
public AxolotlBucketItem(String javaIdentifier, Builder builder) {
@ -39,15 +37,15 @@ public class AxolotlBucketItem extends Item {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
// Bedrock Edition displays the properties of the axolotl. Java does not.
// To work around this, set the custom name to the Axolotl translation and it's displayed correctly
tag.put(new ByteTag("AppendCustomName", (byte) 1));
tag.put(new StringTag("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.axolotl", session.locale())));
builder.putByte("AppendCustomName", 1);
builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.axolotl", session.locale()));
// Boilerplate required so the nametag does not appear as "Bucket of "
tag.put(new StringTag("ColorID", ""));
tag.put(new StringTag("BodyID", ""));
builder.putString("ColorID", "");
builder.putString("BodyID", "");
}
}

View File

@ -25,6 +25,8 @@
package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.component.BannerPatternLayer;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
@ -33,16 +35,14 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtList;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import java.util.ArrayList;
import java.util.List;
import static org.geysermc.erosion.util.BannerUtils.getJavaPatternTag;
public class BannerItem extends BlockItem {
/**
* Holds what a Java ominous banner pattern looks like.
@ -51,19 +51,20 @@ public class BannerItem extends BlockItem {
* ominous banners that we set instead. This variable is used to detect Java ominous banner patterns, and apply
* the correct ominous banner pattern if Bedrock pulls the item from creative.
*/
public static final ListTag OMINOUS_BANNER_PATTERN;
public static final List<BannerPatternLayer> OMINOUS_BANNER_PATTERN;
static {
OMINOUS_BANNER_PATTERN = new ListTag("Patterns");
// Construct what an ominous banner is supposed to look like
OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("mr", 9));
OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("bs", 8));
OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("cs", 7));
OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("bo", 8));
OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("ms", 15));
OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("hh", 8));
OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("mc", 8));
OMINOUS_BANNER_PATTERN.add(getJavaPatternTag("bo", 15));
OMINOUS_BANNER_PATTERN = List.of(
new BannerPatternLayer("mr", 9),
new BannerPatternLayer("bs", 8),
new BannerPatternLayer("cs", 7),
new BannerPatternLayer("bo", 8),
new BannerPatternLayer("ms", 15),
new BannerPatternLayer("hh", 8),
new BannerPatternLayer("mc", 8),
new BannerPatternLayer("bo", 15)
);
}
/**
@ -102,7 +103,7 @@ public class BannerItem extends BlockItem {
* @return The Java edition format pattern nbt
*/
public static CompoundTag getJavaBannerPattern(NbtMap pattern) {
return getJavaPatternTag(pattern.getString("Pattern"), 15 - pattern.getInt("Color"));
return new BannerPatternLayer(pattern.getString("Pattern"), 15 - pattern.getInt("Color"));
}
/**
@ -122,14 +123,14 @@ public class BannerItem extends BlockItem {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
CompoundTag blockEntityTag = tag.remove("BlockEntityTag");
if (blockEntityTag != null && blockEntityTag.get("Patterns") instanceof ListTag patterns) {
List<BannerPatternLayer> patterns = components.get(DataComponentType.BANNER_PATTERNS);
if (patterns != null) {
if (patterns.equals(OMINOUS_BANNER_PATTERN)) {
// Remove the current patterns and set the ominous banner type
tag.put(new IntTag("Type", 1));
builder.putInt("Type", 1);
} else {
invertBannerColors(patterns);
tag.put(patterns);

View File

@ -27,9 +27,10 @@ package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
@Deprecated
public class ChestItem extends BlockItem {
public ChestItem(String javaIdentifier, Builder builder) {
@ -37,18 +38,7 @@ public class ChestItem extends BlockItem {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
// Strip the BlockEntityTag from the chests contents
// sent to the client. The client does not parse this
// or use it for anything, as this tag is fully
// server-side, so we remove it to reduce bandwidth and
// solve potential issues with very large tags.
// There was a problem in the past where this would strip
// NBT data in creative mode, however with the new server
// authoritative inventories, this is no longer a concern.
tag.remove("BlockEntityTag");
}
}

View File

@ -26,17 +26,16 @@
package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.registry.type.ItemMappings;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public class CompassItem extends Item {
public CompassItem(String javaIdentifier, Builder builder) {
@ -45,36 +44,35 @@ public class CompassItem extends Item {
@Override
public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
if (isLodestoneCompass(itemStack.getNbt())) {
if (isLodestoneCompass(itemStack.getDataComponents())) {
return super.translateToBedrock(itemStack, mappings.getLodestoneCompass(), mappings);
}
return super.translateToBedrock(itemStack, mapping, mappings);
}
@Override
public ItemMapping toBedrockDefinition(CompoundTag nbt, ItemMappings mappings) {
if (isLodestoneCompass(nbt)) {
public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) {
if (isLodestoneCompass(components)) {
return mappings.getLodestoneCompass();
}
return super.toBedrockDefinition(nbt, mappings);
return super.toBedrockDefinition(components, mappings);
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
Tag lodestoneTag = tag.get("LodestoneTracked");
if (lodestoneTag instanceof ByteTag) {
int trackId = session.getLodestoneCache().store(tag);
LodestoneTracker tracker = components.get(DataComponentType.LODESTONE_TRACKER);
if (tracker != null) {
int trackId = session.getLodestoneCache().store(tracker);
// Set the bedrock tracking id - will return 0 if invalid
tag.put(new IntTag("trackingHandle", trackId));
builder.putInt("trackingHandle", trackId);
}
}
private boolean isLodestoneCompass(CompoundTag nbt) {
if (nbt != null) {
Tag lodestoneTag = nbt.get("LodestoneTracked");
return lodestoneTag instanceof ByteTag;
private boolean isLodestoneCompass(@Nullable DataComponents components) {
if (components != null) {
return components.getDataComponents().containsKey(DataComponentType.LODESTONE_TRACKER);
}
return false;
}

View File

@ -26,44 +26,41 @@
package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.opennbt.tag.builtin.*;
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.item.ItemTranslator;
import java.util.List;
public class CrossbowItem extends Item {
public CrossbowItem(String javaIdentifier, Builder builder) {
super(javaIdentifier, builder);
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
ListTag chargedProjectiles = tag.get("ChargedProjectiles");
if (chargedProjectiles != null) {
if (!chargedProjectiles.getValue().isEmpty()) {
CompoundTag javaProjectileAsNbt = (CompoundTag) chargedProjectiles.getValue().get(0);
List<ItemStack> chargedProjectiles = components.get(DataComponentType.CHARGED_PROJECTILES);
if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) {
ItemStack javaProjectile = chargedProjectiles.get(0);
ItemMapping projectileMapping = session.getItemMappings().getMapping((String) javaProjectileAsNbt.get("id").getValue());
if (projectileMapping == null) return;
@Nullable CompoundTag projectileTag = javaProjectileAsNbt.get("tag");
ItemStack itemStack = new ItemStack(projectileMapping.getJavaItem().javaId(), (byte) javaProjectileAsNbt.get("Count").getValue(), projectileTag);
ItemData itemData = ItemTranslator.translateToBedrock(session, itemStack);
ItemMapping projectileMapping = session.getItemMappings().getMapping(javaProjectile.getId());
ItemData itemData = ItemTranslator.translateToBedrock(session, javaProjectile);
CompoundTag newProjectile = new CompoundTag("chargedItem");
newProjectile.put(new ByteTag("Count", (byte) itemData.getCount()));
newProjectile.put(new StringTag("Name", projectileMapping.getBedrockIdentifier()));
NbtMapBuilder newProjectile = BedrockItemBuilder.createItemNbt(projectileMapping, itemData.getCount(), itemData.getDamage());
newProjectile.put(new ShortTag("Damage", (short) itemData.getDamage()));
tag.put(newProjectile);
}
builder.putCompound("chargedItem", newProjectile.build());
}
}

View File

@ -25,12 +25,11 @@
package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public class DecoratedPotItem extends BlockItem {
@ -39,14 +38,15 @@ public class DecoratedPotItem extends BlockItem {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) {
if (blockEntityTag.remove("sherds") instanceof ListTag sherds) {
// bedrock wants it on the root level
tag.put(sherds);
}
}
components.get(DataComponentType.POT_DECORATIONS); // TODO
// if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) {
// if (blockEntityTag.remove("sherds") instanceof ListTag sherds) {
// // bedrock wants it on the root level
// tag.put(sherds);
// }
// }
}
}

View File

@ -28,11 +28,11 @@ package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.item.ArmorMaterial;
import org.geysermc.geyser.item.DyeableLeatherItem;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem {
public DyeableArmorItem(String javaIdentifier, ArmorMaterial material, Builder builder) {
@ -40,10 +40,10 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
DyeableLeatherItem.translateNbtToBedrock(tag);
DyeableLeatherItem.translateComponentsToBedrock(components, builder);
}
@Override

View File

@ -28,10 +28,10 @@ package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.item.DyeableLeatherItem;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem {
public DyeableHorseArmorItem(String javaIdentifier, Builder builder) {
@ -39,10 +39,10 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
DyeableLeatherItem.translateNbtToBedrock(tag);
DyeableLeatherItem.translateComponentsToBedrock(components, builder);
}
@Override

View File

@ -30,8 +30,8 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import java.util.ArrayList;
import java.util.List;
@ -42,7 +42,7 @@ public class EnchantedBookItem extends Item {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
List<Tag> newTags = new ArrayList<>();

View File

@ -26,8 +26,8 @@
package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.ItemStack;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.registry.type.ItemMapping;
@ -41,16 +41,16 @@ public class FilledMapItem extends MapItem {
@Override
public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) {
ItemData.Builder builder = super.translateToBedrock(itemStack, mapping, mappings);
CompoundTag nbt = itemStack.getNbt();
if (nbt == null) {
DataComponents components = itemStack.getDataComponents();
if (components == null) {
// This is a fallback for maps with no nbt (Change added back in June 2020; is it needed in 2023?)
return builder.tag(NbtMap.builder().putInt("map", 0).build());
} else if (nbt.get("display") instanceof CompoundTag display) {
// Note: damage 5 treasure map, 6 ???
Tag mapColor = display.get("MapColor");
if (mapColor != null && mapColor.getValue() instanceof Number color) {
} else {
Integer mapColor = components.get(DataComponentType.MAP_COLOR);
if (mapColor != null) {
// Note: damage 5 treasure map, 6 ???
// Java Edition allows any color; Bedrock only allows some. So let's take what colors we can get
switch (color.intValue()) {
switch (mapColor) {
case 3830373 -> builder.damage(3); // Ocean Monument
case 5393476 -> builder.damage(4); // Woodland explorer
}

View File

@ -25,44 +25,47 @@
package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponentType;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.mc.protocol.data.game.item.component.Fireworks;
import com.github.steveice10.opennbt.tag.builtin.*;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.level.FireworkColor;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.util.MathUtils;
import java.util.ArrayList;
import java.util.List;
public class FireworkRocketItem extends Item {
public FireworkRocketItem(String javaIdentifier, Builder builder) {
super(javaIdentifier, builder);
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
CompoundTag fireworks = tag.get("Fireworks");
Fireworks fireworks = components.get(DataComponentType.FIREWORKS);
if (fireworks == null) {
return;
}
NbtMapBuilder fireworksNbt = NbtMap.builder();
fireworksNbt.putByte("Flight", (byte) fireworks.getFlightDuration());
if (fireworks.get("Flight") != null) {
fireworks.put(new ByteTag("Flight", MathUtils.getNbtByte(fireworks.get("Flight").getValue())));
}
ListTag explosions = fireworks.get("Explosions");
if (explosions == null) {
List<Fireworks.FireworkExplosion> explosions = fireworks.getExplosions();
if (explosions.isEmpty()) {
return;
}
for (Tag effect : explosions.getValue()) {
CompoundTag effectData = (CompoundTag) effect;
CompoundTag newEffectData = translateExplosionToBedrock(effectData, "");
explosions.remove(effectData);
explosions.add(newEffectData);
List<NbtMap> explosionNbt = new ArrayList<>();
for (Fireworks.FireworkExplosion explosion : explosions) {
explosionNbt.add(translateExplosionToBedrock(explosion, ""));
}
}
@Override
@ -70,13 +73,15 @@ public class FireworkRocketItem extends Item {
super.translateNbtToJava(tag, mapping);
}
static CompoundTag translateExplosionToBedrock(CompoundTag explosion, String newName) {
CompoundTag newExplosionData = new CompoundTag(newName);
static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion, String newName) {
NbtMapBuilder newExplosionData = NbtMap.builder();
if (explosion.get("Type") != null) {
newExplosionData.put(new ByteTag("FireworkType", MathUtils.getNbtByte(explosion.get("Type").getValue())));
}
//newExplosionData.putByte("FireworkType", explosion.get) //TODO???
// TODO do we need length checks
if (explosion.get("Colors") != null) {
int[] oldColors = (int[]) explosion.get("Colors").getValue();
byte[] colors = new byte[oldColors.length];
@ -101,15 +106,10 @@ public class FireworkRocketItem extends Item {
newExplosionData.put(new ByteArrayTag("FireworkFade", colors));
}
if (explosion.get("Trail") != null) {
newExplosionData.put(new ByteTag("FireworkTrail", MathUtils.getNbtByte(explosion.get("Trail").getValue())));
}
newExplosionData.putBoolean("FireworkTrail", explosion.isHasTrail());
newExplosionData.putBoolean("FireworkFlicker", explosion.isHasTwinkle()); // TODO verify
if (explosion.get("Flicker") != null) {
newExplosionData.put(new ByteTag("FireworkFlicker", MathUtils.getNbtByte(explosion.get("Flicker").getValue())));
}
return newExplosionData;
return newExplosionData.build();
}
static CompoundTag translateExplosionToJava(CompoundTag explosion, String newName) {

View File

@ -31,9 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public class FireworkStarItem extends Item {
public FireworkStarItem(String javaIdentifier, Builder builder) {
@ -41,7 +41,7 @@ public class FireworkStarItem extends Item {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
Tag explosion = tag.remove("Explosion");

View File

@ -29,8 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public class FishingRodItem extends Item {
public FishingRodItem(String javaIdentifier, Builder builder) {
@ -38,7 +38,7 @@ public class FishingRodItem extends Item {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
// Fix damage inconsistency

View File

@ -34,10 +34,8 @@ import com.github.steveice10.opennbt.tag.builtin.*;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.nbt.NbtList;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.item.Enchantment;
@ -46,6 +44,7 @@ import org.geysermc.geyser.registry.type.ItemMappings;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.item.ItemTranslator;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.InventoryUtils;
@ -120,29 +119,20 @@ public class Item {
return new ItemStack(javaId, itemData.getCount(), ItemTranslator.translateToJavaNBT("", itemData.getTag()));
}
public ItemMapping toBedrockDefinition(CompoundTag nbt, ItemMappings mappings) {
public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) {
return mappings.getMapping(javaId);
}
/**
* Takes components from Java Edition and map them into Bedrock.
*/
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
// // Basing off of ItemStack#getHoverName as of 1.20.5. VERIFY??
// Component customName = components.get(DataComponentType.CUSTOM_NAME);
// if (customName == null) {
// customName = components.get(DataComponentType.ITEM_NAME);
// }
// if (customName != null) {
//
// }
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
List<Component> loreComponents = components.get(DataComponentType.LORE);
if (loreComponents != null) {
List<String> lore = new ArrayList<>();
List<String> lore = builder.getOrCreateLore();
for (Component loreComponent : loreComponents) {
lore.add(MessageTranslator.convertMessage(loreComponent, session.locale()));
}
builder.putList("Lore", NbtType.STRING, lore);
}
List<Tag> newTags = new ArrayList<>();

View File

@ -28,9 +28,9 @@ package org.geysermc.geyser.item.type;
import com.github.steveice10.mc.protocol.data.game.item.component.DataComponents;
import com.github.steveice10.opennbt.tag.builtin.*;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public class MapItem extends Item {
public MapItem(String javaIdentifier, Builder builder) {
@ -38,7 +38,7 @@ public class MapItem extends Item {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
Tag mapId = tag.remove("map");

View File

@ -30,10 +30,10 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.text.MessageTranslator;
public class PlayerHeadItem extends Item {
@ -42,7 +42,7 @@ public class PlayerHeadItem extends Item {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
CompoundTag displayTag;

View File

@ -31,9 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.item.components.ToolTier;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
public class ShieldItem extends Item {
public ShieldItem(String javaIdentifier, Builder builder) {
@ -41,7 +41,7 @@ public class ShieldItem extends Item {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
if (tag.remove("BlockEntityTag") instanceof CompoundTag blockEntityTag) {

View File

@ -36,6 +36,7 @@ import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.item.ItemTranslator;
import java.util.ArrayList;
@ -47,7 +48,7 @@ public class ShulkerBoxItem extends BlockItem {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
List<ItemStack> contents = components.get(DataComponentType.CONTAINER);
@ -61,15 +62,12 @@ public class ShulkerBoxItem extends BlockItem {
if (item.getId() == Items.AIR_ID) {
continue;
}
NbtMapBuilder boxItemNbt = NbtMap.builder(); // Final item tag to add to the list
boxItemNbt.putByte("Slot", (byte) slot);
boxItemNbt.putByte("WasPickedUp", (byte) 0); // ???
ItemMapping boxMapping = session.getItemMappings().getMapping(item.getId());
boxItemNbt.putString("Name", boxMapping.getBedrockIdentifier());
boxItemNbt.putShort("Damage", (short) boxMapping.getBedrockData());
boxItemNbt.putByte("Count", (byte) item.getAmount());
NbtMapBuilder boxItemNbt = BedrockItemBuilder.createItemNbt(boxMapping, item.getAmount(), boxMapping.getBedrockData()); // Final item tag to add to the list
boxItemNbt.putByte("Slot", (byte) slot);
boxItemNbt.putByte("WasPickedUp", (byte) 0); // ??? TODO might not be needed
// Only the display name is what we have interest in, so just translate that if relevant
DataComponents boxComponents = item.getDataComponents();
if (boxComponents != null) {
@ -85,7 +83,7 @@ public class ShulkerBoxItem extends BlockItem {
itemsList.add(boxItemNbt.build());
}
builder.putList("Items", NbtType.COMPOUND, itemsList);
builder.getOrCreateNbt().putList("Items", NbtType.COMPOUND, itemsList);
}
@Override

View File

@ -32,10 +32,10 @@ import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextDecoration;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.text.MessageTranslator;
import java.util.ArrayList;
@ -49,7 +49,7 @@ public class TropicalFishBucketItem extends Item {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
// Prevent name from appearing as "Bucket of"

View File

@ -31,9 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.text.MessageTranslator;
import java.util.ArrayList;
@ -45,7 +45,7 @@ public class WritableBookItem extends Item {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
super.translateComponentsToBedrock(session, components, builder);
ListTag pagesTag = tag.remove("pages");

View File

@ -33,8 +33,8 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.text.MessageTranslator;
import java.util.List;
@ -50,7 +50,7 @@ public class WrittenBookItem extends WritableBookItem {
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull NbtMapBuilder builder) {
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
boolean isValid = isValidWrittenBook(tag);
if (!isValid) {
tag.remove("pages");

View File

@ -25,6 +25,7 @@
package org.geysermc.geyser.session.cache;
import com.github.steveice10.mc.protocol.data.game.item.component.LodestoneTracker;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
@ -88,7 +89,7 @@ public final class LodestoneCache {
this.activeLodestones.put(itemStack, new LodestonePos(id++, x, y, z, dim));
}
public int store(CompoundTag tag) {
public int store(LodestoneTracker tracker) {
CompoundTag lodestonePos = tag.get("LodestonePos");
if (lodestonePos == null) {
// invalid

View File

@ -30,6 +30,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.registry.type.ItemMapping;
import java.util.ArrayList;
import java.util.List;
@ -70,6 +71,28 @@ public final class BedrockItemBuilder {
return builder;
}
// NBT convenience methods. Returns NbtMapBuilder since that's what's used the most
public NbtMapBuilder putByte(String name, byte value) {
return getOrCreateNbt().putByte(name, value);
}
public NbtMapBuilder putByte(String name, int value) {
return getOrCreateNbt().putByte(name, (byte) value);
}
public NbtMapBuilder putInt(String name, int value) {
return getOrCreateNbt().putInt(name, value);
}
public NbtMapBuilder putString(String name, String value) {
return getOrCreateNbt().putString(name, value);
}
public NbtMapBuilder putCompound(String name, NbtMap value) {
return getOrCreateNbt().putCompound(name, value);
}
/**
* @return null if no NBT is needed on this item.
*/
@ -90,4 +113,16 @@ public final class BedrockItemBuilder {
}
return builder.build();
}
/**
* Creates item NBT with count, name, and damage set.
*/
public static NbtMapBuilder createItemNbt(ItemMapping mapping, int count, int damage) {
NbtMapBuilder builder = NbtMap.builder();
builder.putByte("Count", (byte) count);
builder.putString("Name", mapping.getBedrockIdentifier());
builder.putShort("Damage", (short) damage);
return builder;
}
}

View File

@ -141,7 +141,7 @@ public final class ItemTranslator {
BedrockItemBuilder nbtBuilder = new BedrockItemBuilder();
if (components != null) {
javaItem.translateComponentsToBedrock(session, components, nbtBuilder.getOrCreateNbt());
javaItem.translateComponentsToBedrock(session, components, nbtBuilder);
}
String customName = getCustomName(session, components, bedrockItem);