3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-11-19 14:30:17 +01:00

Switch to Cloudburst NBT only

Dieser Commit ist enthalten in:
Camotoy 2024-04-26 21:44:59 -04:00
Ursprung 16cb76f523
Commit 2fa7585db3
58 geänderte Dateien mit 586 neuen und 927 gelöschten Zeilen

Datei anzeigen

@ -45,7 +45,6 @@ import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
import org.geysermc.api.Geyser; import org.geysermc.api.Geyser;
import org.geysermc.cumulus.form.Form; import org.geysermc.cumulus.form.Form;
import org.geysermc.cumulus.form.util.FormBuilder; import org.geysermc.cumulus.form.util.FormBuilder;
import org.geysermc.erosion.packet.Packets;
import org.geysermc.floodgate.crypto.AesCipher; import org.geysermc.floodgate.crypto.AesCipher;
import org.geysermc.floodgate.crypto.AesKeyProducer; import org.geysermc.floodgate.crypto.AesKeyProducer;
import org.geysermc.floodgate.crypto.Base64Topping; import org.geysermc.floodgate.crypto.Base64Topping;
@ -384,7 +383,7 @@ public class GeyserImpl implements GeyserApi {
this.newsHandler = new NewsHandler(BRANCH, this.buildNumber()); this.newsHandler = new NewsHandler(BRANCH, this.buildNumber());
Packets.initGeyser(); //Packets.initGeyser();
if (Epoll.isAvailable()) { if (Epoll.isAvailable()) {
this.erosionUnixListener = new UnixSocketClientListener(); this.erosionUnixListener = new UnixSocketClientListener();

Datei anzeigen

@ -25,8 +25,6 @@
package org.geysermc.geyser.entity.type; package org.geysermc.geyser.entity.type;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -57,6 +55,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEn
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import java.util.*; import java.util.*;
@ -194,9 +193,9 @@ public class LivingEntity extends Entity {
/** /**
* Checks to see if a nametag interaction would go through. * Checks to see if a nametag interaction would go through.
*/ */
// Implementation note for 1.20.5: this code was moved to the NameTag item.
protected final InteractionResult checkInteractWithNameTag(GeyserItemStack itemStack) { protected final InteractionResult checkInteractWithNameTag(GeyserItemStack itemStack) {
CompoundTag nbt = itemStack.getNbt(); if (itemStack.getComponent(DataComponentType.CUSTOM_NAME) != null) {
if (nbt != null && nbt.get("display") instanceof CompoundTag displayTag && displayTag.get("Name") instanceof StringTag) {
// The mob shall be named // The mob shall be named
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }

Datei anzeigen

@ -25,14 +25,14 @@
package org.geysermc.geyser.entity.type.player; package org.geysermc.geyser.entity.type.player;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.protocol.bedrock.data.Ability; import org.cloudburstmc.protocol.bedrock.data.Ability;
import org.cloudburstmc.protocol.bedrock.data.AbilityLayer; import org.cloudburstmc.protocol.bedrock.data.AbilityLayer;
import org.cloudburstmc.protocol.bedrock.data.GameType; import org.cloudburstmc.protocol.bedrock.data.GameType;
@ -298,11 +298,11 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
dirtyMetadata.put(EntityDataTypes.MARK_VARIANT, ~entityMetadata.getPrimitiveValue() & 0xff); dirtyMetadata.put(EntityDataTypes.MARK_VARIANT, ~entityMetadata.getPrimitiveValue() & 0xff);
} }
public void setLeftParrot(EntityMetadata<CompoundTag, ?> entityMetadata) { public void setLeftParrot(EntityMetadata<NbtMap, ?> entityMetadata) {
setParrot(entityMetadata.getValue(), true); setParrot(entityMetadata.getValue(), true);
} }
public void setRightParrot(EntityMetadata<CompoundTag, ?> entityMetadata) { public void setRightParrot(EntityMetadata<NbtMap, ?> entityMetadata) {
setParrot(entityMetadata.getValue(), false); setParrot(entityMetadata.getValue(), false);
} }
@ -310,7 +310,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
* Sets the parrot occupying the shoulder. Bedrock Edition requires a full entity whereas Java Edition just * Sets the parrot occupying the shoulder. Bedrock Edition requires a full entity whereas Java Edition just
* spawns it from the NBT data provided * spawns it from the NBT data provided
*/ */
protected void setParrot(CompoundTag tag, boolean isLeft) { protected void setParrot(NbtMap tag, boolean isLeft) {
if (tag != null && !tag.isEmpty()) { if (tag != null && !tag.isEmpty()) {
if ((isLeft && leftParrot != null) || (!isLeft && rightParrot != null)) { if ((isLeft && leftParrot != null) || (!isLeft && rightParrot != null)) {
// No need to update a parrot's data when it already exists // No need to update a parrot's data when it already exists
@ -320,7 +320,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
ParrotEntity parrot = new ParrotEntity(session, 0, session.getEntityCache().getNextEntityId().incrementAndGet(), ParrotEntity parrot = new ParrotEntity(session, 0, session.getEntityCache().getNextEntityId().incrementAndGet(),
null, EntityDefinitions.PARROT, position, motion, getYaw(), getPitch(), getHeadYaw()); null, EntityDefinitions.PARROT, position, motion, getYaw(), getPitch(), getHeadYaw());
parrot.spawnEntity(); parrot.spawnEntity();
parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, (Integer) tag.get("Variant").getValue()); parrot.getDirtyMetadata().put(EntityDataTypes.VARIANT, (Integer) tag.get("Variant"));
// Different position whether the parrot is left or right // Different position whether the parrot is left or right
float offset = isLeft ? 0.4f : -0.4f; float offset = isLeft ? 0.4f : -0.4f;
parrot.getDirtyMetadata().put(EntityDataTypes.SEAT_OFFSET, Vector3f.from(offset, -0.22, -0.1)); parrot.getDirtyMetadata().put(EntityDataTypes.SEAT_OFFSET, Vector3f.from(offset, -0.22, -0.1));
@ -437,11 +437,11 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
} else if (numberFormat instanceof FixedFormat fixedFormat) { } else if (numberFormat instanceof FixedFormat fixedFormat) {
numberString = MessageTranslator.convertMessage(fixedFormat.getValue()); numberString = MessageTranslator.convertMessage(fixedFormat.getValue());
} else if (numberFormat instanceof StyledFormat styledFormat) { } else if (numberFormat instanceof StyledFormat styledFormat) {
CompoundTag styledAmount = styledFormat.getStyle().clone(); NbtMapBuilder styledAmount = styledFormat.getStyle().toBuilder();
styledAmount.put(new StringTag("text", String.valueOf(amount))); styledAmount.putString("text", String.valueOf(amount));
numberString = MessageTranslator.convertJsonMessage( numberString = MessageTranslator.convertJsonMessage(
NbtComponentSerializer.tagComponentToJson(styledAmount).toString()); NbtComponentSerializer.tagComponentToJson(styledAmount.build()).toString(), session.locale());
} else { } else {
numberString = String.valueOf(amount); numberString = String.valueOf(amount);
} }

Datei anzeigen

@ -25,11 +25,7 @@
package org.geysermc.geyser.inventory; package org.geysermc.geyser.inventory;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import lombok.*;
import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
@ -43,6 +39,8 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import java.util.HashMap;
@Data @Data
public class GeyserItemStack { public class GeyserItemStack {
public static final GeyserItemStack EMPTY = new GeyserItemStack(Items.AIR_ID, 0, null); public static final GeyserItemStack EMPTY = new GeyserItemStack(Items.AIR_ID, 0, null);
@ -52,7 +50,7 @@ public class GeyserItemStack {
private DataComponents components; private DataComponents components;
private int netId; private int netId;
@Getter(AccessLevel.NONE) @Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE)
@EqualsAndHashCode.Exclude @EqualsAndHashCode.Exclude
private Item item; private Item item;
@ -67,6 +65,14 @@ public class GeyserItemStack {
this.netId = netId; this.netId = netId;
} }
public static @NonNull GeyserItemStack of(int javaId, int amount) {
return of(javaId, amount, null);
}
public static @NonNull GeyserItemStack of(int javaId, int amount, DataComponents components) {
return new GeyserItemStack(javaId, amount, components);
}
public static @NonNull GeyserItemStack from(@Nullable ItemStack itemStack) { public static @NonNull GeyserItemStack from(@Nullable ItemStack itemStack) {
return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponents()); return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponents());
} }
@ -79,16 +85,27 @@ public class GeyserItemStack {
return isEmpty() ? 0 : amount; return isEmpty() ? 0 : amount;
} }
public @Nullable CompoundTag getNbt() {
Thread.dumpStack();
return null;
}
public @Nullable DataComponents getComponents() { public @Nullable DataComponents getComponents() {
return isEmpty() ? null : components; return isEmpty() ? null : components;
} }
public <T extends Boolean> boolean getComponent(DataComponentType<T> type, boolean def) { @NonNull
public DataComponents getOrCreateComponents() {
if (components == null) {
return components = new DataComponents(new HashMap<>());
}
return components;
}
@Nullable
public <T> T getComponent(@NonNull DataComponentType<T> type) {
if (components == null) {
return null;
}
return components.get(type);
}
public <T extends Boolean> boolean getComponent(@NonNull DataComponentType<T> type, boolean def) {
if (components == null) { if (components == null) {
return def; return def;
} }
@ -100,7 +117,7 @@ public class GeyserItemStack {
return def; return def;
} }
public <T extends Integer> int getComponent(DataComponentType<T> type, int def) { public <T extends Integer> int getComponent(@NonNull DataComponentType<T> type, int def) {
if (components == null) { if (components == null) {
return def; return def;
} }

Datei anzeigen

@ -25,9 +25,6 @@
package org.geysermc.geyser.inventory; package org.geysermc.geyser.inventory;
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
@ -39,6 +36,7 @@ import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.item.ItemTranslator;
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType; import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.jetbrains.annotations.Range; import org.jetbrains.annotations.Range;
import java.util.Arrays; import java.util.Arrays;
@ -137,12 +135,9 @@ public abstract class Inventory {
// Lodestone caching // Lodestone caching
if (newItem.asItem() == Items.COMPASS) { if (newItem.asItem() == Items.COMPASS) {
CompoundTag nbt = newItem.getNbt(); var tracker = newItem.getComponent(DataComponentType.LODESTONE_TRACKER);
if (nbt != null) { if (tracker != null) {
Tag lodestoneTag = nbt.get("LodestoneTracked"); session.getLodestoneCache().cacheInventoryItem(newItem, tracker);
if (lodestoneTag instanceof ByteTag) {
session.getLodestoneCache().cacheInventoryItem(newItem);
}
} }
} }
} }

Datei anzeigen

@ -25,8 +25,10 @@
package org.geysermc.geyser.inventory.item; package org.geysermc.geyser.inventory.item;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import lombok.Getter; import lombok.Getter;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
import java.util.Locale; import java.util.Locale;
@ -85,6 +87,10 @@ public enum Potion {
this.bedrockId = (short) bedrockId; this.bedrockId = (short) bedrockId;
} }
public PotionContents toComponent() {
return new PotionContents(this.ordinal(), -1, Int2ObjectMaps.emptyMap());
}
public static @Nullable Potion getByJavaIdentifier(String javaIdentifier) { public static @Nullable Potion getByJavaIdentifier(String javaIdentifier) {
for (Potion potion : VALUES) { for (Potion potion : VALUES) {
if (potion.javaIdentifier.equals(javaIdentifier)) { if (potion.javaIdentifier.equals(javaIdentifier)) {

Datei anzeigen

@ -25,9 +25,6 @@
package org.geysermc.geyser.inventory.recipe; package org.geysermc.geyser.inventory.recipe;
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextColor;
import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial;
@ -37,6 +34,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemTagDescri
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
/** /**
* Stores information on trim materials and patterns, including smithing armor hacks for pre-1.20. * Stores information on trim materials and patterns, including smithing armor hacks for pre-1.20.
@ -54,11 +52,11 @@ public final class TrimRecipe {
// Color is used when hovering over the item // Color is used when hovering over the item
// Find the nearest legacy color from the RGB Java gives us to work with // Find the nearest legacy color from the RGB Java gives us to work with
// Also yes this is a COMPLETE hack but it works ok!!!!! // Also yes this is a COMPLETE hack but it works ok!!!!!
StringTag colorTag = ((CompoundTag) entry.getData().get("description")).get("color"); String colorTag = entry.getData().getCompound("description").getString("color");
TextColor color = TextColor.fromHexString(colorTag.getValue()); TextColor color = TextColor.fromHexString(colorTag);
String legacy = MessageTranslator.convertMessage(Component.space().color(color)); String legacy = MessageTranslator.convertMessage(Component.space().color(color));
String itemIdentifier = ((StringTag) entry.getData().get("ingredient")).getValue(); String itemIdentifier = entry.getData().getString("ingredient");
ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier);
if (itemMapping == null) { if (itemMapping == null) {
// This should never happen so not sure what to do here. // This should never happen so not sure what to do here.
@ -71,7 +69,7 @@ public final class TrimRecipe {
public static TrimPattern readTrimPattern(GeyserSession session, RegistryEntry entry) { public static TrimPattern readTrimPattern(GeyserSession session, RegistryEntry entry) {
String key = stripNamespace(entry.getId()); String key = stripNamespace(entry.getId());
String itemIdentifier = ((StringTag) entry.getData().get("template_item")).getValue(); String itemIdentifier = entry.getData().getString("template_item");
ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier); ItemMapping itemMapping = session.getItemMappings().getMapping(itemIdentifier);
if (itemMapping == null) { if (itemMapping == null) {
// This should never happen so not sure what to do here. // This should never happen so not sure what to do here.

Datei anzeigen

@ -25,13 +25,6 @@
package org.geysermc.geyser.inventory.updater; package org.geysermc.geyser.inventory.updater;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket;
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 com.github.steveice10.opennbt.tag.builtin.Tag;
import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMaps; import it.unimi.dsi.fastutil.objects.Object2IntMaps;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
@ -53,7 +46,12 @@ import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.ItemUtils; import org.geysermc.geyser.util.ItemUtils;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundRenameItemPacket;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
public class AnvilInventoryUpdater extends InventoryUpdater { public class AnvilInventoryUpdater extends InventoryUpdater {
@ -310,9 +308,9 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
*/ */
private int calcMergeEnchantmentCost(GeyserSession session, GeyserItemStack input, GeyserItemStack material, boolean bedrock) { private int calcMergeEnchantmentCost(GeyserSession session, GeyserItemStack input, GeyserItemStack material, boolean bedrock) {
boolean hasCompatible = false; boolean hasCompatible = false;
Object2IntMap<JavaEnchantment> combinedEnchantments = getEnchantments(input, bedrock); Object2IntMap<JavaEnchantment> combinedEnchantments = getEnchantments(input);
int cost = 0; int cost = 0;
for (Object2IntMap.Entry<JavaEnchantment> entry : getEnchantments(material, bedrock).object2IntEntrySet()) { for (Object2IntMap.Entry<JavaEnchantment> entry : getEnchantments(material).object2IntEntrySet()) {
JavaEnchantment enchantment = entry.getKey(); JavaEnchantment enchantment = entry.getKey();
EnchantmentData data = Registries.ENCHANTMENTS.get(enchantment); EnchantmentData data = Registries.ENCHANTMENTS.get(enchantment);
if (data == null) { if (data == null) {
@ -371,42 +369,26 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
return cost; return cost;
} }
private Object2IntMap<JavaEnchantment> getEnchantments(GeyserItemStack itemStack, boolean bedrock) { private Object2IntMap<JavaEnchantment> getEnchantments(GeyserItemStack itemStack) {
if (itemStack.getNbt() == null) { ItemEnchantments enchantmentComponent;
return Object2IntMaps.emptyMap();
}
Object2IntMap<JavaEnchantment> enchantments = new Object2IntOpenHashMap<>();
Tag enchantmentTag;
if (isEnchantedBook(itemStack)) { if (isEnchantedBook(itemStack)) {
enchantmentTag = itemStack.getNbt().get("StoredEnchantments"); enchantmentComponent = itemStack.getComponent(DataComponentType.STORED_ENCHANTMENTS);
} else { } else {
enchantmentTag = itemStack.getNbt().get("Enchantments"); enchantmentComponent = itemStack.getComponent(DataComponentType.ENCHANTMENTS);
} }
if (enchantmentTag instanceof ListTag listTag) { if (enchantmentComponent != null) {
for (Tag tag : listTag.getValue()) { Object2IntMap<JavaEnchantment> enchantments = new Object2IntOpenHashMap<>();
if (tag instanceof CompoundTag enchantTag) { for (Map.Entry<Integer, Integer> entry : enchantmentComponent.getEnchantments().entrySet()) {
if (enchantTag.get("id") instanceof StringTag javaEnchId) { JavaEnchantment enchantment = JavaEnchantment.of(entry.getKey());
JavaEnchantment enchantment = JavaEnchantment.getByJavaIdentifier(javaEnchId.getValue()); if (enchantment == null) {
if (enchantment == null) { GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + entry.getKey());
GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + javaEnchId.getValue()); continue;
continue;
}
Tag javaEnchLvl = enchantTag.get("lvl");
if (javaEnchLvl == null || !(javaEnchLvl.getValue() instanceof Number number))
continue;
// Handle duplicate enchantments
if (bedrock) {
enchantments.putIfAbsent(enchantment, number.intValue());
} else {
enchantments.mergeInt(enchantment, number.intValue(), Math::max);
}
}
} }
enchantments.put(enchantment, entry.getValue().intValue());
} }
return enchantments;
} }
return enchantments; return Object2IntMaps.emptyMap();
} }
private boolean isEnchantedBook(GeyserItemStack itemStack) { private boolean isEnchantedBook(GeyserItemStack itemStack) {

Datei anzeigen

@ -25,8 +25,6 @@
package org.geysermc.geyser.item; package org.geysermc.geyser.item;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
@ -41,17 +39,4 @@ public interface DyeableLeatherItem {
} }
builder.putInt("customColor", dyedItemColor.getRgb()); builder.putInt("customColor", dyedItemColor.getRgb());
} }
static void translateNbtToJava(CompoundTag tag) {
IntTag color = tag.get("customColor");
if (color == null) {
return;
}
CompoundTag displayTag = tag.get("display");
if (displayTag == null) {
displayTag = new CompoundTag("display");
}
displayTag.put(color);
tag.remove("customColor");
}
} }

Datei anzeigen

@ -25,15 +25,12 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
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.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.protocol.bedrock.data.TrimMaterial; import org.cloudburstmc.protocol.bedrock.data.TrimMaterial;
import org.cloudburstmc.protocol.bedrock.data.TrimPattern; import org.cloudburstmc.protocol.bedrock.data.TrimPattern;
import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.item.ArmorMaterial;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ArmorTrim; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ArmorTrim;
@ -70,19 +67,6 @@ public class ArmorItem extends Item {
} }
} }
@Override
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
super.translateNbtToJava(tag, mapping);
if (tag.get("Trim") instanceof CompoundTag trim) {
StringTag material = trim.remove("Material");
StringTag pattern = trim.remove("Pattern");
// java has a lowercase key, and namespaced value
trim.put(new StringTag("material", "minecraft:" + material.getValue()));
trim.put(new StringTag("pattern", "minecraft:" + pattern.getValue()));
}
}
@Override @Override
public boolean isValidRepairItem(Item other) { public boolean isValidRepairItem(Item other) {
return material.getRepairIngredient() == other; return material.getRepairIngredient() == other;

Datei anzeigen

@ -25,14 +25,16 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.StringTag; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.item.TippedArrowPotion; import org.geysermc.geyser.inventory.item.TippedArrowPotion;
import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.registry.type.ItemMappings;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
public class ArrowItem extends Item { public class ArrowItem extends Item {
public ArrowItem(String javaIdentifier, Builder builder) { public ArrowItem(String javaIdentifier, Builder builder) {
@ -40,13 +42,13 @@ public class ArrowItem extends Item {
} }
@Override @Override
public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByBedrockId(itemData.getDamage()); TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByBedrockId(itemData.getDamage());
ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings);
if (tippedArrowPotion != null) { if (tippedArrowPotion != null) {
itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponents()); itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getComponents());
StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier()); PotionContents contents = new PotionContents(tippedArrowPotion.ordinal(), -1, Int2ObjectMaps.emptyMap());
//itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents()); itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, contents);
} }
return itemStack; return itemStack;
} }

Datei anzeigen

@ -25,7 +25,6 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.*;
import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.Pair;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtList;
@ -52,7 +51,7 @@ public class BannerItem extends BlockItem {
* the correct ominous banner pattern if Bedrock pulls the item from creative. * the correct ominous banner pattern if Bedrock pulls the item from creative.
*/ */
private static final List<Pair<BannerPattern, DyeColor>> OMINOUS_BANNER_PATTERN; private static final List<Pair<BannerPattern, DyeColor>> OMINOUS_BANNER_PATTERN;
private static final ListTag OMINOUS_BANNER_PATTERN_BLOCK; private static final List<NbtMap> OMINOUS_BANNER_PATTERN_BLOCK;
static { static {
// Construct what an ominous banner is supposed to look like // Construct what an ominous banner is supposed to look like
@ -67,7 +66,7 @@ public class BannerItem extends BlockItem {
Pair.of(BannerPattern.BORDER, DyeColor.BLACK) Pair.of(BannerPattern.BORDER, DyeColor.BLACK)
); );
OMINOUS_BANNER_PATTERN_BLOCK = new ListTag("patterns"); OMINOUS_BANNER_PATTERN_BLOCK = new ArrayList<>();
for (Pair<BannerPattern, DyeColor> pair : OMINOUS_BANNER_PATTERN) { for (Pair<BannerPattern, DyeColor> pair : OMINOUS_BANNER_PATTERN) {
OMINOUS_BANNER_PATTERN_BLOCK.add(getJavaBannerPatternTag(pair.left(), pair.right())); OMINOUS_BANNER_PATTERN_BLOCK.add(getJavaBannerPatternTag(pair.left(), pair.right()));
} }
@ -92,7 +91,7 @@ public class BannerItem extends BlockItem {
return true; return true;
} }
public static boolean isOminous(ListTag blockEntityPatterns) { public static boolean isOminous(List<NbtMap> blockEntityPatterns) {
return OMINOUS_BANNER_PATTERN_BLOCK.equals(blockEntityPatterns); return OMINOUS_BANNER_PATTERN_BLOCK.equals(blockEntityPatterns);
} }
@ -102,10 +101,10 @@ public class BannerItem extends BlockItem {
* @param patterns The patterns to convert * @param patterns The patterns to convert
* @return The new converted patterns * @return The new converted patterns
*/ */
public static NbtList<NbtMap> convertBannerPattern(ListTag patterns) { public static NbtList<NbtMap> convertBannerPattern(List<NbtMap> patterns) {
List<NbtMap> tagsList = new ArrayList<>(); List<NbtMap> tagsList = new ArrayList<>();
for (Tag patternTag : patterns.getValue()) { for (NbtMap patternTag : patterns) {
NbtMap bedrockBannerPattern = getBedrockBannerPattern((CompoundTag) patternTag); NbtMap bedrockBannerPattern = getBedrockBannerPattern(patternTag);
if (bedrockBannerPattern != null) { if (bedrockBannerPattern != null) {
tagsList.add(bedrockBannerPattern); tagsList.add(bedrockBannerPattern);
} }
@ -120,9 +119,9 @@ public class BannerItem extends BlockItem {
* @param pattern Java edition pattern nbt * @param pattern Java edition pattern nbt
* @return The Bedrock edition format pattern nbt * @return The Bedrock edition format pattern nbt
*/ */
private static NbtMap getBedrockBannerPattern(CompoundTag pattern) { private static NbtMap getBedrockBannerPattern(NbtMap pattern) {
BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier((String) pattern.get("pattern").getValue()); BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(pattern.getString("pattern"));
DyeColor dyeColor = DyeColor.getByJavaIdentifier((String) pattern.get("color").getValue()); DyeColor dyeColor = DyeColor.getByJavaIdentifier(pattern.getString("color"));
if (bannerPattern == null || dyeColor == null) { if (bannerPattern == null || dyeColor == null) {
return null; return null;
} }
@ -133,11 +132,11 @@ public class BannerItem extends BlockItem {
.build(); .build();
} }
public static CompoundTag getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) { public static NbtMap getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) {
CompoundTag tag = new CompoundTag(""); return NbtMap.builder()
tag.put(new StringTag("pattern", bannerPattern.getJavaIdentifier())); .putString("pattern", bannerPattern.getJavaIdentifier())
tag.put(new StringTag("color", dyeColor.getJavaIdentifier())); .putString("color", dyeColor.getJavaIdentifier())
return tag; .build();
} }
/** /**
@ -190,31 +189,14 @@ public class BannerItem extends BlockItem {
} }
@Override @Override
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { // TODO public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { // TODO
super.translateNbtToJava(tag, mapping); super.translateNbtToJava(bedrockTag, components, mapping);
if (tag.get("Type") instanceof IntTag type && type.getValue() == 1) { if (bedrockTag.getInt("Type") == 1) {
// Ominous banner pattern // Ominous banner pattern
tag.remove("Type"); // TODO more registry stuff
CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); //components.put(DataComponentType.BANNER_PATTERNS);
blockEntityTag.put(OMINOUS_BANNER_PATTERN_BLOCK);
tag.put(blockEntityTag);
} else if (tag.get("Patterns") instanceof ListTag patterns && patterns.getElementType() == CompoundTag.class) {
CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag");
ListTag javaPatterns = new ListTag("patterns");
for (Tag pattern : patterns.getValue()) {
BannerPattern bannerPattern = BannerPattern.getByBedrockIdentifier((String) ((CompoundTag) pattern).get("Pattern").getValue());
DyeColor dyeColor = DyeColor.getById((int) ((CompoundTag) pattern).get("Color").getValue());
if (bannerPattern != null && dyeColor != null) {
javaPatterns.add(getJavaBannerPatternTag(bannerPattern, dyeColor));
}
}
blockEntityTag.put(javaPatterns);
tag.put(blockEntityTag);
tag.remove("Patterns"); // Remove the old Bedrock patterns list
} }
// Bedrock's creative inventory does not support other patterns as of 1.20.5
} }
} }

Datei anzeigen

@ -28,11 +28,11 @@ package org.geysermc.geyser.item.type;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.registry.type.ItemMappings;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker; import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker;
@ -78,7 +78,7 @@ public class CompassItem extends Item {
} }
@Override @Override
public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
if (mapping.getBedrockIdentifier().equals("minecraft:lodestone_compass")) { if (mapping.getBedrockIdentifier().equals("minecraft:lodestone_compass")) {
// Revert the entry back to the compass // Revert the entry back to the compass
mapping = mappings.getStoredItems().compass(); mapping = mappings.getStoredItems().compass();

Datei anzeigen

@ -25,10 +25,6 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
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.NonNull;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
@ -63,22 +59,4 @@ public class CrossbowItem extends Item {
builder.putCompound("chargedItem", newProjectile.build()); builder.putCompound("chargedItem", newProjectile.build());
} }
} }
@Override
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
super.translateNbtToJava(tag, mapping);
if (tag.get("chargedItem") != null) {
CompoundTag chargedItem = tag.get("chargedItem");
CompoundTag newProjectile = new CompoundTag("");
newProjectile.put(new ByteTag("Count", (byte) chargedItem.get("Count").getValue()));
newProjectile.put(new StringTag("id", (String) chargedItem.get("Name").getValue()));
ListTag chargedProjectiles = new ListTag("ChargedProjectiles");
chargedProjectiles.add(newProjectile);
tag.put(chargedProjectiles);
}
}
} }

Datei anzeigen

@ -25,11 +25,9 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.item.ArmorMaterial; import org.geysermc.geyser.item.ArmorMaterial;
import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.item.DyeableLeatherItem;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
@ -45,11 +43,4 @@ public class DyeableArmorItem extends ArmorItem implements DyeableLeatherItem {
DyeableLeatherItem.translateComponentsToBedrock(components, builder); DyeableLeatherItem.translateComponentsToBedrock(components, builder);
} }
@Override
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
super.translateNbtToJava(tag, mapping);
DyeableLeatherItem.translateNbtToJava(tag);
}
} }

Datei anzeigen

@ -25,10 +25,8 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.item.DyeableLeatherItem; import org.geysermc.geyser.item.DyeableLeatherItem;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
@ -44,11 +42,4 @@ public class DyeableHorseArmorItem extends Item implements DyeableLeatherItem {
DyeableLeatherItem.translateComponentsToBedrock(components, builder); DyeableLeatherItem.translateComponentsToBedrock(components, builder);
} }
@Override
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
super.translateNbtToJava(tag, mapping);
DyeableLeatherItem.translateNbtToJava(tag);
}
} }

Datei anzeigen

@ -25,9 +25,14 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.item.Enchantment;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
@ -62,4 +67,29 @@ public class EnchantedBookItem extends Item {
builder.putList("ench", NbtType.COMPOUND, bedrockEnchants); builder.putList("ench", NbtType.COMPOUND, bedrockEnchants);
} }
} }
@Override
public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) {
super.translateNbtToJava(bedrockTag, components, mapping);
List<NbtMap> enchantmentTag = bedrockTag.getList("ench", NbtType.COMPOUND);
if (enchantmentTag != null) {
Int2IntMap javaEnchantments = new Int2IntOpenHashMap(enchantmentTag.size());
for (NbtMap bedrockEnchantment : enchantmentTag) {
short bedrockId = bedrockEnchantment.getShort("id");
Enchantment enchantment = Enchantment.getByBedrockId(bedrockId);
if (enchantment != null) {
int level = bedrockEnchantment.getShort("lvl", (short) 1);
// TODO
javaEnchantments.put(Enchantment.JavaEnchantment.valueOf(enchantment.name()).ordinal(), level);
} else {
GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId);
}
}
if (!javaEnchantments.isEmpty()) {
components.put(DataComponentType.STORED_ENCHANTMENTS, new ItemEnchantments(javaEnchantments, true));
}
}
}
} }

Datei anzeigen

@ -25,9 +25,7 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.ByteTag; import it.unimi.dsi.fastutil.ints.IntArrays;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
@ -36,7 +34,6 @@ import org.geysermc.geyser.level.FireworkColor;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.util.MathUtils;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Fireworks; import org.geysermc.mcprotocollib.protocol.data.game.item.component.Fireworks;
@ -73,8 +70,23 @@ public class FireworkRocketItem extends Item {
} }
@Override @Override
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) {
super.translateNbtToJava(tag, mapping); super.translateNbtToJava(bedrockTag, components, mapping);
NbtMap fireworksTag = bedrockTag.getCompound("Fireworks");
if (!fireworksTag.isEmpty()) {
List<NbtMap> explosions = fireworksTag.getList("Explosions", NbtType.COMPOUND);
if (!explosions.isEmpty()) {
List<Fireworks.FireworkExplosion> javaExplosions = new ArrayList<>();
for (NbtMap explosion : explosions) {
Fireworks.FireworkExplosion javaExplosion = translateExplosionToJava(explosion);
if (javaExplosion != null) {
javaExplosions.add(javaExplosion);
}
}
components.put(DataComponentType.FIREWORKS, new Fireworks(1, javaExplosions));
}
}
} }
static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion) { static NbtMap translateExplosionToBedrock(Fireworks.FireworkExplosion explosion) {
@ -111,45 +123,22 @@ public class FireworkRocketItem extends Item {
return newExplosionData.build(); return newExplosionData.build();
} }
static CompoundTag translateExplosionToJava(CompoundTag explosion, String newName) { /**
CompoundTag newExplosionData = new CompoundTag(newName); * The only thing that the Bedrock creative inventory has - as of 1.20.80 - is color.
*/
if (explosion.get("FireworkType") != null) { static Fireworks.FireworkExplosion translateExplosionToJava(NbtMap explosion) {
newExplosionData.put(new ByteTag("Type", MathUtils.getNbtByte(explosion.get("FireworkType").getValue()))); byte[] javaColors = explosion.getByteArray("FireworkColor", null);
} if (javaColors != null) {
int[] colors = new int[javaColors.length];
if (explosion.get("FireworkColor") != null) {
byte[] oldColors = (byte[]) explosion.get("FireworkColor").getValue();
int[] colors = new int[oldColors.length];
int i = 0; int i = 0;
for (byte color : oldColors) { for (byte color : javaColors) {
colors[i++] = FireworkColor.fromBedrockId(color); colors[i++] = FireworkColor.fromBedrockId(color);
} }
newExplosionData.put(new IntArrayTag("Colors", colors)); return new Fireworks.FireworkExplosion(0, colors, IntArrays.EMPTY_ARRAY, false, false);
} else {
return null;
} }
if (explosion.get("FireworkFade") != null) {
byte[] oldColors = (byte[]) explosion.get("FireworkFade").getValue();
int[] colors = new int[oldColors.length];
int i = 0;
for (byte color : oldColors) {
colors[i++] = FireworkColor.fromBedrockId(color);
}
newExplosionData.put(new IntArrayTag("FadeColors", colors));
}
if (explosion.get("FireworkTrail") != null) {
newExplosionData.put(new ByteTag("Trail", MathUtils.getNbtByte(explosion.get("FireworkTrail").getValue())));
}
if (explosion.get("FireworkFlicker") != null) {
newExplosionData.put(new ByteTag("Flicker", MathUtils.getNbtByte(explosion.get("FireworkFlicker").getValue())));
}
return newExplosionData;
} }
} }

Datei anzeigen

@ -25,8 +25,6 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
@ -80,15 +78,16 @@ public class FireworkStarItem extends Item {
} }
@Override @Override
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) {
super.translateNbtToJava(tag, mapping); super.translateNbtToJava(bedrockTag, components, mapping);
Tag explosion = tag.remove("FireworksItem"); NbtMap explosion = bedrockTag.getCompound("FireworksItem");
if (explosion instanceof CompoundTag) { if (!explosion.isEmpty()) {
CompoundTag newExplosion = FireworkRocketItem.translateExplosionToJava((CompoundTag) explosion, "Explosion"); Fireworks.FireworkExplosion newExplosion = FireworkRocketItem.translateExplosionToJava(explosion);
tag.put(newExplosion); if (newExplosion == null) {
return;
}
components.put(DataComponentType.FIREWORK_EXPLOSION, newExplosion);
} }
// Remove custom color, if any, since this only exists on Bedrock
tag.remove("customColor");
} }
} }

Datei anzeigen

@ -25,14 +25,12 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.registry.type.ItemMappings;
import org.geysermc.mcprotocollib.protocol.data.game.Holder; import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Instrument; import org.geysermc.mcprotocollib.protocol.data.game.item.component.Instrument;
@ -80,18 +78,11 @@ public class GoatHornItem extends Item {
} }
@Override @Override
public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings);
int damage = itemData.getDamage(); int damage = itemData.getDamage();
if (damage < 0 || damage >= INSTRUMENTS.size()) { itemStack.getOrCreateComponents().put(DataComponentType.INSTRUMENT, Holder.ofId(damage));
GeyserImpl.getInstance().getLogger().debug("Unknown goat horn instrument for damage: " + damage);
damage = 0;
}
String instrument = INSTRUMENTS.get(damage);
StringTag instrumentTag = new StringTag("instrument", "minecraft:" + instrument);
//itemStack.getNbt().put(instrumentTag);
return itemStack; return itemStack;
} }

Datei anzeigen

@ -25,7 +25,6 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.*;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -33,6 +32,7 @@ import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.nbt.NbtType;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.item.Enchantment; import org.geysermc.geyser.inventory.item.Enchantment;
import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
@ -44,7 +44,6 @@ import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.item.ItemTranslator; import org.geysermc.geyser.translator.item.ItemTranslator;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.mcprotocollib.protocol.data.game.Identifier; import org.geysermc.mcprotocollib.protocol.data.game.Identifier;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments; import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
@ -108,11 +107,8 @@ public class Item {
return builder; return builder;
} }
public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
if (itemData.getTag() == null) { return GeyserItemStack.of(javaId, itemData.getCount());
return new ItemStack(javaId, itemData.getCount(), null);
}
return new ItemStack(javaId, itemData.getCount(), null/*ItemTranslator.translateToJavaNBT("", itemData.getTag())*/);
} }
public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) { public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) {
@ -162,57 +158,60 @@ public class Item {
* </ul> * </ul>
* Therefore, if translation cannot be achieved for a certain item, it is not necessarily bad. * Therefore, if translation cannot be achieved for a certain item, it is not necessarily bad.
*/ */
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) {
CompoundTag displayTag = tag.get("display"); // TODO see if any items from the creative menu need this
if (displayTag != null) { // CompoundTag displayTag = tag.get("display");
if (displayTag.contains("Name")) { // if (displayTag != null) {
StringTag nameTag = displayTag.get("Name"); // if (displayTag.contains("Name")) {
displayTag.put(new StringTag("Name", MessageTranslator.convertToJavaMessage(nameTag.getValue()))); // StringTag nameTag = displayTag.get("Name");
} // displayTag.put(new StringTag("Name", MessageTranslator.convertToJavaMessage(nameTag.getValue())));
// }
//
// if (displayTag.contains("Lore")) {
// ListTag loreTag = displayTag.get("Lore");
// List<Tag> lore = new ArrayList<>();
// for (Tag subTag : loreTag.getValue()) {
// if (!(subTag instanceof StringTag)) continue;
// lore.add(new StringTag("", MessageTranslator.convertToJavaMessage(((StringTag) subTag).getValue())));
// }
// displayTag.put(new ListTag("Lore", lore));
// }
// }
if (displayTag.contains("Lore")) { // TODO no creative item should have enchantments *except* enchanted books
ListTag loreTag = displayTag.get("Lore"); // List<NbtMap> enchantmentTag = bedrockTag.getList("ench", NbtType.COMPOUND);
List<Tag> lore = new ArrayList<>(); // if (enchantmentTag != null) {
for (Tag subTag : loreTag.getValue()) { // List<Tag> enchantments = new ArrayList<>();
if (!(subTag instanceof StringTag)) continue; // for (Tag value : enchantmentTag.getValue()) {
lore.add(new StringTag("", MessageTranslator.convertToJavaMessage(((StringTag) subTag).getValue()))); // if (!(value instanceof CompoundTag tagValue))
} // continue;
displayTag.put(new ListTag("Lore", lore)); //
} // ShortTag bedrockId = tagValue.get("id");
} // if (bedrockId == null) continue;
//
ListTag enchantmentTag = tag.remove("ench"); // Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue());
if (enchantmentTag != null) { // if (enchantment != null) {
List<Tag> enchantments = new ArrayList<>(); // CompoundTag javaTag = new CompoundTag("");
for (Tag value : enchantmentTag.getValue()) { // Map<String, Tag> javaValue = javaTag.getValue();
if (!(value instanceof CompoundTag tagValue)) // javaValue.put("id", new StringTag("id", enchantment.getJavaIdentifier()));
continue; // ShortTag levelTag = tagValue.get("lvl");
// javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1));
ShortTag bedrockId = tagValue.get("id"); // javaTag.setValue(javaValue);
if (bedrockId == null) continue; //
// enchantments.add(javaTag);
Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue()); // } else {
if (enchantment != null) { // GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId);
CompoundTag javaTag = new CompoundTag(""); // }
Map<String, Tag> javaValue = javaTag.getValue(); // }
javaValue.put("id", new StringTag("id", enchantment.getJavaIdentifier())); // if (!enchantments.isEmpty()) {
ShortTag levelTag = tagValue.get("lvl"); // if ((this instanceof EnchantedBookItem)) {
javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1)); // bedrockTag.put(new ListTag("StoredEnchantments", enchantments));
javaTag.setValue(javaValue); // components.put(DataComponentType.STORED_ENCHANTMENTS, enchantments);
// } else {
enchantments.add(javaTag); // components.put(DataComponentType.ENCHANTMENTS, enchantments);
} else { // }
GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId); // }
} // }
}
if (!enchantments.isEmpty()) {
if ((this instanceof EnchantedBookItem)) {
tag.put(new ListTag("StoredEnchantments", enchantments));
} else {
tag.put(new ListTag("Enchantments", enchantments));
}
}
}
} }
protected final @Nullable NbtMap remapEnchantment(GeyserSession session, int enchantId, int level, BedrockItemBuilder builder) { protected final @Nullable NbtMap remapEnchantment(GeyserSession session, int enchantId, int level, BedrockItemBuilder builder) {
@ -243,8 +242,8 @@ public class Item {
/* Translation methods end */ /* Translation methods end */
public ItemStack newItemStack(int count, DataComponents components) { public GeyserItemStack newItemStack(int count, DataComponents components) {
return new ItemStack(this.javaId, count, components); return GeyserItemStack.of(this.javaId, count, components);
} }
public void setJavaId(int javaId) { // TODO like this? public void setJavaId(int javaId) { // TODO like this?

Datei anzeigen

@ -25,10 +25,7 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
@ -52,15 +49,4 @@ public class MapItem extends Item {
builder.putInt("map_name_index", mapValue); builder.putInt("map_name_index", mapValue);
builder.putByte("map_display_players", (byte) 1); builder.putByte("map_display_players", (byte) 1);
} }
@Override
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
super.translateNbtToJava(tag, mapping);
IntTag mapNameIndex = tag.remove("map_name_index");
if (mapNameIndex != null) {
tag.put(new IntTag("map", mapNameIndex.getValue()));
tag.remove("map_uuid");
}
}
} }

Datei anzeigen

@ -25,16 +25,15 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.item.Potion; import org.geysermc.geyser.inventory.item.Potion;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.registry.type.ItemMappings;
import org.geysermc.geyser.translator.item.CustomItemTranslator; import org.geysermc.geyser.translator.item.CustomItemTranslator;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
@ -69,12 +68,11 @@ public class PotionItem extends Item {
} }
@Override @Override
public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) { public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
Potion potion = Potion.getByBedrockId(itemData.getDamage()); Potion potion = Potion.getByBedrockId(itemData.getDamage());
ItemStack itemStack = super.translateToJava(itemData, mapping, mappings); GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings);
if (potion != null) { if (potion != null) {
StringTag potionTag = new StringTag("Potion", potion.getJavaIdentifier()); itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, potion.toComponent());
//itemStack.getNbt().put(potionTag);
} }
return itemStack; return itemStack;
} }

Datei anzeigen

@ -25,7 +25,6 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
@ -85,12 +84,4 @@ public class ShulkerBoxItem extends BlockItem {
} }
builder.putList("Items", NbtType.COMPOUND, itemsList); builder.putList("Items", NbtType.COMPOUND, itemsList);
} }
@Override
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
super.translateNbtToJava(tag, mapping);
// Remove any extraneous Bedrock tag and don't touch the Java one
tag.remove("Items");
}
} }

Datei anzeigen

@ -25,13 +25,12 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.format.TextDecoration;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMap;
import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity; import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.text.MinecraftLocale;
@ -58,26 +57,22 @@ public class TropicalFishBucketItem extends Item {
builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale())); builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale()));
// Add Java's client side lore tag // Add Java's client side lore tag
// Do you know how frequently Java NBT used to be before 1.20.5? It was a lot. And now it's just this lowly check. // Do you know how frequently Java NBT used to be before 1.20.5? It was a lot. And now it's just this lowly check.
CompoundTag entityTag = components.get(DataComponentType.BUCKET_ENTITY_DATA); NbtMap entityTag = components.get(DataComponentType.BUCKET_ENTITY_DATA);
if (entityTag != null && !entityTag.isEmpty()) { if (entityTag != null && !entityTag.isEmpty()) {
//TODO test //TODO test
Tag bucketVariant = entityTag.get("BucketVariantTag"); int bucketVariant = entityTag.getInt("BucketVariantTag");
if (bucketVariant == null || !(bucketVariant.getValue() instanceof Number)) {
return;
}
List<String> lore = builder.getOrCreateLore(); List<String> lore = builder.getOrCreateLore();
int varNumber = ((Number) bucketVariant.getValue()).intValue(); int predefinedVariantId = TropicalFishEntity.getPredefinedId(bucketVariant);
int predefinedVariantId = TropicalFishEntity.getPredefinedId(varNumber);
if (predefinedVariantId != -1) { if (predefinedVariantId != -1) {
Component tooltip = Component.translatable("entity.minecraft.tropical_fish.predefined." + predefinedVariantId, LORE_STYLE); Component tooltip = Component.translatable("entity.minecraft.tropical_fish.predefined." + predefinedVariantId, LORE_STYLE);
lore.add(0, MessageTranslator.convertMessage(tooltip, session.locale())); lore.add(0, MessageTranslator.convertMessage(tooltip, session.locale()));
} else { } else {
Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(varNumber), LORE_STYLE); Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(bucketVariant), LORE_STYLE);
lore.add(0, MessageTranslator.convertMessage(typeTooltip, session.locale())); lore.add(0, MessageTranslator.convertMessage(typeTooltip, session.locale()));
byte baseColor = TropicalFishEntity.getBaseColor(varNumber); byte baseColor = TropicalFishEntity.getBaseColor(bucketVariant);
byte patternColor = TropicalFishEntity.getPatternColor(varNumber); byte patternColor = TropicalFishEntity.getPatternColor(bucketVariant);
Component colorTooltip = Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(baseColor), LORE_STYLE); Component colorTooltip = Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(baseColor), LORE_STYLE);
if (baseColor != patternColor) { if (baseColor != patternColor) {
colorTooltip = colorTooltip.append(Component.text(", ", LORE_STYLE)) colorTooltip = colorTooltip.append(Component.text(", ", LORE_STYLE))

Datei anzeigen

@ -25,15 +25,10 @@
package org.geysermc.geyser.item.type; package org.geysermc.geyser.item.type;
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 com.github.steveice10.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder; import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
@ -69,24 +64,4 @@ public class WritableBookItem extends Item {
builder.putList("pages", NbtType.COMPOUND, bedrockPages); builder.putList("pages", NbtType.COMPOUND, bedrockPages);
} }
@Override
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
super.translateNbtToJava(tag, mapping);
if (!tag.contains("pages")) {
return;
}
List<Tag> pages = new ArrayList<>();
ListTag pagesTag = tag.get("pages");
for (Tag subTag : pagesTag.getValue()) {
if (!(subTag instanceof CompoundTag pageTag))
continue;
StringTag textTag = pageTag.get("text");
pages.add(new StringTag("", textTag.getValue()));
}
tag.remove("pages");
tag.put(new ListTag("pages", pages));
}
} }

Datei anzeigen

@ -62,7 +62,7 @@ public class WrittenBookItem extends Item {
for (Filterable<Component> page : bookContent.getPages()) { for (Filterable<Component> page : bookContent.getPages()) {
NbtMapBuilder pageBuilder = NbtMap.builder(); NbtMapBuilder pageBuilder = NbtMap.builder();
pageBuilder.putString("photoname", ""); pageBuilder.putString("photoname", "");
pageBuilder.putString("text", MessageTranslator.convertMessage(page.getRaw())); pageBuilder.putString("text", MessageTranslator.convertMessage(session, page.getRaw()));
bedrockPages.add(pageBuilder.build()); bedrockPages.add(pageBuilder.build());
} }
builder.putList("pages", NbtType.COMPOUND, bedrockPages); builder.putList("pages", NbtType.COMPOUND, bedrockPages);
@ -70,6 +70,5 @@ public class WrittenBookItem extends Item {
builder.putString("title", bookContent.getTitle().getRaw()) builder.putString("title", bookContent.getTitle().getRaw())
.putString("author", bookContent.getAuthor()) .putString("author", bookContent.getAuthor())
.putInt("generation", bookContent.getGeneration()); .putInt("generation", bookContent.getGeneration());
// TODO isResolved
} }
} }

Datei anzeigen

@ -25,13 +25,9 @@
package org.geysermc.geyser.level; package org.geysermc.geyser.level;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMap;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
import java.util.List;
/** /**
* Represents the information we store from the current Java dimension * Represents the information we store from the current Java dimension
* @param piglinSafe Whether piglins and hoglins are safe from conversion in this dimension. * @param piglinSafe Whether piglins and hoglins are safe from conversion in this dimension.
@ -39,33 +35,16 @@ import java.util.List;
*/ */
public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale) { public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale) {
public static void load(List<RegistryEntry> entries, Int2ObjectMap<JavaDimension> map) {
for (int i = 0; i < entries.size(); i++) {
RegistryEntry entry = entries.get(i);
CompoundTag dimension = entry.getData();
int minY = ((IntTag) dimension.get("min_y")).getValue();
int maxY = ((IntTag) dimension.get("height")).getValue();
// Logical height can be ignored probably - seems to be for artificial limits like the Nether.
// Set if piglins/hoglins should shake
boolean piglinSafe = ((Number) dimension.get("piglin_safe").getValue()).byteValue() != (byte) 0;
// Load world coordinate scale for the world border
double coordinateScale = ((Number) dimension.get("coordinate_scale").getValue()).doubleValue();
map.put(i, new JavaDimension(minY, maxY, piglinSafe, coordinateScale));
}
}
public static JavaDimension read(RegistryEntry entry) { public static JavaDimension read(RegistryEntry entry) {
CompoundTag dimension = entry.getData(); NbtMap dimension = entry.getData();
int minY = ((IntTag) dimension.get("min_y")).getValue(); int minY = dimension.getInt("min_y");
int maxY = ((IntTag) dimension.get("height")).getValue(); int maxY = dimension.getInt("height");
// Logical height can be ignored probably - seems to be for artificial limits like the Nether. // Logical height can be ignored probably - seems to be for artificial limits like the Nether.
// Set if piglins/hoglins should shake // Set if piglins/hoglins should shake
boolean piglinSafe = ((Number) dimension.get("piglin_safe").getValue()).byteValue() != (byte) 0; boolean piglinSafe = dimension.getBoolean("piglin_safe");
// Load world coordinate scale for the world border // Load world coordinate scale for the world border
double coordinateScale = ((Number) dimension.get("coordinate_scale").getValue()).doubleValue(); double coordinateScale = dimension.getDouble("coordinate_scale");
return new JavaDimension(minY, maxY, piglinSafe, coordinateScale); return new JavaDimension(minY, maxY, piglinSafe, coordinateScale);
} }

Datei anzeigen

@ -25,15 +25,13 @@
package org.geysermc.geyser.session.cache; package org.geysermc.geyser.session.cache;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
@ -54,17 +52,7 @@ public final class LodestoneCache {
*/ */
private int id = 1; private int id = 1;
public void cacheInventoryItem(GeyserItemStack itemStack) { public void cacheInventoryItem(GeyserItemStack itemStack, LodestoneTracker tracker) {
DataComponents components = itemStack.getComponents();
if (components == null) {
// invalid
return;
}
LodestoneTracker tracker = components.get(DataComponentType.LODESTONE_TRACKER);
if (tracker == null) {
return;
}
GlobalPos position = tracker.getPos(); GlobalPos position = tracker.getPos();
if (position == null) { if (position == null) {

Datei anzeigen

@ -26,10 +26,9 @@
package org.geysermc.geyser.skin; package org.geysermc.geyser.skin;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
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.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtType;
import org.cloudburstmc.protocol.bedrock.data.skin.ImageData; import org.cloudburstmc.protocol.bedrock.data.skin.ImageData;
import org.cloudburstmc.protocol.bedrock.data.skin.SerializedSkin; import org.cloudburstmc.protocol.bedrock.data.skin.SerializedSkin;
import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket;
@ -45,6 +44,7 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Base64; import java.util.Base64;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -224,22 +224,22 @@ public class SkinManager {
* @param tag tag to build the GameProfileData from * @param tag tag to build the GameProfileData from
* @return The built GameProfileData, or null if this wasn't a valid tag * @return The built GameProfileData, or null if this wasn't a valid tag
*/ */
public static @Nullable GameProfileData from(CompoundTag tag) { public static @Nullable GameProfileData from(NbtMap tag) {
if (!(tag.get("Properties") instanceof CompoundTag propertiesTag)) { NbtMap properties = tag.getCompound("Properties", null);
if (properties == null) {
return null; return null;
} }
if (!(propertiesTag.get("textures") instanceof ListTag texturesTag) || texturesTag.size() == 0) { List<NbtMap> textures = properties.getList("textures", NbtType.COMPOUND);
if (textures.isEmpty()) {
return null; return null;
} }
if (!(texturesTag.get(0) instanceof CompoundTag texturesData)) { String skinDataValue = textures.get(0).getString("Value", null);
return null; if (skinDataValue == null) {
}
if (!(texturesData.get("Value") instanceof StringTag skinDataValue)) {
return null; return null;
} }
try { try {
return loadFromJson(skinDataValue.getValue()); return loadFromJson(skinDataValue);
} catch (IOException e) { } catch (IOException e) {
GeyserImpl.getInstance().getLogger().debug("Something went wrong while processing skin for tag " + tag); GeyserImpl.getInstance().getLogger().debug("Something went wrong while processing skin for tag " + tag);
if (GeyserImpl.getInstance().getConfig().isDebugMode()) { if (GeyserImpl.getInstance().getConfig().isDebugMode()) {

Datei anzeigen

@ -25,15 +25,14 @@
package org.geysermc.geyser.text; package org.geysermc.geyser.text;
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 com.github.steveice10.opennbt.tag.builtin.Tag;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.Style;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtType;
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry; import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
@ -42,28 +41,28 @@ public final class TextDecoration {
private final Style style; private final Style style;
private final Set<Parameter> parameters; private final Set<Parameter> parameters;
public TextDecoration(CompoundTag tag) { public TextDecoration(NbtMap tag) {
translationKey = (String) tag.get("translation_key").getValue(); translationKey = tag.getString("translation_key");
CompoundTag styleTag = tag.get("style"); NbtMap styleTag = tag.getCompound("style");
Style.Builder builder = Style.style(); Style.Builder builder = Style.style();
if (styleTag != null) { if (!styleTag.isEmpty()) {
StringTag color = styleTag.get("color"); String color = styleTag.getString("color", null);
if (color != null) { if (color != null) {
builder.color(NamedTextColor.NAMES.value(color.getValue())); builder.color(NamedTextColor.NAMES.value(color));
} }
//TODO implement the rest //TODO implement the rest
Tag italic = styleTag.get("italic"); boolean italic = styleTag.getBoolean("italic");
if (italic != null && ((Number) italic.getValue()).byteValue() == (byte) 1) { if (italic) {
builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC); builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC);
} }
} }
style = builder.build(); style = builder.build();
this.parameters = EnumSet.noneOf(Parameter.class); this.parameters = EnumSet.noneOf(Parameter.class);
ListTag parameters = tag.get("parameters"); List<String> parameters = tag.getList("parameters", NbtType.STRING);
for (Tag parameter : parameters) { for (String parameter : parameters) {
this.parameters.add(Parameter.valueOf(((String) parameter.getValue()).toUpperCase(Locale.ROOT))); this.parameters.add(Parameter.valueOf(parameter.toUpperCase(Locale.ROOT)));
} }
} }
@ -90,8 +89,8 @@ public final class TextDecoration {
public static TextDecoration readChatType(RegistryEntry entry) { public static TextDecoration readChatType(RegistryEntry entry) {
// Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla. // Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla.
CompoundTag tag = entry.getData(); NbtMap tag = entry.getData();
CompoundTag chat = tag.get("chat"); NbtMap chat = tag.getCompound("chat", null);
TextDecoration textDecoration = null; TextDecoration textDecoration = null;
if (chat != null) { if (chat != null) {
textDecoration = new TextDecoration(chat); textDecoration = new TextDecoration(chat);

Datei anzeigen

@ -224,7 +224,7 @@ public abstract class InventoryTranslator {
//only set the head if the destination is the head slot //only set the head if the destination is the head slot
GeyserItemStack javaItem = inventory.getItem(sourceSlot); GeyserItemStack javaItem = inventory.getItem(sourceSlot);
if (javaItem.asItem() == Items.PLAYER_HEAD if (javaItem.asItem() == Items.PLAYER_HEAD
&& javaItem.getNbt() != null) { && javaItem.getComponents() != null) {
FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents()); FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents());
} }
} else if (sourceSlot == 5) { } else if (sourceSlot == 5) {

Datei anzeigen

@ -94,7 +94,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
contents[i - 5] = item.getItemData(session); contents[i - 5] = item.getItemData(session);
if (i == 5 && if (i == 5 &&
item.asItem() == Items.PLAYER_HEAD && item.asItem() == Items.PLAYER_HEAD &&
item.getNbt() != null) { item.getComponents() != null) {
FakeHeadProvider.setHead(session, session.getPlayerEntity(), item.getComponents()); FakeHeadProvider.setHead(session, session.getPlayerEntity(), item.getComponents());
} }
} }
@ -138,7 +138,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
if (slot == 5) { if (slot == 5) {
// Check for custom skull // Check for custom skull
if (javaItem.asItem() == Items.PLAYER_HEAD if (javaItem.asItem() == Items.PLAYER_HEAD
&& javaItem.getNbt() != null) { && javaItem.getComponents() != null) {
FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents()); FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents());
} else { } else {
FakeHeadProvider.restoreOriginalSkin(session, session.getPlayerEntity()); FakeHeadProvider.restoreOriginalSkin(session, session.getPlayerEntity());

Datei anzeigen

@ -58,7 +58,7 @@ public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator
.putInt("z", position.getZ()) .putInt("z", position.getZ())
.putString("CustomName", inventory.getTitle()); .putString("CustomName", inventory.getTitle());
// Don't reset facing property // Don't reset facing property
shulkerBoxTranslator.translateTag(tag, null, javaBlockState); shulkerBoxTranslator.translateTag(session, tag, null, javaBlockState);
BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); BlockEntityDataPacket dataPacket = new BlockEntityDataPacket();
dataPacket.setData(tag.build()); dataPacket.setData(tag.build());

Datei anzeigen

@ -29,22 +29,11 @@ import com.github.steveice10.mc.auth.data.GameProfile;
import com.github.steveice10.mc.auth.data.GameProfile.Texture; import com.github.steveice10.mc.auth.data.GameProfile.Texture;
import com.github.steveice10.mc.auth.data.GameProfile.TextureType; import com.github.steveice10.mc.auth.data.GameProfile.TextureType;
import com.github.steveice10.mc.auth.exception.property.PropertyException; import com.github.steveice10.mc.auth.exception.property.PropertyException;
import org.geysermc.mcprotocollib.protocol.data.game.Identifier;
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.AdventureModePredicate;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers;
import com.github.steveice10.opennbt.tag.builtin.*;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.nbt.NbtList;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType;
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
@ -63,6 +52,13 @@ import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.InventoryUtils; import org.geysermc.geyser.util.InventoryUtils;
import org.geysermc.mcprotocollib.protocol.data.game.Identifier;
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.AdventureModePredicate;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttributeModifiers;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -93,16 +89,17 @@ public final class ItemTranslator {
ItemMapping bedrockItem = mappings.getMapping(data); ItemMapping bedrockItem = mappings.getMapping(data);
Item javaItem = bedrockItem.getJavaItem(); Item javaItem = bedrockItem.getJavaItem();
ItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings); GeyserItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings);
// if (itemStack.getNbt() != null) { NbtMap nbt = data.getTag();
// javaItem.translateNbtToJava(itemStack.getNbt(), bedrockItem); if (nbt != null && !nbt.isEmpty()) {
// if (itemStack.getNbt().isEmpty()) { DataComponents components = new DataComponents(new HashMap<>());
// // Otherwise, seems to cause issues with villagers accepting books, and I don't see how this will break anything else. - Camotoy javaItem.translateNbtToJava(nbt, components, bedrockItem);
// itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), null); if (!components.getDataComponents().isEmpty()) {
// } itemStack.setComponents(components);
// } }
return itemStack; }
return itemStack.getItemStack();
} }
public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, int javaId, int count, DataComponents components) { public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, int javaId, int count, DataComponents components) {
@ -375,125 +372,6 @@ public final class ItemTranslator {
} }
} }
public static NbtMap translateNbtToBedrock(CompoundTag tag) {
if (!tag.getValue().isEmpty()) {
NbtMapBuilder builder = NbtMap.builder();
for (Tag javaTag : tag.values()) {
Object translatedTag = translateToBedrockNBT(javaTag);
if (translatedTag == null)
continue;
builder.put(javaTag.getName(), translatedTag);
}
return builder.build();
}
return NbtMap.EMPTY;
}
private static @Nullable Object translateToBedrockNBT(Tag tag) {
if (tag instanceof CompoundTag compoundTag) {
return translateNbtToBedrock(compoundTag);
}
if (tag instanceof ListTag listTag) {
List<Object> tagList = new ArrayList<>();
for (Tag value : listTag) {
tagList.add(translateToBedrockNBT(value));
}
NbtType<?> type = NbtType.COMPOUND;
if (!tagList.isEmpty()) {
type = NbtType.byClass(tagList.get(0).getClass());
}
//noinspection unchecked,rawtypes
return new NbtList(type, tagList);
}
if (tag instanceof LongArrayTag) {
//Long array tag does not exist in BE
//LongArrayTag longArrayTag = (LongArrayTag) tag;
//return new org.cloudburstmc.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
return null;
}
return tag.getValue();
}
public static CompoundTag translateToJavaNBT(String name, NbtMap tag) {
CompoundTag javaTag = new CompoundTag(name);
Map<String, Tag> javaValue = javaTag.getValue();
if (tag != null && !tag.isEmpty()) {
for (Map.Entry<String, Object> entry : tag.entrySet()) {
Tag translatedTag = translateToJavaNBT(entry.getKey(), entry.getValue());
if (translatedTag == null)
continue;
javaValue.put(translatedTag.getName(), translatedTag);
}
}
javaTag.setValue(javaValue);
return javaTag;
}
private static @Nullable Tag translateToJavaNBT(String name, Object object) {
if (object instanceof int[]) {
return new IntArrayTag(name, (int[]) object);
}
if (object instanceof byte[]) {
return new ByteArrayTag(name, (byte[]) object);
}
if (object instanceof Byte) {
return new ByteTag(name, (byte) object);
}
if (object instanceof Float) {
return new FloatTag(name, (float) object);
}
if (object instanceof Double) {
return new DoubleTag(name, (double) object);
}
if (object instanceof Integer) {
return new IntTag(name, (int) object);
}
if (object instanceof long[]) {
return new LongArrayTag(name, (long[]) object);
}
if (object instanceof Long) {
return new LongTag(name, (long) object);
}
if (object instanceof Short) {
return new ShortTag(name, (short) object);
}
if (object instanceof String) {
return new StringTag(name, (String) object);
}
if (object instanceof List) {
List<Tag> tags = new ArrayList<>();
for (Object value : (List<?>) object) {
Tag javaTag = translateToJavaNBT("", value);
if (javaTag != null)
tags.add(javaTag);
}
return new ListTag(name, tags);
}
if (object instanceof NbtMap map) {
return translateToJavaNBT(name, map);
}
return null;
}
/** /**
* Translates the display name of the item * Translates the display name of the item
* @param session the Bedrock client's session * @param session the Bedrock client's session

Datei anzeigen

@ -25,40 +25,43 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.cloudburstmc.nbt.NbtMap;
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.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.item.type.BannerItem; import org.geysermc.geyser.item.type.BannerItem;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
import java.util.List;
@BlockEntity(type = BlockEntityType.BANNER) @BlockEntity(type = BlockEntityType.BANNER)
public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
int bannerColor = BlockStateValues.getBannerColor(blockState); int bannerColor = BlockStateValues.getBannerColor(blockState);
if (bannerColor != -1) { if (bannerColor != -1) {
builder.put("Base", 15 - bannerColor); bedrockNbt.putInt("Base", 15 - bannerColor);
} }
if (tag == null) { if (javaNbt == null) {
return; return;
} }
if (tag.get("patterns") instanceof ListTag patterns) { List<NbtMap> patterns = javaNbt.getList("patterns", NbtType.COMPOUND);
if (!patterns.isEmpty()) {
if (BannerItem.isOminous(patterns)) { if (BannerItem.isOminous(patterns)) {
// This is an ominous banner; don't try to translate the raw patterns (it doesn't translate correctly) // This is an ominous banner; don't try to translate the raw patterns (it doesn't translate correctly)
// and tell the Bedrock client that this is an ominous banner // and tell the Bedrock client that this is an ominous banner
builder.putInt("Type", 1); bedrockNbt.putInt("Type", 1);
} else { } else {
builder.put("Patterns", BannerItem.convertBannerPattern(patterns)); bedrockNbt.putList("Patterns", NbtType.COMPOUND, BannerItem.convertBannerPattern(patterns));
} }
} }
Tag customName = tag.get("CustomName"); String customName = javaNbt.getString("CustomName", null);
if (customName != null) { if (customName != null) {
builder.put("CustomName", customName.getValue()); bedrockNbt.putString("CustomName", customName);
} }
} }
} }

Datei anzeigen

@ -25,18 +25,19 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.cloudburstmc.nbt.NbtMap;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
@BlockEntity(type = BlockEntityType.BEACON) @BlockEntity(type = BlockEntityType.BEACON)
public class BeaconBlockEntityTranslator extends BlockEntityTranslator { public class BeaconBlockEntityTranslator extends BlockEntityTranslator {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
int primary = getOrDefault(tag.get("Primary"), 0); int primary = javaNbt.getInt("primary");
// The effects here generally map one-to-one Java <-> Bedrock. Only the newer ones get more complicated // The effects here generally map one-to-one Java <-> Bedrock. Only the newer ones get more complicated
builder.putInt("primary", primary == -1 ? 0 : primary); bedrockNbt.putInt("primary", primary == -1 ? 0 : primary);
int secondary = getOrDefault(tag.get("Secondary"), 0); int secondary = javaNbt.getInt("secondary");
builder.putInt("secondary", secondary == -1 ? 0 : secondary); bedrockNbt.putInt("secondary", secondary == -1 ? 0 : secondary);
} }
} }

Datei anzeigen

@ -25,20 +25,21 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.cloudburstmc.nbt.NbtMap;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
@BlockEntity(type = BlockEntityType.BED) @BlockEntity(type = BlockEntityType.BED)
public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
byte bedcolor = BlockStateValues.getBedColor(blockState); byte bedcolor = BlockStateValues.getBedColor(blockState);
// Just in case... // Just in case...
if (bedcolor == -1) { if (bedcolor == -1) {
bedcolor = 0; bedcolor = 0;
} }
builder.put("color", bedcolor); bedrockNbt.putByte("color", bedcolor);
} }
} }

Datei anzeigen

@ -25,13 +25,11 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.BlockEntityUtils; import org.geysermc.geyser.util.BlockEntityUtils;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
/** /**
* The class that all block entities (on both Java and Bedrock) should translate with * The class that all block entities (on both Java and Bedrock) should translate with
@ -40,11 +38,11 @@ public abstract class BlockEntityTranslator {
protected BlockEntityTranslator() { protected BlockEntityTranslator() {
} }
public abstract void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState); public abstract void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState);
public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) {
NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z); NbtMapBuilder tagBuilder = getConstantBedrockTag(type, x, y, z);
translateTag(tagBuilder, tag, blockState); translateTag(session, tagBuilder, javaNbt, blockState);
return tagBuilder.build(); return tagBuilder.build();
} }
@ -59,9 +57,4 @@ public abstract class BlockEntityTranslator {
.putInt("z", z) .putInt("z", z)
.putString("id", bedrockId); .putString("id", bedrockId);
} }
@SuppressWarnings("unchecked")
protected <T> T getOrDefault(Tag tag, T defaultValue) {
return (tag != null && tag.getValue() != null) ? (T) tag.getValue() : defaultValue;
}
} }

Datei anzeigen

@ -25,49 +25,46 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
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.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.item.Items; import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
@BlockEntity(type = BlockEntityType.BRUSHABLE_BLOCK) @BlockEntity(type = BlockEntityType.BRUSHABLE_BLOCK)
public class BrushableBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { public class BrushableBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
if (!(tag.remove("item") instanceof CompoundTag itemTag)) { NbtMap itemTag = javaNbt.getCompound("item");
if (itemTag.isEmpty()) {
return; return;
} }
Tag hitDirection = tag.get("hit_direction"); byte hitDirection = javaNbt.getByte("hit_direction", (byte) -1);
if (hitDirection == null) { if (hitDirection == -1) {
// java server sends no direction when the item recedes back into the block (if player stops brushing) // java server sends no direction when the item recedes back into the block (if player stops brushing)
return; return;
} }
String id = ((StringTag) itemTag.get("id")).getValue(); String id = itemTag.getString("id");
if (Items.AIR.javaIdentifier().equals(id)) { if (Items.AIR.javaIdentifier().equals(id)) {
return; // server sends air when the block contains nothing return; // server sends air when the block contains nothing
} }
ItemMapping mapping = Registries.ITEMS.forVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()).getMapping(id); ItemMapping mapping = session.getItemMappings().getMapping(id);
if (mapping == null) { if (mapping == null) {
return; return;
} }
NbtMapBuilder itemBuilder = NbtMap.builder() NbtMapBuilder itemBuilder = NbtMap.builder()
.putString("Name", mapping.getBedrockIdentifier()) .putString("Name", mapping.getBedrockIdentifier())
.putByte("Count", (byte) itemTag.get("Count").getValue()); .putByte("Count", (byte) itemTag.getByte("Count"));
builder.putCompound("item", itemBuilder.build()); bedrockNbt.putCompound("item", itemBuilder.build());
// controls which side the item protrudes from // controls which side the item protrudes from
builder.putByte("brush_direction", ((Number) hitDirection.getValue()).byteValue()); bedrockNbt.putByte("brush_direction", hitDirection);
// controls how much the item protrudes // controls how much the item protrudes
builder.putInt("brush_count", BlockStateValues.getBrushProgress(blockState)); bedrockNbt.putInt("brush_count", BlockStateValues.getBrushProgress(blockState));
} }
} }

Datei anzeigen

@ -25,37 +25,37 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
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.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.network.GameProtocol; import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
import java.util.List;
@BlockEntity(type = BlockEntityType.CAMPFIRE) @BlockEntity(type = BlockEntityType.CAMPFIRE)
public class CampfireBlockEntityTranslator extends BlockEntityTranslator { public class CampfireBlockEntityTranslator extends BlockEntityTranslator {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
if (tag.get("Items") instanceof ListTag items) { List<NbtMap> items = javaNbt.getList("Items", NbtType.COMPOUND);
if (items != null) {
int i = 1; int i = 1;
for (Tag itemTag : items.getValue()) { for (NbtMap itemTag : items) {
builder.put("Item" + i, getItem((CompoundTag) itemTag)); bedrockNbt.put("Item" + i, getItem(session, itemTag));
i++; i++;
} }
} }
} }
protected NbtMap getItem(CompoundTag tag) { protected NbtMap getItem(GeyserSession session, NbtMap tag) {
// TODO: Version independent mappings ItemMapping mapping = session.getItemMappings().getMapping(tag.getString("id"));
ItemMapping mapping = Registries.ITEMS.forVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()).getMapping((String) tag.get("id").getValue()); if (mapping == null) {
NbtMapBuilder tagBuilder = NbtMap.builder() mapping = ItemMapping.AIR;
.putString("Name", mapping.getBedrockIdentifier()) }
.putByte("Count", (byte) tag.get("Count").getValue()) NbtMapBuilder tagBuilder = BedrockItemBuilder.createItemNbt(mapping, tag.getByte("Count"), mapping.getBedrockData());
.putShort("Damage", (short) mapping.getBedrockData()); tagBuilder.put("tag", NbtMap.builder().build()); // I don't think this is necessary... - Camo, 1.20.5/1.20.80
tagBuilder.put("tag", NbtMap.builder().build());
return tagBuilder.build(); return tagBuilder.build();
} }
} }

Datei anzeigen

@ -25,34 +25,31 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.cloudburstmc.nbt.NbtMap;
import com.github.steveice10.opennbt.tag.builtin.*;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
@BlockEntity(type = BlockEntityType.COMMAND_BLOCK) @BlockEntity(type = BlockEntityType.COMMAND_BLOCK)
public class CommandBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { public class CommandBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
if (tag == null || tag.size() < 5) { if (javaNbt == null || javaNbt.size() < 5) {
return; // These values aren't here return; // These values aren't here
} }
// Java infers from the block state, but Bedrock needs it in the tag // Java infers from the block state, but Bedrock needs it in the tag
builder.put("conditionalMode", BlockStateValues.getCommandBlockValues().getOrDefault(blockState, (byte) 0)); bedrockNbt.putByte("conditionalMode", BlockStateValues.getCommandBlockValues().getOrDefault(blockState, (byte) 0));
// Java and Bedrock values // Java and Bedrock values
builder.put("conditionMet", ((ByteTag) tag.get("conditionMet")).getValue()); bedrockNbt.putByte("conditionMet", javaNbt.getByte("conditionMet"));
builder.put("auto", ((ByteTag) tag.get("auto")).getValue()); bedrockNbt.putByte("auto", javaNbt.getByte("auto"));
builder.put("CustomName", MessageTranslator.convertJsonMessage(((StringTag) tag.get("CustomName")).getValue())); bedrockNbt.putString("CustomName", MessageTranslator.convertJsonMessage(javaNbt.getString("CustomName"), session.locale()));
builder.put("powered", ((ByteTag) tag.get("powered")).getValue()); bedrockNbt.putByte("powered", javaNbt.getByte("powered"));
builder.put("Command", ((StringTag) tag.get("Command")).getValue()); bedrockNbt.putString("Command", javaNbt.getString("Command"));
builder.put("SuccessCount", ((IntTag) tag.get("SuccessCount")).getValue()); bedrockNbt.putInt("SuccessCount", javaNbt.getInt("SuccessCount"));
builder.put("TrackOutput", ((ByteTag) tag.get("TrackOutput")).getValue()); bedrockNbt.putByte("TrackOutput", javaNbt.getByte("TrackOutput"));
builder.put("UpdateLastExecution", ((ByteTag) tag.get("UpdateLastExecution")).getValue()); bedrockNbt.putByte("UpdateLastExecution", javaNbt.getByte("UpdateLastExecution"));
if (tag.get("LastExecution") != null) { bedrockNbt.putLong("LastExecution", javaNbt.getLong("LastExecution")); // Note: may not be present? Was a null check before 1.20.5
builder.put("LastExecution", ((LongTag) tag.get("LastExecution")).getValue());
} else {
builder.put("LastExecution", (long) 0);
}
} }
} }

Datei anzeigen

@ -25,33 +25,22 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMap;
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.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
import java.util.ArrayList;
import java.util.List;
@BlockEntity(type = BlockEntityType.DECORATED_POT) @BlockEntity(type = BlockEntityType.DECORATED_POT)
public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator { public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
if (tag == null) { if (javaNbt == null) {
return; return;
} }
// exact same format // exact same format
if (tag.get("sherds") instanceof ListTag sherds) { bedrockNbt.putList("sherds", NbtType.STRING, javaNbt.getList("sherds", NbtType.STRING));
List<String> translated = new ArrayList<>(4);
for (Tag sherd : sherds) {
translated.add(((StringTag) sherd).getValue());
}
builder.putList("sherds", NbtType.STRING, translated);
}
} }
} }

Datei anzeigen

@ -25,8 +25,8 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.level.block.DoubleChestValue; import org.geysermc.geyser.level.block.DoubleChestValue;
@ -47,17 +47,17 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl
@Override @Override
public void updateBlock(GeyserSession session, int blockState, Vector3i position) { public void updateBlock(GeyserSession session, int blockState, Vector3i position) {
NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockEntityType.CHEST), position.getX(), position.getY(), position.getZ()); NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(BlockEntityType.CHEST), position.getX(), position.getY(), position.getZ());
translateTag(tagBuilder, null, blockState); translateTag(session, tagBuilder, null, blockState);
BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position); BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position);
} }
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
DoubleChestValue chestValues = BlockStateValues.getDoubleChestValues().get(blockState); DoubleChestValue chestValues = BlockStateValues.getDoubleChestValues().get(blockState);
if (chestValues != null) { if (chestValues != null) {
int x = (int) builder.get("x"); int x = (int) bedrockNbt.get("x");
int z = (int) builder.get("z"); int z = (int) bedrockNbt.get("z");
translateChestValue(builder, chestValues, x, z); translateChestValue(bedrockNbt, chestValues, x, z);
} }
} }
@ -88,10 +88,10 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl
x = x + (chestValues.isLeft() ? 1 : -1); x = x + (chestValues.isLeft() ? 1 : -1);
} }
} }
builder.put("pairx", x); builder.putInt("pairx", x);
builder.put("pairz", z); builder.putInt("pairz", z);
if (!chestValues.isLeft()) { if (!chestValues.isLeft()) {
builder.put("pairlead", (byte) 1); builder.putInt("pairlead", (byte) 1);
} }
} }
} }

Datei anzeigen

@ -25,11 +25,12 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession;
public class EmptyBlockEntityTranslator extends BlockEntityTranslator { public class EmptyBlockEntityTranslator extends BlockEntityTranslator {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
} }
} }

Datei anzeigen

@ -25,44 +25,28 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.LongTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import org.cloudburstmc.nbt.NbtList; import org.cloudburstmc.nbt.NbtList;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
import java.util.LinkedHashMap;
@BlockEntity(type = BlockEntityType.END_GATEWAY) @BlockEntity(type = BlockEntityType.END_GATEWAY)
public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator { public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
Tag ageTag = tag.get("Age"); bedrockNbt.putInt("Age", (int) javaNbt.getLong("Age"));
if (ageTag instanceof LongTag) {
builder.put("Age", (int) ((long) ageTag.getValue()));
}
// Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist // Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist
// Linked coordinates // Linked coordinates
IntList tagsList = new IntArrayList(); IntList tagsList = new IntArrayList();
// Yes, the axis letters are capitalized // Yes, the axis letters are capitalized
tagsList.add(getExitPortalCoordinate(tag, "X")); NbtMap exitPortal = javaNbt.getCompound("ExitPortal");
tagsList.add(getExitPortalCoordinate(tag, "Y")); tagsList.add(exitPortal.getInt("X", 0));
tagsList.add(getExitPortalCoordinate(tag, "Z")); tagsList.add(exitPortal.getInt("Y", 0));
builder.put("ExitPortal", new NbtList<>(NbtType.INT, tagsList)); tagsList.add(exitPortal.getInt( "Z", 0));
} bedrockNbt.put("ExitPortal", new NbtList<>(NbtType.INT, tagsList));
private int getExitPortalCoordinate(CompoundTag tag, String axis) {
// Return 0 if it doesn't exist, otherwise give proper value
if (tag.get("ExitPortal") != null) {
LinkedHashMap<?, ?> compoundTag = (LinkedHashMap<?, ?>) tag.get("ExitPortal").getValue();
IntTag intTag = (IntTag) compoundTag.get(axis);
return intTag.getValue();
}
return 0;
} }
} }

Datei anzeigen

@ -25,28 +25,27 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMap;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
@BlockEntity(type = BlockEntityType.JIGSAW) @BlockEntity(type = BlockEntityType.JIGSAW)
public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
Tag jointTag = tag.get("joint"); String joint = javaNbt.getString("joint", null);
if (jointTag instanceof StringTag) { if (joint != null) {
builder.put("joint", ((StringTag) jointTag).getValue()); bedrockNbt.putString("joint", joint);
} else { } else {
// Tag is not present in at least 1.14.4 Paper // Tag is not present in at least 1.14.4 Paper
// Minecraft 1.18.1 deliberately has a fallback here, but not for any other value // Minecraft 1.18.1 deliberately has a fallback here, but not for any other value
builder.put("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState) ? "aligned" : "rollable"); bedrockNbt.putString("joint", BlockStateValues.getHorizontalFacingJigsaws().contains(blockState) ? "aligned" : "rollable");
} }
builder.put("name", getOrDefault(tag.get("name"), "")); bedrockNbt.putString("name", javaNbt.getString("name"));
builder.put("target_pool", getOrDefault(tag.get("pool"), "")); bedrockNbt.putString("target_pool", javaNbt.getString("target_pool"));
builder.put("final_state", ((StringTag) tag.get("final_state")).getValue()); bedrockNbt.putString("final_state", javaNbt.getString("final_state"));
builder.put("target", getOrDefault(tag.get("target"), "")); bedrockNbt.putString("target", javaNbt.getString("target"));
} }
} }

Datei anzeigen

@ -25,10 +25,11 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator; import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
@ -39,12 +40,12 @@ public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator imple
* where {@code tag} is passed as null. * where {@code tag} is passed as null.
*/ */
@Override @Override
public void translateTag(NbtMapBuilder builder, @Nullable CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, @Nullable NbtMap javaNbt, int blockState) {
byte direction = BlockStateValues.getShulkerBoxDirection(blockState); byte direction = BlockStateValues.getShulkerBoxDirection(blockState);
// Just in case... // Just in case...
if (direction == -1) { if (direction == -1) {
direction = 1; direction = 1;
} }
builder.put("facing", direction); bedrockNbt.putByte("facing", direction);
} }
} }

Datei anzeigen

@ -25,15 +25,16 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
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.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.SignUtils; import org.geysermc.geyser.util.SignUtils;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
import java.util.List;
@BlockEntity(type = BlockEntityType.SIGN) @BlockEntity(type = BlockEntityType.SIGN)
public class SignBlockEntityTranslator extends BlockEntityTranslator { public class SignBlockEntityTranslator extends BlockEntityTranslator {
@ -72,25 +73,21 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator {
} }
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
builder.putCompound("FrontText", translateSide(tag.get("front_text"))); bedrockNbt.putCompound("FrontText", translateSide(javaNbt.getCompound("front_text")));
builder.putCompound("BackText", translateSide(tag.get("back_text"))); bedrockNbt.putCompound("BackText", translateSide(javaNbt.getCompound("back_text")));
var waxed = tag.get("is_waxed"); bedrockNbt.putBoolean("IsWaxed", javaNbt.getBoolean("is_waxed"));
builder.putBoolean("IsWaxed", waxed != null && waxed.getValue() instanceof Number number && number.byteValue() != 0);
} }
private NbtMap translateSide(Tag tag) { private NbtMap translateSide(NbtMap javaNbt) {
if (!(tag instanceof CompoundTag signData)) {
return NbtMap.EMPTY;
}
NbtMapBuilder builder = NbtMap.builder(); NbtMapBuilder builder = NbtMap.builder();
StringBuilder signText = new StringBuilder(); StringBuilder signText = new StringBuilder();
Tag messages = signData.get("messages"); List<String> messages = javaNbt.getList("messages", NbtType.STRING);
if (messages instanceof ListTag listTag) { if (!messages.isEmpty()) {
var it = listTag.iterator(); var it = messages.iterator();
while (it.hasNext()) { while (it.hasNext()) {
String signLine = (String) it.next().getValue(); String signLine = it.next();
signLine = MessageTranslator.convertMessageLenient(signLine); signLine = MessageTranslator.convertMessageLenient(signLine);
// Check the character width on the sign to ensure there is no overflow that is usually hidden // Check the character width on the sign to ensure there is no overflow that is usually hidden
@ -133,13 +130,13 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator {
builder.putString("Text", signText.toString()); builder.putString("Text", signText.toString());
// Java Edition 1.14 added the ability to change the text color of the whole sign using dye // Java Edition 1.14 added the ability to change the text color of the whole sign using dye
Tag color = signData.get("color"); String color = javaNbt.getString("color", null);
if (color != null) { if (color != null) {
builder.putInt("SignTextColor", getBedrockSignColor(color.getValue().toString())); builder.putInt("SignTextColor", getBedrockSignColor(color));
} }
// Glowing text // Glowing text
boolean isGlowing = getOrDefault(signData.get("has_glowing_text"), (byte) 0) != (byte) 0; boolean isGlowing = javaNbt.getBoolean("has_glowing_text");
builder.putBoolean("IgnoreLighting", isGlowing); builder.putBoolean("IgnoreLighting", isGlowing);
return builder.build(); return builder.build();
} }

Datei anzeigen

@ -25,24 +25,22 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.cloudburstmc.nbt.NbtType;
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.level.block.BlockStateValues; import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.SkullCache; import org.geysermc.geyser.session.cache.SkullCache;
import org.geysermc.geyser.skin.SkinProvider; import org.geysermc.geyser.skin.SkinProvider;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -52,56 +50,60 @@ import java.util.concurrent.ExecutionException;
public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
byte skullVariant = BlockStateValues.getSkullVariant(blockState); byte skullVariant = BlockStateValues.getSkullVariant(blockState);
float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f; float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f;
// Just in case... // Just in case...
if (skullVariant == -1) { if (skullVariant == -1) {
skullVariant = 0; skullVariant = 0;
} }
builder.put("Rotation", rotation); bedrockNbt.putFloat("Rotation", rotation);
builder.put("SkullType", skullVariant); bedrockNbt.putByte("SkullType", skullVariant);
if (BlockStateValues.isSkullPowered(blockState)) { if (BlockStateValues.isSkullPowered(blockState)) {
builder.putBoolean("MouthMoving", true); bedrockNbt.putBoolean("MouthMoving", true);
} }
} }
private static UUID getUUID(CompoundTag profile) { private static UUID getUUID(NbtMap profile) {
if (profile.get("id") instanceof IntArrayTag uuidTag && uuidTag.length() == 4) { int[] uuidAsArray = profile.getIntArray("id");
int[] uuidAsArray = uuidTag.getValue(); if (uuidAsArray.length == 4) {
// thank u viaversion // thank u viaversion
return new UUID((long) uuidAsArray[0] << 32 | ((long) uuidAsArray[1] & 0xFFFFFFFFL), return new UUID((long) uuidAsArray[0] << 32 | ((long) uuidAsArray[1] & 0xFFFFFFFFL),
(long) uuidAsArray[2] << 32 | ((long) uuidAsArray[3] & 0xFFFFFFFFL)); (long) uuidAsArray[2] << 32 | ((long) uuidAsArray[3] & 0xFFFFFFFFL));
} }
// Convert username to an offline UUID // Convert username to an offline UUID
String username = null; String username = null;
if (profile.get("name") instanceof StringTag nameTag) { String nameTag = profile.getString("name", null);
username = nameTag.getValue().toLowerCase(Locale.ROOT); if (nameTag != null) {
username = nameTag.toLowerCase(Locale.ROOT);
} }
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); return UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8));
} }
private static CompletableFuture<String> getTextures(CompoundTag profile, UUID uuid) { private static CompletableFuture<@Nullable String> getTextures(NbtMap profile, UUID uuid) {
ListTag properties = profile.get("properties"); List<NbtMap> properties = profile.getList("properties", NbtType.COMPOUND);
if (properties == null) { if (properties.isEmpty()) {
if (uuid != null && uuid.version() == 4) { if (uuid != null && uuid.version() == 4) {
String uuidString = uuid.toString().replace("-", ""); String uuidString = uuid.toString().replace("-", "");
return SkinProvider.requestTexturesFromUUID(uuidString); return SkinProvider.requestTexturesFromUUID(uuidString);
} else if (profile.get("name") instanceof StringTag nameTag) { } else {
// Fall back to username if UUID was missing or was an offline mode UUID String nameTag = profile.getString("name", null);
return SkinProvider.requestTexturesFromUsername(nameTag.getValue()); if (nameTag != null) {
// Fall back to username if UUID was missing or was an offline mode UUID
return SkinProvider.requestTexturesFromUsername(nameTag);
}
} }
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);
} }
LinkedHashMap<?,?> tag1 = (LinkedHashMap<?,?>) properties.get(0).getValue(); NbtMap tag1 = properties.get(0);
StringTag texture = (StringTag) tag1.get("value"); String texture = tag1.getString("value", null);
return CompletableFuture.completedFuture(texture.getValue()); return CompletableFuture.completedFuture(texture);
} }
public static @Nullable BlockDefinition translateSkull(GeyserSession session, CompoundTag tag, Vector3i blockPosition, int blockState) { public static @Nullable BlockDefinition translateSkull(GeyserSession session, NbtMap javaNbt, Vector3i blockPosition, int blockState) {
CompoundTag profile = tag.get("profile"); NbtMap profile = javaNbt.getCompound("profile");
if (profile == null) { if (profile.isEmpty()) {
session.getSkullCache().removeSkull(blockPosition); session.getSkullCache().removeSkull(blockPosition);
return null; return null;
} }
@ -112,13 +114,13 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements
try { try {
String texture = texturesFuture.get(); String texture = texturesFuture.get();
if (texture == null) { if (texture == null) {
session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + tag); session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + javaNbt);
return null; return null;
} }
SkullCache.Skull skull = session.getSkullCache().putSkull(blockPosition, uuid, texture, blockState); SkullCache.Skull skull = session.getSkullCache().putSkull(blockPosition, uuid, texture, blockState);
return skull.getBlockDefinition(); return skull.getBlockDefinition();
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
session.getGeyser().getLogger().debug("Failed to acquire textures for custom skull: " + blockPosition + " " + tag); session.getGeyser().getLogger().debug("Failed to acquire textures for custom skull: " + blockPosition + " " + javaNbt);
if (GeyserImpl.getInstance().getConfig().isDebugMode()) { if (GeyserImpl.getInstance().getConfig().isDebugMode()) {
e.printStackTrace(); e.printStackTrace();
} }
@ -129,7 +131,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements
// profile contained a username, so we have to wait for it to be retrieved // profile contained a username, so we have to wait for it to be retrieved
texturesFuture.whenComplete((texturesProperty, throwable) -> { texturesFuture.whenComplete((texturesProperty, throwable) -> {
if (texturesProperty == null) { if (texturesProperty == null) {
session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + tag); session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + javaNbt);
return; return;
} }
if (session.getEventLoop().inEventLoop()) { if (session.getEventLoop().inEventLoop()) {

Datei anzeigen

@ -25,10 +25,6 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
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.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.math.vector.Vector3i;
@ -38,17 +34,18 @@ import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.geyser.entity.EntityDefinition; import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
@BlockEntity(type = BlockEntityType.MOB_SPAWNER) @BlockEntity(type = BlockEntityType.MOB_SPAWNER)
public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { public class SpawnerBlockEntityTranslator extends BlockEntityTranslator {
@Override @Override
public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) {
// Sending an empty EntityIdentifier to empty the spawner is ignored by the client, so we send a whole new spawner! // Sending an empty EntityIdentifier to empty the spawner is ignored by the client, so we send a whole new spawner!
// Fixes https://github.com/GeyserMC/Geyser/issues/4214 // Fixes https://github.com/GeyserMC/Geyser/issues/4214
CompoundTag spawnData = tag.get("SpawnData"); NbtMap spawnData = javaNbt.getCompound("SpawnData");
if (spawnData != null) { if (spawnData != null) {
CompoundTag entityTag = spawnData.get("entity"); NbtMap entityTag = spawnData.getCompound("entity");
if (entityTag.isEmpty()) { if (entityTag.isEmpty()) {
Vector3i position = Vector3i.from(x, y, z); Vector3i position = Vector3i.from(x, y, z);
// Set to air and back to reset the spawner - "just" updating the spawner doesn't work // Set to air and back to reset the spawner - "just" updating the spawner doesn't work
@ -66,62 +63,63 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator {
} }
} }
return super.getBlockEntityTag(session, type, x, y, z, tag, blockState); return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState);
} }
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
Tag current; Object current;
if ((current = tag.get("MaxNearbyEntities")) != null) { // TODO use primitive get and put methods
builder.put("MaxNearbyEntities", current.getValue()); if ((current = javaNbt.get("MaxNearbyEntities")) != null) {
bedrockNbt.put("MaxNearbyEntities", current);
} }
if ((current = tag.get("RequiredPlayerRange")) != null) { if ((current = javaNbt.get("RequiredPlayerRange")) != null) {
builder.put("RequiredPlayerRange", current.getValue()); bedrockNbt.put("RequiredPlayerRange", current);
} }
if ((current = tag.get("SpawnCount")) != null) { if ((current = javaNbt.get("SpawnCount")) != null) {
builder.put("SpawnCount", current.getValue()); bedrockNbt.put("SpawnCount", current);
} }
if ((current = tag.get("MaxSpawnDelay")) != null) { if ((current = javaNbt.get("MaxSpawnDelay")) != null) {
builder.put("MaxSpawnDelay", current.getValue()); bedrockNbt.put("MaxSpawnDelay", current);
} }
if ((current = tag.get("Delay")) != null) { if ((current = javaNbt.get("Delay")) != null) {
builder.put("Delay", current.getValue()); bedrockNbt.put("Delay", current);
} }
if ((current = tag.get("SpawnRange")) != null) { if ((current = javaNbt.get("SpawnRange")) != null) {
builder.put("SpawnRange", current.getValue()); bedrockNbt.put("SpawnRange", current);
} }
if ((current = tag.get("MinSpawnDelay")) != null) { if ((current = javaNbt.get("MinSpawnDelay")) != null) {
builder.put("MinSpawnDelay", current.getValue()); bedrockNbt.put("MinSpawnDelay", current);
} }
translateSpawnData(builder, tag.get("SpawnData")); translateSpawnData(bedrockNbt, javaNbt.getCompound("SpawnData", null));
builder.put("isMovable", (byte) 1); bedrockNbt.put("isMovable", (byte) 1);
} }
static void translateSpawnData(@NonNull NbtMapBuilder builder, @Nullable CompoundTag spawnData) { static void translateSpawnData(@NonNull NbtMapBuilder builder, @Nullable NbtMap spawnData) {
if (spawnData == null) { if (spawnData == null) {
return; return;
} }
CompoundTag entityTag = spawnData.get("entity"); NbtMap entityTag = spawnData.getCompound("entity");
if (entityTag.get("id") instanceof StringTag idTag) { String entityId = entityTag.getString("id");
if (entityId != null) {
// As of 1.19.3, spawners can be empty // As of 1.19.3, spawners can be empty
String entityId = idTag.getValue();
builder.put("EntityIdentifier", entityId); builder.put("EntityIdentifier", entityId);
EntityDefinition<?> definition = Registries.JAVA_ENTITY_IDENTIFIERS.get(entityId); EntityDefinition<?> definition = Registries.JAVA_ENTITY_IDENTIFIERS.get(entityId);
if (definition != null) { if (definition != null) {
builder.put("DisplayEntityWidth", definition.width()); builder.putFloat("DisplayEntityWidth", definition.width());
builder.put("DisplayEntityHeight", definition.height()); builder.putFloat("DisplayEntityHeight", definition.height());
builder.put("DisplayEntityScale", 1.0f); builder.putFloat("DisplayEntityScale", 1.0f);
} }
} }
} }

Datei anzeigen

@ -25,8 +25,6 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
@ -35,22 +33,23 @@ import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation;
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.StructureBlockUtils; import org.geysermc.geyser.util.StructureBlockUtils;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
@BlockEntity(type = BlockEntityType.STRUCTURE_BLOCK) @BlockEntity(type = BlockEntityType.STRUCTURE_BLOCK)
public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator { public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
@Override @Override
public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, CompoundTag tag, int blockState) { public NbtMap getBlockEntityTag(GeyserSession session, BlockEntityType type, int x, int y, int z, NbtMap javaNbt, int blockState) {
// Sending a structure with size 0 doesn't clear the outline. Hence, we have to force it by replacing the block :/ // Sending a structure with size 0 doesn't clear the outline. Hence, we have to force it by replacing the block :/
int xStructureSize = getOrDefault(tag.get("sizeX"), 0); int xStructureSize = javaNbt.getInt("sizeX");
int yStructureSize = getOrDefault(tag.get("sizeY"), 0); int yStructureSize = javaNbt.getInt("sizeY");
int zStructureSize = getOrDefault(tag.get("sizeZ"), 0); int zStructureSize = javaNbt.getInt("sizeZ");
Vector3i size = Vector3i.from(xStructureSize, yStructureSize, zStructureSize); Vector3i size = Vector3i.from(xStructureSize, yStructureSize, zStructureSize);
if (size.equals(Vector3i.ZERO)) { if (size.equals(Vector3i.ZERO)) {
Vector3i position = Vector3i.from(x, y, z); Vector3i position = Vector3i.from(x, y, z);
String mode = getOrDefault(tag.get("mode"), ""); String mode = javaNbt.getString("mode");
// Set to air and back to reset the structure block // Set to air and back to reset the structure block
UpdateBlockPacket emptyBlockPacket = new UpdateBlockPacket(); UpdateBlockPacket emptyBlockPacket = new UpdateBlockPacket();
@ -66,18 +65,18 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
session.sendUpstreamPacket(spawnerBlockPacket); session.sendUpstreamPacket(spawnerBlockPacket);
} }
return super.getBlockEntityTag(session, type, x, y, z, tag, blockState); return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState);
} }
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
if (tag.size() < 5) { if (javaNbt.size() < 5) {
return; // These values aren't here return; // These values aren't here
} }
builder.putString("structureName", getOrDefault(tag.get("name"), "")); bedrockNbt.putString("structureName", javaNbt.getString("name"));
String mode = getOrDefault(tag.get("mode"), ""); String mode = javaNbt.getString("mode");
int bedrockData = switch (mode) { int bedrockData = switch (mode) {
case "LOAD" -> 2; case "LOAD" -> 2;
case "CORNER" -> 3; case "CORNER" -> 3;
@ -85,53 +84,53 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
default -> 1; // SAVE default -> 1; // SAVE
}; };
builder.putInt("data", bedrockData); bedrockNbt.putInt("data", bedrockData);
builder.putString("dataField", ""); // ??? possibly related to Java's "metadata" bedrockNbt.putString("dataField", ""); // ??? possibly related to Java's "metadata"
// Mirror behaves different in Java and Bedrock - it requires modifying the position in space as well // Mirror behaves different in Java and Bedrock - it requires modifying the position in space as well
String mirror = getOrDefault(tag.get("mirror"), ""); String mirror = javaNbt.getString("mirror");
StructureMirror bedrockMirror = switch (mirror) { StructureMirror bedrockMirror = switch (mirror) {
case "FRONT_BACK" -> StructureMirror.X; case "FRONT_BACK" -> StructureMirror.X;
case "LEFT_RIGHT" -> StructureMirror.Z; case "LEFT_RIGHT" -> StructureMirror.Z;
default -> StructureMirror.NONE; default -> StructureMirror.NONE;
}; };
builder.putByte("mirror", (byte) bedrockMirror.ordinal()); bedrockNbt.putByte("mirror", (byte) bedrockMirror.ordinal());
builder.putByte("ignoreEntities", getOrDefault(tag.get("ignoreEntities"), (byte) 0)); bedrockNbt.putByte("ignoreEntities", javaNbt.getByte("ignoreEntities"));
builder.putByte("isPowered", getOrDefault(tag.get("powered"), (byte) 0)); bedrockNbt.putByte("isPowered", javaNbt.getByte("powered"));
builder.putLong("seed", getOrDefault(tag.get("seed"), 0L)); bedrockNbt.putLong("seed", javaNbt.getLong("seed"));
builder.putByte("showBoundingBox", getOrDefault(tag.get("showboundingbox"), (byte) 0)); bedrockNbt.putByte("showBoundingBox", javaNbt.getByte("showboundingbox"));
String rotation = getOrDefault(tag.get("rotation"), ""); String rotation = javaNbt.getString("rotation");
StructureRotation bedrockRotation = switch (rotation) { StructureRotation bedrockRotation = switch (rotation) {
case "CLOCKWISE_90" -> StructureRotation.ROTATE_90; case "CLOCKWISE_90" -> StructureRotation.ROTATE_90;
case "CLOCKWISE_180" -> StructureRotation.ROTATE_180; case "CLOCKWISE_180" -> StructureRotation.ROTATE_180;
case "COUNTERCLOCKWISE_90" -> StructureRotation.ROTATE_270; case "COUNTERCLOCKWISE_90" -> StructureRotation.ROTATE_270;
default -> StructureRotation.NONE; default -> StructureRotation.NONE;
}; };
builder.putByte("rotation", (byte) bedrockRotation.ordinal()); bedrockNbt.putByte("rotation", (byte) bedrockRotation.ordinal());
int xStructureSize = getOrDefault(tag.get("sizeX"), 0); int xStructureSize = javaNbt.getInt("sizeX");
int yStructureSize = getOrDefault(tag.get("sizeY"), 0); int yStructureSize = javaNbt.getInt("sizeY");
int zStructureSize = getOrDefault(tag.get("sizeZ"), 0); int zStructureSize = javaNbt.getInt("sizeZ");
// The "positions" are also offsets on Java // The "positions" are also offsets on Java
int posX = getOrDefault(tag.get("posX"), 0); int posX = javaNbt.getInt("posX");
int posY = getOrDefault(tag.get("posY"), 0); int posY = javaNbt.getInt("posY");
int posZ = getOrDefault(tag.get("posZ"), 0); int posZ = javaNbt.getInt("posZ");
Vector3i offset = StructureBlockUtils.calculateOffset(bedrockRotation, bedrockMirror, Vector3i offset = StructureBlockUtils.calculateOffset(bedrockRotation, bedrockMirror,
xStructureSize, zStructureSize); xStructureSize, zStructureSize);
builder.putInt("xStructureOffset", posX + offset.getX()); bedrockNbt.putInt("xStructureOffset", posX + offset.getX());
builder.putInt("yStructureOffset", posY); bedrockNbt.putInt("yStructureOffset", posY);
builder.putInt("zStructureOffset", posZ + offset.getZ()); bedrockNbt.putInt("zStructureOffset", posZ + offset.getZ());
builder.putInt("xStructureSize", xStructureSize); bedrockNbt.putInt("xStructureSize", xStructureSize);
builder.putInt("yStructureSize", yStructureSize); bedrockNbt.putInt("yStructureSize", yStructureSize);
builder.putInt("zStructureSize", zStructureSize); bedrockNbt.putInt("zStructureSize", zStructureSize);
builder.putFloat("integrity", getOrDefault(tag.get("integrity"), 0f)); // Is 1.0f by default on Java but 100.0f on Bedrock bedrockNbt.putFloat("integrity", javaNbt.getFloat("integrity")); // Is 1.0f by default on Java but 100.0f on Bedrock
// Java's "showair" is unrepresented // Java's "showair" is unrepresented
} }

Datei anzeigen

@ -25,23 +25,24 @@
package org.geysermc.geyser.translator.level.block.entity; package org.geysermc.geyser.translator.level.block.entity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtMapBuilder;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType; import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
@BlockEntity(type = BlockEntityType.TRIAL_SPAWNER) @BlockEntity(type = BlockEntityType.TRIAL_SPAWNER)
public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator { public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator {
@Override @Override
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
if (tag == null) { if (javaNbt == null) {
return; return;
} }
// trial spawners have "spawn_data" instead of "SpawnData" // trial spawners have "spawn_data" instead of "SpawnData"
SpawnerBlockEntityTranslator.translateSpawnData(builder, tag.get("spawn_data")); SpawnerBlockEntityTranslator.translateSpawnData(bedrockNbt, javaNbt.getCompound("spawn_data", null));
// Because trial spawners don't exist on bedrock yet // Because trial spawners don't exist on bedrock yet
builder.put("id", "MobSpawner"); bedrockNbt.put("id", "MobSpawner");
} }
} }

Datei anzeigen

@ -25,9 +25,8 @@
package org.geysermc.geyser.translator.protocol.java.level; package org.geysermc.geyser.translator.protocol.java.level;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror; import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror;
@ -71,7 +70,7 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
packet.getNbt(), blockState), packet.getPosition()); packet.getNbt(), blockState), packet.getPosition());
// Check for custom skulls. // Check for custom skulls.
boolean hasCustomHeadBlock = false; boolean hasCustomHeadBlock = false;
if (session.getPreferencesCache().showCustomSkulls() && packet.getNbt() != null && packet.getNbt().contains("profile")) { if (session.getPreferencesCache().showCustomSkulls() && packet.getNbt() != null && packet.getNbt().containsKey("profile")) {
BlockDefinition blockDefinition = SkullBlockEntityTranslator.translateSkull(session, packet.getNbt(), position, blockState); BlockDefinition blockDefinition = SkullBlockEntityTranslator.translateSkull(session, packet.getNbt(), position, blockState);
if (blockDefinition != null) { if (blockDefinition != null) {
hasCustomHeadBlock = true; hasCustomHeadBlock = true;
@ -107,21 +106,21 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
&& packet.getPosition().equals(session.getStructureBlockCache().getCurrentStructureBlock()) && packet.getPosition().equals(session.getStructureBlockCache().getCurrentStructureBlock())
&& packet.getNbt() != null && packet.getNbt().size() > 5 && packet.getNbt() != null && packet.getNbt().size() > 5
) { ) {
CompoundTag map = packet.getNbt(); NbtMap map = packet.getNbt();
String mode = getOrDefault(map.get("mode"), ""); String mode = map.getString("mode");
if (!mode.equalsIgnoreCase("LOAD")) { if (!mode.equalsIgnoreCase("LOAD")) {
return; return;
} }
String mirror = getOrDefault(map.get("mirror"), ""); String mirror = map.getString("mirror");
StructureMirror bedrockMirror = switch (mirror) { StructureMirror bedrockMirror = switch (mirror) {
case "FRONT_BACK" -> StructureMirror.X; case "FRONT_BACK" -> StructureMirror.X;
case "LEFT_RIGHT" -> StructureMirror.Z; case "LEFT_RIGHT" -> StructureMirror.Z;
default -> StructureMirror.NONE; default -> StructureMirror.NONE;
}; };
String rotation = getOrDefault(map.get("rotation"), ""); String rotation = map.getString("rotation");
StructureRotation bedrockRotation = switch (rotation) { StructureRotation bedrockRotation = switch (rotation) {
case "CLOCKWISE_90" -> StructureRotation.ROTATE_90; case "CLOCKWISE_90" -> StructureRotation.ROTATE_90;
case "CLOCKWISE_180" -> StructureRotation.ROTATE_180; case "CLOCKWISE_180" -> StructureRotation.ROTATE_180;
@ -129,10 +128,10 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
default -> StructureRotation.NONE; default -> StructureRotation.NONE;
}; };
String name = getOrDefault(map.get("name"), ""); String name = map.getString("name");
int sizeX = getOrDefault(map.get("sizeX"), 0); int sizeX = map.getInt("sizeX");
int sizeY = getOrDefault(map.get("sizeY"), 0); int sizeY = map.getInt("sizeY");
int sizeZ = getOrDefault(map.get("sizeZ"), 0); int sizeZ = map.getInt("sizeZ");
session.getStructureBlockCache().setCurrentStructureBlock(null); session.getStructureBlockCache().setCurrentStructureBlock(null);
@ -149,10 +148,4 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
StructureBlockUtils.sendStructureData(session, size, name); StructureBlockUtils.sendStructureData(session, size, name);
} }
} }
protected <T> T getOrDefault(Tag tag, T defaultValue) {
//noinspection unchecked
return (tag != null && tag.getValue() != null) ? (T) tag.getValue() : defaultValue;
}
} }

Datei anzeigen

@ -25,7 +25,6 @@
package org.geysermc.geyser.translator.protocol.java.level; package org.geysermc.geyser.translator.protocol.java.level;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.ByteBufOutputStream;
@ -385,7 +384,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
final int chunkBlockZ = packet.getZ() << 4; final int chunkBlockZ = packet.getZ() << 4;
for (BlockEntityInfo blockEntity : blockEntities) { for (BlockEntityInfo blockEntity : blockEntities) {
BlockEntityType type = blockEntity.getType(); BlockEntityType type = blockEntity.getType();
CompoundTag tag = blockEntity.getNbt(); NbtMap tag = blockEntity.getNbt();
if (type == null) { if (type == null) {
// As an example: ViaVersion will send -1 if it cannot find the block entity type // As an example: ViaVersion will send -1 if it cannot find the block entity type
// Vanilla Minecraft gracefully handles this // Vanilla Minecraft gracefully handles this
@ -422,7 +421,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
} }
// Check for custom skulls // Check for custom skulls
if (session.getPreferencesCache().showCustomSkulls() && type == BlockEntityType.SKULL && tag != null && tag.contains("profile")) { if (session.getPreferencesCache().showCustomSkulls() && type == BlockEntityType.SKULL && tag != null && tag.containsKey("profile")) {
BlockDefinition blockDefinition = SkullBlockEntityTranslator.translateSkull(session, tag, Vector3i.from(x + chunkBlockX, y, z + chunkBlockZ), blockState); BlockDefinition blockDefinition = SkullBlockEntityTranslator.translateSkull(session, tag, Vector3i.from(x + chunkBlockX, y, z + chunkBlockZ), blockState);
if (blockDefinition != null) { if (blockDefinition != null) {
int bedrockSectionY = (y >> 4) - (bedrockDimension.minY() >> 4); int bedrockSectionY = (y >> 4) - (bedrockDimension.minY() >> 4);

Datei anzeigen

@ -25,16 +25,12 @@
package org.geysermc.geyser.translator.sound; package org.geysermc.geyser.translator.sound;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
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 com.github.steveice10.opennbt.tag.builtin.Tag;
import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3f;
import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.registry.Registries; import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.BlockUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import java.util.Map; import java.util.Map;
@ -104,25 +100,14 @@ public interface BlockSoundInteractionTranslator extends SoundInteractionTransla
return true; return true;
} }
CompoundTag tag = itemInHand.getNbt(); var canPlaceOn = itemInHand.getComponent(DataComponentType.CAN_PLACE_ON);
if (tag == null) { if (canPlaceOn == null || canPlaceOn.getPredicates().isEmpty()) {
// No CanPlaceOn tag can exist // Component doesn't exist - no restrictions apply.
return false; return true;
}
ListTag canPlaceOn = tag.get("CanPlaceOn");
if (canPlaceOn == null || canPlaceOn.size() == 0) {
return false;
} }
String cleanIdentifier = BlockUtils.getCleanIdentifier(blockIdentifier); for (var blockPredicate : canPlaceOn.getPredicates()) {
// I don't want to deal with this right now. TODO
for (Tag t : canPlaceOn) {
if (t instanceof StringTag stringTag) {
if (cleanIdentifier.equals(stringTag.getValue())) {
// This operation would/could be a success!
return true;
}
}
} }
// The block in world is not present in the CanPlaceOn tag on the item // The block in world is not present in the CanPlaceOn tag on the item

Datei anzeigen

@ -187,14 +187,28 @@ public class MessageTranslator {
} }
} }
/**
* Convenience method for locale getting.
*/
public static String convertJsonMessage(GeyserSession session, String message) {
return convertJsonMessage(message, session.locale());
}
public static String convertJsonMessage(String message, String locale) { public static String convertJsonMessage(String message, String locale) {
return convertMessage(GSON_SERIALIZER.deserialize(message), locale); return convertMessage(GSON_SERIALIZER.deserialize(message), locale);
} }
public static String convertJsonMessage(String message) { /**
return convertJsonMessage(message, GeyserLocale.getDefaultLocale()); * Convenience method for locale getting.
*/
public static String convertMessage(GeyserSession session, Component message) {
return convertMessage(message, session.locale());
} }
/**
* DO NOT USE THIS METHOD unless where you're calling from does not have a (reliable) way of getting the
* context's locale.
*/
public static String convertMessage(Component message) { public static String convertMessage(Component message) {
return convertMessage(message, GeyserLocale.getDefaultLocale()); return convertMessage(message, GeyserLocale.getDefaultLocale());
} }

Datei anzeigen

@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128"
raknet = "1.0.0.CR3-20240416.144209-1" raknet = "1.0.0.CR3-20240416.144209-1"
blockstateupdater="1.20.80-20240411.142413-1" blockstateupdater="1.20.80-20240411.142413-1"
mcauthlib = "d9d773e" mcauthlib = "d9d773e"
mcprotocollib = "1ca8808" # Revert from jitpack after release mcprotocollib = "98410a1" # Revert from jitpack after release
adventure = "4.14.0" adventure = "4.14.0"
adventure-platform = "4.3.0" adventure-platform = "4.3.0"
junit = "5.9.2" junit = "5.9.2"