Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-25 15:50:14 +01:00
Switch to Cloudburst NBT only
Dieser Commit ist enthalten in:
Ursprung
16cb76f523
Commit
2fa7585db3
@ -45,7 +45,6 @@ import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
|
||||
import org.geysermc.api.Geyser;
|
||||
import org.geysermc.cumulus.form.Form;
|
||||
import org.geysermc.cumulus.form.util.FormBuilder;
|
||||
import org.geysermc.erosion.packet.Packets;
|
||||
import org.geysermc.floodgate.crypto.AesCipher;
|
||||
import org.geysermc.floodgate.crypto.AesKeyProducer;
|
||||
import org.geysermc.floodgate.crypto.Base64Topping;
|
||||
@ -384,7 +383,7 @@ public class GeyserImpl implements GeyserApi {
|
||||
|
||||
this.newsHandler = new NewsHandler(BRANCH, this.buildNumber());
|
||||
|
||||
Packets.initGeyser();
|
||||
//Packets.initGeyser();
|
||||
|
||||
if (Epoll.isAvailable()) {
|
||||
this.erosionUnixListener = new UnixSocketClientListener();
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
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.Getter;
|
||||
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.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -194,9 +193,9 @@ public class LivingEntity extends Entity {
|
||||
/**
|
||||
* 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) {
|
||||
CompoundTag nbt = itemStack.getNbt();
|
||||
if (nbt != null && nbt.get("display") instanceof CompoundTag displayTag && displayTag.get("Name") instanceof StringTag) {
|
||||
if (itemStack.getComponent(DataComponentType.CUSTOM_NAME) != null) {
|
||||
// The mob shall be named
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
@ -25,14 +25,14 @@
|
||||
|
||||
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.Setter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
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.AbilityLayer;
|
||||
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);
|
||||
}
|
||||
|
||||
public void setLeftParrot(EntityMetadata<CompoundTag, ?> entityMetadata) {
|
||||
public void setLeftParrot(EntityMetadata<NbtMap, ?> entityMetadata) {
|
||||
setParrot(entityMetadata.getValue(), true);
|
||||
}
|
||||
|
||||
public void setRightParrot(EntityMetadata<CompoundTag, ?> entityMetadata) {
|
||||
public void setRightParrot(EntityMetadata<NbtMap, ?> entityMetadata) {
|
||||
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
|
||||
* 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 ((isLeft && leftParrot != null) || (!isLeft && rightParrot != null)) {
|
||||
// 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(),
|
||||
null, EntityDefinitions.PARROT, position, motion, getYaw(), getPitch(), getHeadYaw());
|
||||
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
|
||||
float offset = isLeft ? 0.4f : -0.4f;
|
||||
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) {
|
||||
numberString = MessageTranslator.convertMessage(fixedFormat.getValue());
|
||||
} else if (numberFormat instanceof StyledFormat styledFormat) {
|
||||
CompoundTag styledAmount = styledFormat.getStyle().clone();
|
||||
styledAmount.put(new StringTag("text", String.valueOf(amount)));
|
||||
NbtMapBuilder styledAmount = styledFormat.getStyle().toBuilder();
|
||||
styledAmount.putString("text", String.valueOf(amount));
|
||||
|
||||
numberString = MessageTranslator.convertJsonMessage(
|
||||
NbtComponentSerializer.tagComponentToJson(styledAmount).toString());
|
||||
NbtComponentSerializer.tagComponentToJson(styledAmount.build()).toString(), session.locale());
|
||||
} else {
|
||||
numberString = String.valueOf(amount);
|
||||
}
|
||||
|
@ -25,11 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.inventory;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.*;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
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.DataComponents;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@Data
|
||||
public class GeyserItemStack {
|
||||
public static final GeyserItemStack EMPTY = new GeyserItemStack(Items.AIR_ID, 0, null);
|
||||
@ -52,7 +50,7 @@ public class GeyserItemStack {
|
||||
private DataComponents components;
|
||||
private int netId;
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE)
|
||||
@EqualsAndHashCode.Exclude
|
||||
private Item item;
|
||||
|
||||
@ -67,6 +65,14 @@ public class GeyserItemStack {
|
||||
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) {
|
||||
return itemStack == null ? EMPTY : new GeyserItemStack(itemStack.getId(), itemStack.getAmount(), itemStack.getDataComponents());
|
||||
}
|
||||
@ -79,16 +85,27 @@ public class GeyserItemStack {
|
||||
return isEmpty() ? 0 : amount;
|
||||
}
|
||||
|
||||
public @Nullable CompoundTag getNbt() {
|
||||
Thread.dumpStack();
|
||||
return null;
|
||||
}
|
||||
|
||||
public @Nullable DataComponents getComponents() {
|
||||
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) {
|
||||
return def;
|
||||
}
|
||||
@ -100,7 +117,7 @@ public class GeyserItemStack {
|
||||
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) {
|
||||
return def;
|
||||
}
|
||||
|
@ -25,9 +25,6 @@
|
||||
|
||||
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.Setter;
|
||||
import lombok.ToString;
|
||||
@ -39,6 +36,7 @@ import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
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 java.util.Arrays;
|
||||
@ -137,12 +135,9 @@ public abstract class Inventory {
|
||||
|
||||
// Lodestone caching
|
||||
if (newItem.asItem() == Items.COMPASS) {
|
||||
CompoundTag nbt = newItem.getNbt();
|
||||
if (nbt != null) {
|
||||
Tag lodestoneTag = nbt.get("LodestoneTracked");
|
||||
if (lodestoneTag instanceof ByteTag) {
|
||||
session.getLodestoneCache().cacheInventoryItem(newItem);
|
||||
}
|
||||
var tracker = newItem.getComponent(DataComponentType.LODESTONE_TRACKER);
|
||||
if (tracker != null) {
|
||||
session.getLodestoneCache().cacheInventoryItem(newItem, tracker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,10 @@
|
||||
|
||||
package org.geysermc.geyser.inventory.item;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
||||
import lombok.Getter;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@ -85,6 +87,10 @@ public enum Potion {
|
||||
this.bedrockId = (short) bedrockId;
|
||||
}
|
||||
|
||||
public PotionContents toComponent() {
|
||||
return new PotionContents(this.ordinal(), -1, Int2ObjectMaps.emptyMap());
|
||||
}
|
||||
|
||||
public static @Nullable Potion getByJavaIdentifier(String javaIdentifier) {
|
||||
for (Potion potion : VALUES) {
|
||||
if (potion.javaIdentifier.equals(javaIdentifier)) {
|
||||
|
@ -25,9 +25,6 @@
|
||||
|
||||
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.format.TextColor;
|
||||
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.session.GeyserSession;
|
||||
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.
|
||||
@ -54,11 +52,11 @@ public final class TrimRecipe {
|
||||
// Color is used when hovering over the item
|
||||
// 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!!!!!
|
||||
StringTag colorTag = ((CompoundTag) entry.getData().get("description")).get("color");
|
||||
TextColor color = TextColor.fromHexString(colorTag.getValue());
|
||||
String colorTag = entry.getData().getCompound("description").getString("color");
|
||||
TextColor color = TextColor.fromHexString(colorTag);
|
||||
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);
|
||||
if (itemMapping == null) {
|
||||
// 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) {
|
||||
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);
|
||||
if (itemMapping == null) {
|
||||
// This should never happen so not sure what to do here.
|
||||
|
@ -25,13 +25,6 @@
|
||||
|
||||
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.Object2IntMaps;
|
||||
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.text.MessageTranslator;
|
||||
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;
|
||||
|
||||
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) {
|
||||
boolean hasCompatible = false;
|
||||
Object2IntMap<JavaEnchantment> combinedEnchantments = getEnchantments(input, bedrock);
|
||||
Object2IntMap<JavaEnchantment> combinedEnchantments = getEnchantments(input);
|
||||
int cost = 0;
|
||||
for (Object2IntMap.Entry<JavaEnchantment> entry : getEnchantments(material, bedrock).object2IntEntrySet()) {
|
||||
for (Object2IntMap.Entry<JavaEnchantment> entry : getEnchantments(material).object2IntEntrySet()) {
|
||||
JavaEnchantment enchantment = entry.getKey();
|
||||
EnchantmentData data = Registries.ENCHANTMENTS.get(enchantment);
|
||||
if (data == null) {
|
||||
@ -371,42 +369,26 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
|
||||
return cost;
|
||||
}
|
||||
|
||||
private Object2IntMap<JavaEnchantment> getEnchantments(GeyserItemStack itemStack, boolean bedrock) {
|
||||
if (itemStack.getNbt() == null) {
|
||||
return Object2IntMaps.emptyMap();
|
||||
}
|
||||
Object2IntMap<JavaEnchantment> enchantments = new Object2IntOpenHashMap<>();
|
||||
Tag enchantmentTag;
|
||||
private Object2IntMap<JavaEnchantment> getEnchantments(GeyserItemStack itemStack) {
|
||||
ItemEnchantments enchantmentComponent;
|
||||
if (isEnchantedBook(itemStack)) {
|
||||
enchantmentTag = itemStack.getNbt().get("StoredEnchantments");
|
||||
enchantmentComponent = itemStack.getComponent(DataComponentType.STORED_ENCHANTMENTS);
|
||||
} else {
|
||||
enchantmentTag = itemStack.getNbt().get("Enchantments");
|
||||
enchantmentComponent = itemStack.getComponent(DataComponentType.ENCHANTMENTS);
|
||||
}
|
||||
if (enchantmentTag instanceof ListTag listTag) {
|
||||
for (Tag tag : listTag.getValue()) {
|
||||
if (tag instanceof CompoundTag enchantTag) {
|
||||
if (enchantTag.get("id") instanceof StringTag javaEnchId) {
|
||||
JavaEnchantment enchantment = JavaEnchantment.getByJavaIdentifier(javaEnchId.getValue());
|
||||
if (enchantment == null) {
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + javaEnchId.getValue());
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (enchantmentComponent != null) {
|
||||
Object2IntMap<JavaEnchantment> enchantments = new Object2IntOpenHashMap<>();
|
||||
for (Map.Entry<Integer, Integer> entry : enchantmentComponent.getEnchantments().entrySet()) {
|
||||
JavaEnchantment enchantment = JavaEnchantment.of(entry.getKey());
|
||||
if (enchantment == null) {
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + entry.getKey());
|
||||
continue;
|
||||
}
|
||||
enchantments.put(enchantment, entry.getValue().intValue());
|
||||
}
|
||||
return enchantments;
|
||||
}
|
||||
return enchantments;
|
||||
return Object2IntMaps.emptyMap();
|
||||
}
|
||||
|
||||
private boolean isEnchantedBook(GeyserItemStack itemStack) {
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
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.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
@ -41,17 +39,4 @@ public interface DyeableLeatherItem {
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
@ -25,15 +25,12 @@
|
||||
|
||||
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.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.TrimMaterial;
|
||||
import org.cloudburstmc.protocol.bedrock.data.TrimPattern;
|
||||
import org.geysermc.geyser.item.ArmorMaterial;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
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
|
||||
public boolean isValidRepairItem(Item other) {
|
||||
return material.getRepairIngredient() == other;
|
||||
|
@ -25,14 +25,16 @@
|
||||
|
||||
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.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.item.TippedArrowPotion;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
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 ArrowItem(String javaIdentifier, Builder builder) {
|
||||
@ -40,13 +42,13 @@ public class ArrowItem extends Item {
|
||||
}
|
||||
|
||||
@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());
|
||||
ItemStack itemStack = super.translateToJava(itemData, mapping, mappings);
|
||||
GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings);
|
||||
if (tippedArrowPotion != null) {
|
||||
itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getDataComponents());
|
||||
StringTag potionTag = new StringTag("Potion", tippedArrowPotion.getJavaIdentifier());
|
||||
//itemStack.getDataComponents().put(DataComponentType.POTION_CONTENTS, new PotionContents());
|
||||
itemStack = Items.TIPPED_ARROW.newItemStack(itemStack.getAmount(), itemStack.getComponents());
|
||||
PotionContents contents = new PotionContents(tippedArrowPotion.ordinal(), -1, Int2ObjectMaps.emptyMap());
|
||||
itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, contents);
|
||||
}
|
||||
return itemStack;
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
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.
|
||||
*/
|
||||
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 {
|
||||
// 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)
|
||||
);
|
||||
|
||||
OMINOUS_BANNER_PATTERN_BLOCK = new ListTag("patterns");
|
||||
OMINOUS_BANNER_PATTERN_BLOCK = new ArrayList<>();
|
||||
for (Pair<BannerPattern, DyeColor> pair : OMINOUS_BANNER_PATTERN) {
|
||||
OMINOUS_BANNER_PATTERN_BLOCK.add(getJavaBannerPatternTag(pair.left(), pair.right()));
|
||||
}
|
||||
@ -92,7 +91,7 @@ public class BannerItem extends BlockItem {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isOminous(ListTag blockEntityPatterns) {
|
||||
public static boolean isOminous(List<NbtMap> blockEntityPatterns) {
|
||||
return OMINOUS_BANNER_PATTERN_BLOCK.equals(blockEntityPatterns);
|
||||
}
|
||||
|
||||
@ -102,10 +101,10 @@ public class BannerItem extends BlockItem {
|
||||
* @param patterns The patterns to convert
|
||||
* @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<>();
|
||||
for (Tag patternTag : patterns.getValue()) {
|
||||
NbtMap bedrockBannerPattern = getBedrockBannerPattern((CompoundTag) patternTag);
|
||||
for (NbtMap patternTag : patterns) {
|
||||
NbtMap bedrockBannerPattern = getBedrockBannerPattern(patternTag);
|
||||
if (bedrockBannerPattern != null) {
|
||||
tagsList.add(bedrockBannerPattern);
|
||||
}
|
||||
@ -120,9 +119,9 @@ public class BannerItem extends BlockItem {
|
||||
* @param pattern Java edition pattern nbt
|
||||
* @return The Bedrock edition format pattern nbt
|
||||
*/
|
||||
private static NbtMap getBedrockBannerPattern(CompoundTag pattern) {
|
||||
BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier((String) pattern.get("pattern").getValue());
|
||||
DyeColor dyeColor = DyeColor.getByJavaIdentifier((String) pattern.get("color").getValue());
|
||||
private static NbtMap getBedrockBannerPattern(NbtMap pattern) {
|
||||
BannerPattern bannerPattern = BannerPattern.getByJavaIdentifier(pattern.getString("pattern"));
|
||||
DyeColor dyeColor = DyeColor.getByJavaIdentifier(pattern.getString("color"));
|
||||
if (bannerPattern == null || dyeColor == null) {
|
||||
return null;
|
||||
}
|
||||
@ -133,11 +132,11 @@ public class BannerItem extends BlockItem {
|
||||
.build();
|
||||
}
|
||||
|
||||
public static CompoundTag getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) {
|
||||
CompoundTag tag = new CompoundTag("");
|
||||
tag.put(new StringTag("pattern", bannerPattern.getJavaIdentifier()));
|
||||
tag.put(new StringTag("color", dyeColor.getJavaIdentifier()));
|
||||
return tag;
|
||||
public static NbtMap getJavaBannerPatternTag(BannerPattern bannerPattern, DyeColor dyeColor) {
|
||||
return NbtMap.builder()
|
||||
.putString("pattern", bannerPattern.getJavaIdentifier())
|
||||
.putString("color", dyeColor.getJavaIdentifier())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,31 +189,14 @@ public class BannerItem extends BlockItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) { // TODO
|
||||
super.translateNbtToJava(tag, mapping);
|
||||
public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) { // TODO
|
||||
super.translateNbtToJava(bedrockTag, components, mapping);
|
||||
|
||||
if (tag.get("Type") instanceof IntTag type && type.getValue() == 1) {
|
||||
if (bedrockTag.getInt("Type") == 1) {
|
||||
// Ominous banner pattern
|
||||
tag.remove("Type");
|
||||
CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag");
|
||||
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
|
||||
// TODO more registry stuff
|
||||
//components.put(DataComponentType.BANNER_PATTERNS);
|
||||
}
|
||||
// Bedrock's creative inventory does not support other patterns as of 1.20.5
|
||||
}
|
||||
}
|
||||
|
@ -28,11 +28,11 @@ package org.geysermc.geyser.item.type;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
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.ItemMappings;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
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.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.LodestoneTracker;
|
||||
@ -78,7 +78,7 @@ public class CompassItem extends Item {
|
||||
}
|
||||
|
||||
@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")) {
|
||||
// Revert the entry back to the compass
|
||||
mapping = mappings.getStoredItems().compass();
|
||||
|
@ -25,10 +25,6 @@
|
||||
|
||||
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.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
@ -63,22 +59,4 @@ public class CrossbowItem extends Item {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,11 +25,9 @@
|
||||
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.item.ArmorMaterial;
|
||||
import org.geysermc.geyser.item.DyeableLeatherItem;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
|
||||
super.translateNbtToJava(tag, mapping);
|
||||
|
||||
DyeableLeatherItem.translateNbtToJava(tag);
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,8 @@
|
||||
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.item.DyeableLeatherItem;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
|
||||
super.translateNbtToJava(tag, mapping);
|
||||
|
||||
DyeableLeatherItem.translateNbtToJava(tag);
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,14 @@
|
||||
|
||||
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.cloudburstmc.nbt.NbtMap;
|
||||
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.translator.item.BedrockItemBuilder;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,7 @@
|
||||
|
||||
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.IntArrayTag;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrays;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
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.session.GeyserSession;
|
||||
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.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Fireworks;
|
||||
@ -73,8 +70,23 @@ public class FireworkRocketItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
|
||||
super.translateNbtToJava(tag, mapping);
|
||||
public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping 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) {
|
||||
@ -111,45 +123,22 @@ public class FireworkRocketItem extends Item {
|
||||
return newExplosionData.build();
|
||||
}
|
||||
|
||||
static CompoundTag translateExplosionToJava(CompoundTag explosion, String newName) {
|
||||
CompoundTag newExplosionData = new CompoundTag(newName);
|
||||
|
||||
if (explosion.get("FireworkType") != null) {
|
||||
newExplosionData.put(new ByteTag("Type", MathUtils.getNbtByte(explosion.get("FireworkType").getValue())));
|
||||
}
|
||||
|
||||
if (explosion.get("FireworkColor") != null) {
|
||||
byte[] oldColors = (byte[]) explosion.get("FireworkColor").getValue();
|
||||
int[] colors = new int[oldColors.length];
|
||||
/**
|
||||
* The only thing that the Bedrock creative inventory has - as of 1.20.80 - is color.
|
||||
*/
|
||||
static Fireworks.FireworkExplosion translateExplosionToJava(NbtMap explosion) {
|
||||
byte[] javaColors = explosion.getByteArray("FireworkColor", null);
|
||||
if (javaColors != null) {
|
||||
int[] colors = new int[javaColors.length];
|
||||
|
||||
int i = 0;
|
||||
for (byte color : oldColors) {
|
||||
for (byte color : javaColors) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
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.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
@ -80,15 +78,16 @@ public class FireworkStarItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
|
||||
super.translateNbtToJava(tag, mapping);
|
||||
public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) {
|
||||
super.translateNbtToJava(bedrockTag, components, mapping);
|
||||
|
||||
Tag explosion = tag.remove("FireworksItem");
|
||||
if (explosion instanceof CompoundTag) {
|
||||
CompoundTag newExplosion = FireworkRocketItem.translateExplosionToJava((CompoundTag) explosion, "Explosion");
|
||||
tag.put(newExplosion);
|
||||
NbtMap explosion = bedrockTag.getCompound("FireworksItem");
|
||||
if (!explosion.isEmpty()) {
|
||||
Fireworks.FireworkExplosion newExplosion = FireworkRocketItem.translateExplosionToJava(explosion);
|
||||
if (newExplosion == null) {
|
||||
return;
|
||||
}
|
||||
components.put(DataComponentType.FIREWORK_EXPLOSION, newExplosion);
|
||||
}
|
||||
// Remove custom color, if any, since this only exists on Bedrock
|
||||
tag.remove("customColor");
|
||||
}
|
||||
}
|
||||
|
@ -25,14 +25,12 @@
|
||||
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
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.ItemMappings;
|
||||
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.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Instrument;
|
||||
@ -80,18 +78,11 @@ public class GoatHornItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
|
||||
ItemStack itemStack = super.translateToJava(itemData, mapping, mappings);
|
||||
public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
|
||||
GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings);
|
||||
|
||||
int damage = itemData.getDamage();
|
||||
if (damage < 0 || damage >= INSTRUMENTS.size()) {
|
||||
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);
|
||||
itemStack.getOrCreateComponents().put(DataComponentType.INSTRUMENT, Holder.ofId(damage));
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
@ -33,6 +32,7 @@ import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
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.text.MessageTranslator;
|
||||
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.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
|
||||
@ -108,11 +107,8 @@ public class Item {
|
||||
return builder;
|
||||
}
|
||||
|
||||
public @NonNull ItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
|
||||
if (itemData.getTag() == null) {
|
||||
return new ItemStack(javaId, itemData.getCount(), null);
|
||||
}
|
||||
return new ItemStack(javaId, itemData.getCount(), null/*ItemTranslator.translateToJavaNBT("", itemData.getTag())*/);
|
||||
public @NonNull GeyserItemStack translateToJava(@NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
|
||||
return GeyserItemStack.of(javaId, itemData.getCount());
|
||||
}
|
||||
|
||||
public ItemMapping toBedrockDefinition(DataComponents components, ItemMappings mappings) {
|
||||
@ -162,57 +158,60 @@ public class Item {
|
||||
* </ul>
|
||||
* Therefore, if translation cannot be achieved for a certain item, it is not necessarily bad.
|
||||
*/
|
||||
public void translateNbtToJava(@NonNull CompoundTag tag, @NonNull ItemMapping mapping) {
|
||||
CompoundTag displayTag = tag.get("display");
|
||||
if (displayTag != null) {
|
||||
if (displayTag.contains("Name")) {
|
||||
StringTag nameTag = displayTag.get("Name");
|
||||
displayTag.put(new StringTag("Name", MessageTranslator.convertToJavaMessage(nameTag.getValue())));
|
||||
}
|
||||
public void translateNbtToJava(@NonNull NbtMap bedrockTag, @NonNull DataComponents components, @NonNull ItemMapping mapping) {
|
||||
// TODO see if any items from the creative menu need this
|
||||
// CompoundTag displayTag = tag.get("display");
|
||||
// if (displayTag != null) {
|
||||
// if (displayTag.contains("Name")) {
|
||||
// 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")) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
ListTag enchantmentTag = tag.remove("ench");
|
||||
if (enchantmentTag != null) {
|
||||
List<Tag> enchantments = new ArrayList<>();
|
||||
for (Tag value : enchantmentTag.getValue()) {
|
||||
if (!(value instanceof CompoundTag tagValue))
|
||||
continue;
|
||||
|
||||
ShortTag bedrockId = tagValue.get("id");
|
||||
if (bedrockId == null) continue;
|
||||
|
||||
Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue());
|
||||
if (enchantment != null) {
|
||||
CompoundTag javaTag = new CompoundTag("");
|
||||
Map<String, Tag> javaValue = javaTag.getValue();
|
||||
javaValue.put("id", new StringTag("id", enchantment.getJavaIdentifier()));
|
||||
ShortTag levelTag = tagValue.get("lvl");
|
||||
javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1));
|
||||
javaTag.setValue(javaValue);
|
||||
|
||||
enchantments.add(javaTag);
|
||||
} 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO no creative item should have enchantments *except* enchanted books
|
||||
// List<NbtMap> enchantmentTag = bedrockTag.getList("ench", NbtType.COMPOUND);
|
||||
// if (enchantmentTag != null) {
|
||||
// List<Tag> enchantments = new ArrayList<>();
|
||||
// for (Tag value : enchantmentTag.getValue()) {
|
||||
// if (!(value instanceof CompoundTag tagValue))
|
||||
// continue;
|
||||
//
|
||||
// ShortTag bedrockId = tagValue.get("id");
|
||||
// if (bedrockId == null) continue;
|
||||
//
|
||||
// Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue());
|
||||
// if (enchantment != null) {
|
||||
// CompoundTag javaTag = new CompoundTag("");
|
||||
// Map<String, Tag> javaValue = javaTag.getValue();
|
||||
// javaValue.put("id", new StringTag("id", enchantment.getJavaIdentifier()));
|
||||
// ShortTag levelTag = tagValue.get("lvl");
|
||||
// javaValue.put("lvl", new IntTag("lvl", levelTag != null ? levelTag.getValue() : 1));
|
||||
// javaTag.setValue(javaValue);
|
||||
//
|
||||
// enchantments.add(javaTag);
|
||||
// } else {
|
||||
// GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId);
|
||||
// }
|
||||
// }
|
||||
// if (!enchantments.isEmpty()) {
|
||||
// if ((this instanceof EnchantedBookItem)) {
|
||||
// bedrockTag.put(new ListTag("StoredEnchantments", enchantments));
|
||||
// components.put(DataComponentType.STORED_ENCHANTMENTS, enchantments);
|
||||
// } else {
|
||||
// components.put(DataComponentType.ENCHANTMENTS, enchantments);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
protected final @Nullable NbtMap remapEnchantment(GeyserSession session, int enchantId, int level, BedrockItemBuilder builder) {
|
||||
@ -243,8 +242,8 @@ public class Item {
|
||||
|
||||
/* Translation methods end */
|
||||
|
||||
public ItemStack newItemStack(int count, DataComponents components) {
|
||||
return new ItemStack(this.javaId, count, components);
|
||||
public GeyserItemStack newItemStack(int count, DataComponents components) {
|
||||
return GeyserItemStack.of(this.javaId, count, components);
|
||||
}
|
||||
|
||||
public void setJavaId(int javaId) { // TODO like this?
|
||||
|
@ -25,10 +25,7 @@
|
||||
|
||||
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.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.item.component.DataComponentType;
|
||||
@ -52,15 +49,4 @@ public class MapItem extends Item {
|
||||
builder.putInt("map_name_index", mapValue);
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,16 +25,15 @@
|
||||
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.item.Potion;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
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.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
|
||||
@ -69,12 +68,11 @@ public class PotionItem extends Item {
|
||||
}
|
||||
|
||||
@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());
|
||||
ItemStack itemStack = super.translateToJava(itemData, mapping, mappings);
|
||||
GeyserItemStack itemStack = super.translateToJava(itemData, mapping, mappings);
|
||||
if (potion != null) {
|
||||
StringTag potionTag = new StringTag("Potion", potion.getJavaIdentifier());
|
||||
//itemStack.getNbt().put(potionTag);
|
||||
itemStack.getOrCreateComponents().put(DataComponentType.POTION_CONTENTS, potion.toComponent());
|
||||
}
|
||||
return itemStack;
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
@ -85,12 +84,4 @@ public class ShulkerBoxItem extends BlockItem {
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
@ -25,13 +25,12 @@
|
||||
|
||||
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.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
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()));
|
||||
// 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.
|
||||
CompoundTag entityTag = components.get(DataComponentType.BUCKET_ENTITY_DATA);
|
||||
NbtMap entityTag = components.get(DataComponentType.BUCKET_ENTITY_DATA);
|
||||
if (entityTag != null && !entityTag.isEmpty()) {
|
||||
//TODO test
|
||||
Tag bucketVariant = entityTag.get("BucketVariantTag");
|
||||
if (bucketVariant == null || !(bucketVariant.getValue() instanceof Number)) {
|
||||
return;
|
||||
}
|
||||
int bucketVariant = entityTag.getInt("BucketVariantTag");
|
||||
List<String> lore = builder.getOrCreateLore();
|
||||
|
||||
int varNumber = ((Number) bucketVariant.getValue()).intValue();
|
||||
int predefinedVariantId = TropicalFishEntity.getPredefinedId(varNumber);
|
||||
int predefinedVariantId = TropicalFishEntity.getPredefinedId(bucketVariant);
|
||||
if (predefinedVariantId != -1) {
|
||||
Component tooltip = Component.translatable("entity.minecraft.tropical_fish.predefined." + predefinedVariantId, LORE_STYLE);
|
||||
lore.add(0, MessageTranslator.convertMessage(tooltip, session.locale()));
|
||||
} 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()));
|
||||
|
||||
byte baseColor = TropicalFishEntity.getBaseColor(varNumber);
|
||||
byte patternColor = TropicalFishEntity.getPatternColor(varNumber);
|
||||
byte baseColor = TropicalFishEntity.getBaseColor(bucketVariant);
|
||||
byte patternColor = TropicalFishEntity.getPatternColor(bucketVariant);
|
||||
Component colorTooltip = Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(baseColor), LORE_STYLE);
|
||||
if (baseColor != patternColor) {
|
||||
colorTooltip = colorTooltip.append(Component.text(", ", LORE_STYLE))
|
||||
|
@ -25,15 +25,10 @@
|
||||
|
||||
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.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
@ -69,24 +64,4 @@ public class WritableBookItem extends Item {
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public class WrittenBookItem extends Item {
|
||||
for (Filterable<Component> page : bookContent.getPages()) {
|
||||
NbtMapBuilder pageBuilder = NbtMap.builder();
|
||||
pageBuilder.putString("photoname", "");
|
||||
pageBuilder.putString("text", MessageTranslator.convertMessage(page.getRaw()));
|
||||
pageBuilder.putString("text", MessageTranslator.convertMessage(session, page.getRaw()));
|
||||
bedrockPages.add(pageBuilder.build());
|
||||
}
|
||||
builder.putList("pages", NbtType.COMPOUND, bedrockPages);
|
||||
@ -70,6 +70,5 @@ public class WrittenBookItem extends Item {
|
||||
builder.putString("title", bookContent.getTitle().getRaw())
|
||||
.putString("author", bookContent.getAuthor())
|
||||
.putInt("generation", bookContent.getGeneration());
|
||||
// TODO isResolved
|
||||
}
|
||||
}
|
||||
|
@ -25,13 +25,9 @@
|
||||
|
||||
package org.geysermc.geyser.level;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents the information we store from the current Java 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 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) {
|
||||
CompoundTag dimension = entry.getData();
|
||||
int minY = ((IntTag) dimension.get("min_y")).getValue();
|
||||
int maxY = ((IntTag) dimension.get("height")).getValue();
|
||||
NbtMap dimension = entry.getData();
|
||||
int minY = dimension.getInt("min_y");
|
||||
int maxY = dimension.getInt("height");
|
||||
// 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;
|
||||
boolean piglinSafe = dimension.getBoolean("piglin_safe");
|
||||
// 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);
|
||||
}
|
||||
|
@ -25,15 +25,13 @@
|
||||
|
||||
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.Int2ObjectOpenHashMap;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
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.WeakHashMap;
|
||||
@ -54,17 +52,7 @@ public final class LodestoneCache {
|
||||
*/
|
||||
private int id = 1;
|
||||
|
||||
public void cacheInventoryItem(GeyserItemStack itemStack) {
|
||||
DataComponents components = itemStack.getComponents();
|
||||
if (components == null) {
|
||||
// invalid
|
||||
return;
|
||||
}
|
||||
LodestoneTracker tracker = components.get(DataComponentType.LODESTONE_TRACKER);
|
||||
if (tracker == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
public void cacheInventoryItem(GeyserItemStack itemStack, LodestoneTracker tracker) {
|
||||
GlobalPos position = tracker.getPos();
|
||||
|
||||
if (position == null) {
|
||||
|
@ -26,10 +26,9 @@
|
||||
package org.geysermc.geyser.skin;
|
||||
|
||||
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.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.skin.ImageData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.skin.SerializedSkin;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket;
|
||||
@ -45,6 +44,7 @@ import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@ -224,22 +224,22 @@ public class SkinManager {
|
||||
* @param tag tag to build the GameProfileData from
|
||||
* @return The built GameProfileData, or null if this wasn't a valid tag
|
||||
*/
|
||||
public static @Nullable GameProfileData from(CompoundTag tag) {
|
||||
if (!(tag.get("Properties") instanceof CompoundTag propertiesTag)) {
|
||||
public static @Nullable GameProfileData from(NbtMap tag) {
|
||||
NbtMap properties = tag.getCompound("Properties", null);
|
||||
if (properties == 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;
|
||||
}
|
||||
if (!(texturesTag.get(0) instanceof CompoundTag texturesData)) {
|
||||
return null;
|
||||
}
|
||||
if (!(texturesData.get("Value") instanceof StringTag skinDataValue)) {
|
||||
String skinDataValue = textures.get(0).getString("Value", null);
|
||||
if (skinDataValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return loadFromJson(skinDataValue.getValue());
|
||||
return loadFromJson(skinDataValue);
|
||||
} catch (IOException e) {
|
||||
GeyserImpl.getInstance().getLogger().debug("Something went wrong while processing skin for tag " + tag);
|
||||
if (GeyserImpl.getInstance().getConfig().isDebugMode()) {
|
||||
|
@ -25,15 +25,14 @@
|
||||
|
||||
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.Style;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
@ -42,28 +41,28 @@ public final class TextDecoration {
|
||||
private final Style style;
|
||||
private final Set<Parameter> parameters;
|
||||
|
||||
public TextDecoration(CompoundTag tag) {
|
||||
translationKey = (String) tag.get("translation_key").getValue();
|
||||
public TextDecoration(NbtMap tag) {
|
||||
translationKey = tag.getString("translation_key");
|
||||
|
||||
CompoundTag styleTag = tag.get("style");
|
||||
NbtMap styleTag = tag.getCompound("style");
|
||||
Style.Builder builder = Style.style();
|
||||
if (styleTag != null) {
|
||||
StringTag color = styleTag.get("color");
|
||||
if (!styleTag.isEmpty()) {
|
||||
String color = styleTag.getString("color", null);
|
||||
if (color != null) {
|
||||
builder.color(NamedTextColor.NAMES.value(color.getValue()));
|
||||
builder.color(NamedTextColor.NAMES.value(color));
|
||||
}
|
||||
//TODO implement the rest
|
||||
Tag italic = styleTag.get("italic");
|
||||
if (italic != null && ((Number) italic.getValue()).byteValue() == (byte) 1) {
|
||||
boolean italic = styleTag.getBoolean("italic");
|
||||
if (italic) {
|
||||
builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC);
|
||||
}
|
||||
}
|
||||
style = builder.build();
|
||||
|
||||
this.parameters = EnumSet.noneOf(Parameter.class);
|
||||
ListTag parameters = tag.get("parameters");
|
||||
for (Tag parameter : parameters) {
|
||||
this.parameters.add(Parameter.valueOf(((String) parameter.getValue()).toUpperCase(Locale.ROOT)));
|
||||
List<String> parameters = tag.getList("parameters", NbtType.STRING);
|
||||
for (String parameter : parameters) {
|
||||
this.parameters.add(Parameter.valueOf(parameter.toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,8 +89,8 @@ public final class TextDecoration {
|
||||
|
||||
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.
|
||||
CompoundTag tag = entry.getData();
|
||||
CompoundTag chat = tag.get("chat");
|
||||
NbtMap tag = entry.getData();
|
||||
NbtMap chat = tag.getCompound("chat", null);
|
||||
TextDecoration textDecoration = null;
|
||||
if (chat != null) {
|
||||
textDecoration = new TextDecoration(chat);
|
||||
|
@ -224,7 +224,7 @@ public abstract class InventoryTranslator {
|
||||
//only set the head if the destination is the head slot
|
||||
GeyserItemStack javaItem = inventory.getItem(sourceSlot);
|
||||
if (javaItem.asItem() == Items.PLAYER_HEAD
|
||||
&& javaItem.getNbt() != null) {
|
||||
&& javaItem.getComponents() != null) {
|
||||
FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents());
|
||||
}
|
||||
} else if (sourceSlot == 5) {
|
||||
|
@ -94,7 +94,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
contents[i - 5] = item.getItemData(session);
|
||||
if (i == 5 &&
|
||||
item.asItem() == Items.PLAYER_HEAD &&
|
||||
item.getNbt() != null) {
|
||||
item.getComponents() != null) {
|
||||
FakeHeadProvider.setHead(session, session.getPlayerEntity(), item.getComponents());
|
||||
}
|
||||
}
|
||||
@ -138,7 +138,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
if (slot == 5) {
|
||||
// Check for custom skull
|
||||
if (javaItem.asItem() == Items.PLAYER_HEAD
|
||||
&& javaItem.getNbt() != null) {
|
||||
&& javaItem.getComponents() != null) {
|
||||
FakeHeadProvider.setHead(session, session.getPlayerEntity(), javaItem.getComponents());
|
||||
} else {
|
||||
FakeHeadProvider.restoreOriginalSkin(session, session.getPlayerEntity());
|
||||
|
@ -58,7 +58,7 @@ public class ShulkerInventoryTranslator extends AbstractBlockInventoryTranslator
|
||||
.putInt("z", position.getZ())
|
||||
.putString("CustomName", inventory.getTitle());
|
||||
// Don't reset facing property
|
||||
shulkerBoxTranslator.translateTag(tag, null, javaBlockState);
|
||||
shulkerBoxTranslator.translateTag(session, tag, null, javaBlockState);
|
||||
|
||||
BlockEntityDataPacket dataPacket = new BlockEntityDataPacket();
|
||||
dataPacket.setData(tag.build());
|
||||
|
@ -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.TextureType;
|
||||
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.format.NamedTextColor;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
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.translator.text.MessageTranslator;
|
||||
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.util.ArrayList;
|
||||
@ -93,16 +89,17 @@ public final class ItemTranslator {
|
||||
ItemMapping bedrockItem = mappings.getMapping(data);
|
||||
Item javaItem = bedrockItem.getJavaItem();
|
||||
|
||||
ItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings);
|
||||
GeyserItemStack itemStack = javaItem.translateToJava(data, bedrockItem, mappings);
|
||||
|
||||
// if (itemStack.getNbt() != null) {
|
||||
// javaItem.translateNbtToJava(itemStack.getNbt(), bedrockItem);
|
||||
// if (itemStack.getNbt().isEmpty()) {
|
||||
// // Otherwise, seems to cause issues with villagers accepting books, and I don't see how this will break anything else. - Camotoy
|
||||
// itemStack = new ItemStack(itemStack.getId(), itemStack.getAmount(), null);
|
||||
// }
|
||||
// }
|
||||
return itemStack;
|
||||
NbtMap nbt = data.getTag();
|
||||
if (nbt != null && !nbt.isEmpty()) {
|
||||
DataComponents components = new DataComponents(new HashMap<>());
|
||||
javaItem.translateNbtToJava(nbt, components, bedrockItem);
|
||||
if (!components.getDataComponents().isEmpty()) {
|
||||
itemStack.setComponents(components);
|
||||
}
|
||||
}
|
||||
return itemStack.getItemStack();
|
||||
}
|
||||
|
||||
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
|
||||
* @param session the Bedrock client's session
|
||||
|
@ -25,40 +25,43 @@
|
||||
|
||||
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.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.item.type.BannerItem;
|
||||
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)
|
||||
public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||
@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);
|
||||
if (bannerColor != -1) {
|
||||
builder.put("Base", 15 - bannerColor);
|
||||
bedrockNbt.putInt("Base", 15 - bannerColor);
|
||||
}
|
||||
|
||||
if (tag == null) {
|
||||
if (javaNbt == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tag.get("patterns") instanceof ListTag patterns) {
|
||||
List<NbtMap> patterns = javaNbt.getList("patterns", NbtType.COMPOUND);
|
||||
if (!patterns.isEmpty()) {
|
||||
if (BannerItem.isOminous(patterns)) {
|
||||
// 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
|
||||
builder.putInt("Type", 1);
|
||||
bedrockNbt.putInt("Type", 1);
|
||||
} 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) {
|
||||
builder.put("CustomName", customName.getValue());
|
||||
bedrockNbt.putString("CustomName", customName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,18 +25,19 @@
|
||||
|
||||
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.nbt.NbtMap;
|
||||
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)
|
||||
public class BeaconBlockEntityTranslator extends BlockEntityTranslator {
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
int primary = getOrDefault(tag.get("Primary"), 0);
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
int primary = javaNbt.getInt("primary");
|
||||
// The effects here generally map one-to-one Java <-> Bedrock. Only the newer ones get more complicated
|
||||
builder.putInt("primary", primary == -1 ? 0 : primary);
|
||||
int secondary = getOrDefault(tag.get("Secondary"), 0);
|
||||
builder.putInt("secondary", secondary == -1 ? 0 : secondary);
|
||||
bedrockNbt.putInt("primary", primary == -1 ? 0 : primary);
|
||||
int secondary = javaNbt.getInt("secondary");
|
||||
bedrockNbt.putInt("secondary", secondary == -1 ? 0 : secondary);
|
||||
}
|
||||
}
|
||||
|
@ -25,20 +25,21 @@
|
||||
|
||||
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.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
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)
|
||||
public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||
@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);
|
||||
// Just in case...
|
||||
if (bedcolor == -1) {
|
||||
bedcolor = 0;
|
||||
}
|
||||
builder.put("color", bedcolor);
|
||||
bedrockNbt.putByte("color", bedcolor);
|
||||
}
|
||||
}
|
||||
|
@ -25,13 +25,11 @@
|
||||
|
||||
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.NbtMapBuilder;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
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
|
||||
@ -40,11 +38,11 @@ public abstract class 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);
|
||||
translateTag(tagBuilder, tag, blockState);
|
||||
translateTag(session, tagBuilder, javaNbt, blockState);
|
||||
return tagBuilder.build();
|
||||
}
|
||||
|
||||
@ -59,9 +57,4 @@ public abstract class BlockEntityTranslator {
|
||||
.putInt("z", z)
|
||||
.putString("id", bedrockId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> T getOrDefault(Tag tag, T defaultValue) {
|
||||
return (tag != null && tag.getValue() != null) ? (T) tag.getValue() : defaultValue;
|
||||
}
|
||||
}
|
||||
|
@ -25,49 +25,46 @@
|
||||
|
||||
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.NbtMapBuilder;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
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.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.BRUSHABLE_BLOCK)
|
||||
public class BrushableBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
if (!(tag.remove("item") instanceof CompoundTag itemTag)) {
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
NbtMap itemTag = javaNbt.getCompound("item");
|
||||
if (itemTag.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Tag hitDirection = tag.get("hit_direction");
|
||||
if (hitDirection == null) {
|
||||
byte hitDirection = javaNbt.getByte("hit_direction", (byte) -1);
|
||||
if (hitDirection == -1) {
|
||||
// java server sends no direction when the item recedes back into the block (if player stops brushing)
|
||||
return;
|
||||
}
|
||||
|
||||
String id = ((StringTag) itemTag.get("id")).getValue();
|
||||
String id = itemTag.getString("id");
|
||||
if (Items.AIR.javaIdentifier().equals(id)) {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
NbtMapBuilder itemBuilder = NbtMap.builder()
|
||||
.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
|
||||
builder.putByte("brush_direction", ((Number) hitDirection.getValue()).byteValue());
|
||||
bedrockNbt.putByte("brush_direction", hitDirection);
|
||||
// controls how much the item protrudes
|
||||
builder.putInt("brush_count", BlockStateValues.getBrushProgress(blockState));
|
||||
bedrockNbt.putInt("brush_count", BlockStateValues.getBrushProgress(blockState));
|
||||
}
|
||||
}
|
||||
|
@ -25,37 +25,37 @@
|
||||
|
||||
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.NbtMapBuilder;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.CAMPFIRE)
|
||||
public class CampfireBlockEntityTranslator extends BlockEntityTranslator {
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
if (tag.get("Items") instanceof ListTag items) {
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
List<NbtMap> items = javaNbt.getList("Items", NbtType.COMPOUND);
|
||||
if (items != null) {
|
||||
int i = 1;
|
||||
for (Tag itemTag : items.getValue()) {
|
||||
builder.put("Item" + i, getItem((CompoundTag) itemTag));
|
||||
for (NbtMap itemTag : items) {
|
||||
bedrockNbt.put("Item" + i, getItem(session, itemTag));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected NbtMap getItem(CompoundTag tag) {
|
||||
// TODO: Version independent mappings
|
||||
ItemMapping mapping = Registries.ITEMS.forVersion(GameProtocol.DEFAULT_BEDROCK_CODEC.getProtocolVersion()).getMapping((String) tag.get("id").getValue());
|
||||
NbtMapBuilder tagBuilder = NbtMap.builder()
|
||||
.putString("Name", mapping.getBedrockIdentifier())
|
||||
.putByte("Count", (byte) tag.get("Count").getValue())
|
||||
.putShort("Damage", (short) mapping.getBedrockData());
|
||||
tagBuilder.put("tag", NbtMap.builder().build());
|
||||
protected NbtMap getItem(GeyserSession session, NbtMap tag) {
|
||||
ItemMapping mapping = session.getItemMappings().getMapping(tag.getString("id"));
|
||||
if (mapping == null) {
|
||||
mapping = ItemMapping.AIR;
|
||||
}
|
||||
NbtMapBuilder tagBuilder = BedrockItemBuilder.createItemNbt(mapping, tag.getByte("Count"), mapping.getBedrockData());
|
||||
tagBuilder.put("tag", NbtMap.builder().build()); // I don't think this is necessary... - Camo, 1.20.5/1.20.80
|
||||
return tagBuilder.build();
|
||||
}
|
||||
}
|
||||
|
@ -25,34 +25,31 @@
|
||||
|
||||
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.*;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.COMMAND_BLOCK)
|
||||
public class CommandBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
if (tag == null || tag.size() < 5) {
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
if (javaNbt == null || javaNbt.size() < 5) {
|
||||
return; // These values aren't here
|
||||
}
|
||||
// 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
|
||||
builder.put("conditionMet", ((ByteTag) tag.get("conditionMet")).getValue());
|
||||
builder.put("auto", ((ByteTag) tag.get("auto")).getValue());
|
||||
builder.put("CustomName", MessageTranslator.convertJsonMessage(((StringTag) tag.get("CustomName")).getValue()));
|
||||
builder.put("powered", ((ByteTag) tag.get("powered")).getValue());
|
||||
builder.put("Command", ((StringTag) tag.get("Command")).getValue());
|
||||
builder.put("SuccessCount", ((IntTag) tag.get("SuccessCount")).getValue());
|
||||
builder.put("TrackOutput", ((ByteTag) tag.get("TrackOutput")).getValue());
|
||||
builder.put("UpdateLastExecution", ((ByteTag) tag.get("UpdateLastExecution")).getValue());
|
||||
if (tag.get("LastExecution") != null) {
|
||||
builder.put("LastExecution", ((LongTag) tag.get("LastExecution")).getValue());
|
||||
} else {
|
||||
builder.put("LastExecution", (long) 0);
|
||||
}
|
||||
bedrockNbt.putByte("conditionMet", javaNbt.getByte("conditionMet"));
|
||||
bedrockNbt.putByte("auto", javaNbt.getByte("auto"));
|
||||
bedrockNbt.putString("CustomName", MessageTranslator.convertJsonMessage(javaNbt.getString("CustomName"), session.locale()));
|
||||
bedrockNbt.putByte("powered", javaNbt.getByte("powered"));
|
||||
bedrockNbt.putString("Command", javaNbt.getString("Command"));
|
||||
bedrockNbt.putInt("SuccessCount", javaNbt.getInt("SuccessCount"));
|
||||
bedrockNbt.putByte("TrackOutput", javaNbt.getByte("TrackOutput"));
|
||||
bedrockNbt.putByte("UpdateLastExecution", javaNbt.getByte("UpdateLastExecution"));
|
||||
bedrockNbt.putLong("LastExecution", javaNbt.getLong("LastExecution")); // Note: may not be present? Was a null check before 1.20.5
|
||||
}
|
||||
}
|
||||
|
@ -25,33 +25,22 @@
|
||||
|
||||
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.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.DECORATED_POT)
|
||||
public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
if (tag == null) {
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
if (javaNbt == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// exact same format
|
||||
if (tag.get("sherds") instanceof ListTag sherds) {
|
||||
List<String> translated = new ArrayList<>(4);
|
||||
for (Tag sherd : sherds) {
|
||||
translated.add(((StringTag) sherd).getValue());
|
||||
}
|
||||
builder.putList("sherds", NbtType.STRING, translated);
|
||||
}
|
||||
bedrockNbt.putList("sherds", NbtType.STRING, javaNbt.getList("sherds", NbtType.STRING));
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,8 @@
|
||||
|
||||
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.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.DoubleChestValue;
|
||||
@ -47,17 +47,17 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl
|
||||
@Override
|
||||
public void updateBlock(GeyserSession session, int blockState, Vector3i position) {
|
||||
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);
|
||||
}
|
||||
|
||||
@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);
|
||||
if (chestValues != null) {
|
||||
int x = (int) builder.get("x");
|
||||
int z = (int) builder.get("z");
|
||||
translateChestValue(builder, chestValues, x, z);
|
||||
int x = (int) bedrockNbt.get("x");
|
||||
int z = (int) bedrockNbt.get("z");
|
||||
translateChestValue(bedrockNbt, chestValues, x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,10 +88,10 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl
|
||||
x = x + (chestValues.isLeft() ? 1 : -1);
|
||||
}
|
||||
}
|
||||
builder.put("pairx", x);
|
||||
builder.put("pairz", z);
|
||||
builder.putInt("pairx", x);
|
||||
builder.putInt("pairz", z);
|
||||
if (!chestValues.isLeft()) {
|
||||
builder.put("pairlead", (byte) 1);
|
||||
builder.putInt("pairlead", (byte) 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,11 +25,12 @@
|
||||
|
||||
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.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
public class EmptyBlockEntityTranslator extends BlockEntityTranslator {
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
}
|
||||
}
|
||||
|
@ -25,44 +25,28 @@
|
||||
|
||||
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.IntList;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.END_GATEWAY)
|
||||
public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator {
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
Tag ageTag = tag.get("Age");
|
||||
if (ageTag instanceof LongTag) {
|
||||
builder.put("Age", (int) ((long) ageTag.getValue()));
|
||||
}
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
bedrockNbt.putInt("Age", (int) javaNbt.getLong("Age"));
|
||||
// Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist
|
||||
// Linked coordinates
|
||||
IntList tagsList = new IntArrayList();
|
||||
// Yes, the axis letters are capitalized
|
||||
tagsList.add(getExitPortalCoordinate(tag, "X"));
|
||||
tagsList.add(getExitPortalCoordinate(tag, "Y"));
|
||||
tagsList.add(getExitPortalCoordinate(tag, "Z"));
|
||||
builder.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;
|
||||
NbtMap exitPortal = javaNbt.getCompound("ExitPortal");
|
||||
tagsList.add(exitPortal.getInt("X", 0));
|
||||
tagsList.add(exitPortal.getInt("Y", 0));
|
||||
tagsList.add(exitPortal.getInt( "Z", 0));
|
||||
bedrockNbt.put("ExitPortal", new NbtList<>(NbtType.INT, tagsList));
|
||||
}
|
||||
}
|
||||
|
@ -25,28 +25,27 @@
|
||||
|
||||
package org.geysermc.geyser.translator.level.block.entity;
|
||||
|
||||
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.NbtMapBuilder;
|
||||
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.JIGSAW)
|
||||
public class JigsawBlockBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
Tag jointTag = tag.get("joint");
|
||||
if (jointTag instanceof StringTag) {
|
||||
builder.put("joint", ((StringTag) jointTag).getValue());
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
String joint = javaNbt.getString("joint", null);
|
||||
if (joint != null) {
|
||||
bedrockNbt.putString("joint", joint);
|
||||
} else {
|
||||
// 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
|
||||
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"), ""));
|
||||
builder.put("target_pool", getOrDefault(tag.get("pool"), ""));
|
||||
builder.put("final_state", ((StringTag) tag.get("final_state")).getValue());
|
||||
builder.put("target", getOrDefault(tag.get("target"), ""));
|
||||
bedrockNbt.putString("name", javaNbt.getString("name"));
|
||||
bedrockNbt.putString("target_pool", javaNbt.getString("target_pool"));
|
||||
bedrockNbt.putString("final_state", javaNbt.getString("final_state"));
|
||||
bedrockNbt.putString("target", javaNbt.getString("target"));
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,11 @@
|
||||
|
||||
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.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.ShulkerInventoryTranslator;
|
||||
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.
|
||||
*/
|
||||
@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);
|
||||
// Just in case...
|
||||
if (direction == -1) {
|
||||
direction = 1;
|
||||
}
|
||||
builder.put("facing", direction);
|
||||
bedrockNbt.putByte("facing", direction);
|
||||
}
|
||||
}
|
||||
|
@ -25,15 +25,16 @@
|
||||
|
||||
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.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.ChatColor;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.SignUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.SIGN)
|
||||
public class SignBlockEntityTranslator extends BlockEntityTranslator {
|
||||
@ -72,25 +73,21 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
builder.putCompound("FrontText", translateSide(tag.get("front_text")));
|
||||
builder.putCompound("BackText", translateSide(tag.get("back_text")));
|
||||
var waxed = tag.get("is_waxed");
|
||||
builder.putBoolean("IsWaxed", waxed != null && waxed.getValue() instanceof Number number && number.byteValue() != 0);
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
bedrockNbt.putCompound("FrontText", translateSide(javaNbt.getCompound("front_text")));
|
||||
bedrockNbt.putCompound("BackText", translateSide(javaNbt.getCompound("back_text")));
|
||||
bedrockNbt.putBoolean("IsWaxed", javaNbt.getBoolean("is_waxed"));
|
||||
}
|
||||
|
||||
private NbtMap translateSide(Tag tag) {
|
||||
if (!(tag instanceof CompoundTag signData)) {
|
||||
return NbtMap.EMPTY;
|
||||
}
|
||||
private NbtMap translateSide(NbtMap javaNbt) {
|
||||
NbtMapBuilder builder = NbtMap.builder();
|
||||
|
||||
StringBuilder signText = new StringBuilder();
|
||||
Tag messages = signData.get("messages");
|
||||
if (messages instanceof ListTag listTag) {
|
||||
var it = listTag.iterator();
|
||||
List<String> messages = javaNbt.getList("messages", NbtType.STRING);
|
||||
if (!messages.isEmpty()) {
|
||||
var it = messages.iterator();
|
||||
while (it.hasNext()) {
|
||||
String signLine = (String) it.next().getValue();
|
||||
String signLine = it.next();
|
||||
signLine = MessageTranslator.convertMessageLenient(signLine);
|
||||
|
||||
// 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());
|
||||
|
||||
// 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) {
|
||||
builder.putInt("SignTextColor", getBedrockSignColor(color.getValue().toString()));
|
||||
builder.putInt("SignTextColor", getBedrockSignColor(color));
|
||||
}
|
||||
|
||||
// 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);
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -25,24 +25,22 @@
|
||||
|
||||
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.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.packet.UpdateBlockPacket;
|
||||
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.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.SkullCache;
|
||||
import org.geysermc.geyser.skin.SkinProvider;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -52,56 +50,60 @@ import java.util.concurrent.ExecutionException;
|
||||
public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState {
|
||||
|
||||
@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);
|
||||
float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f;
|
||||
// Just in case...
|
||||
if (skullVariant == -1) {
|
||||
skullVariant = 0;
|
||||
}
|
||||
builder.put("Rotation", rotation);
|
||||
builder.put("SkullType", skullVariant);
|
||||
bedrockNbt.putFloat("Rotation", rotation);
|
||||
bedrockNbt.putByte("SkullType", skullVariant);
|
||||
if (BlockStateValues.isSkullPowered(blockState)) {
|
||||
builder.putBoolean("MouthMoving", true);
|
||||
bedrockNbt.putBoolean("MouthMoving", true);
|
||||
}
|
||||
}
|
||||
|
||||
private static UUID getUUID(CompoundTag profile) {
|
||||
if (profile.get("id") instanceof IntArrayTag uuidTag && uuidTag.length() == 4) {
|
||||
int[] uuidAsArray = uuidTag.getValue();
|
||||
private static UUID getUUID(NbtMap profile) {
|
||||
int[] uuidAsArray = profile.getIntArray("id");
|
||||
if (uuidAsArray.length == 4) {
|
||||
// thank u viaversion
|
||||
return new UUID((long) uuidAsArray[0] << 32 | ((long) uuidAsArray[1] & 0xFFFFFFFFL),
|
||||
(long) uuidAsArray[2] << 32 | ((long) uuidAsArray[3] & 0xFFFFFFFFL));
|
||||
}
|
||||
// Convert username to an offline UUID
|
||||
String username = null;
|
||||
if (profile.get("name") instanceof StringTag nameTag) {
|
||||
username = nameTag.getValue().toLowerCase(Locale.ROOT);
|
||||
String nameTag = profile.getString("name", null);
|
||||
if (nameTag != null) {
|
||||
username = nameTag.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
private static CompletableFuture<String> getTextures(CompoundTag profile, UUID uuid) {
|
||||
ListTag properties = profile.get("properties");
|
||||
if (properties == null) {
|
||||
private static CompletableFuture<@Nullable String> getTextures(NbtMap profile, UUID uuid) {
|
||||
List<NbtMap> properties = profile.getList("properties", NbtType.COMPOUND);
|
||||
if (properties.isEmpty()) {
|
||||
if (uuid != null && uuid.version() == 4) {
|
||||
String uuidString = uuid.toString().replace("-", "");
|
||||
return SkinProvider.requestTexturesFromUUID(uuidString);
|
||||
} else if (profile.get("name") instanceof StringTag nameTag) {
|
||||
// Fall back to username if UUID was missing or was an offline mode UUID
|
||||
return SkinProvider.requestTexturesFromUsername(nameTag.getValue());
|
||||
} else {
|
||||
String nameTag = profile.getString("name", null);
|
||||
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);
|
||||
}
|
||||
|
||||
LinkedHashMap<?,?> tag1 = (LinkedHashMap<?,?>) properties.get(0).getValue();
|
||||
StringTag texture = (StringTag) tag1.get("value");
|
||||
return CompletableFuture.completedFuture(texture.getValue());
|
||||
NbtMap tag1 = properties.get(0);
|
||||
String texture = tag1.getString("value", null);
|
||||
return CompletableFuture.completedFuture(texture);
|
||||
}
|
||||
|
||||
public static @Nullable BlockDefinition translateSkull(GeyserSession session, CompoundTag tag, Vector3i blockPosition, int blockState) {
|
||||
CompoundTag profile = tag.get("profile");
|
||||
if (profile == null) {
|
||||
public static @Nullable BlockDefinition translateSkull(GeyserSession session, NbtMap javaNbt, Vector3i blockPosition, int blockState) {
|
||||
NbtMap profile = javaNbt.getCompound("profile");
|
||||
if (profile.isEmpty()) {
|
||||
session.getSkullCache().removeSkull(blockPosition);
|
||||
return null;
|
||||
}
|
||||
@ -112,13 +114,13 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements
|
||||
try {
|
||||
String texture = texturesFuture.get();
|
||||
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;
|
||||
}
|
||||
SkullCache.Skull skull = session.getSkullCache().putSkull(blockPosition, uuid, texture, blockState);
|
||||
return skull.getBlockDefinition();
|
||||
} 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()) {
|
||||
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
|
||||
texturesFuture.whenComplete((texturesProperty, throwable) -> {
|
||||
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;
|
||||
}
|
||||
if (session.getEventLoop().inEventLoop()) {
|
||||
|
@ -25,10 +25,6 @@
|
||||
|
||||
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.Nullable;
|
||||
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.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.MOB_SPAWNER)
|
||||
public class SpawnerBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
@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!
|
||||
// Fixes https://github.com/GeyserMC/Geyser/issues/4214
|
||||
CompoundTag spawnData = tag.get("SpawnData");
|
||||
NbtMap spawnData = javaNbt.getCompound("SpawnData");
|
||||
if (spawnData != null) {
|
||||
CompoundTag entityTag = spawnData.get("entity");
|
||||
NbtMap entityTag = spawnData.getCompound("entity");
|
||||
if (entityTag.isEmpty()) {
|
||||
Vector3i position = Vector3i.from(x, y, z);
|
||||
// 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
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
Tag current;
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
Object current;
|
||||
|
||||
if ((current = tag.get("MaxNearbyEntities")) != null) {
|
||||
builder.put("MaxNearbyEntities", current.getValue());
|
||||
// TODO use primitive get and put methods
|
||||
if ((current = javaNbt.get("MaxNearbyEntities")) != null) {
|
||||
bedrockNbt.put("MaxNearbyEntities", current);
|
||||
}
|
||||
|
||||
if ((current = tag.get("RequiredPlayerRange")) != null) {
|
||||
builder.put("RequiredPlayerRange", current.getValue());
|
||||
if ((current = javaNbt.get("RequiredPlayerRange")) != null) {
|
||||
bedrockNbt.put("RequiredPlayerRange", current);
|
||||
}
|
||||
|
||||
if ((current = tag.get("SpawnCount")) != null) {
|
||||
builder.put("SpawnCount", current.getValue());
|
||||
if ((current = javaNbt.get("SpawnCount")) != null) {
|
||||
bedrockNbt.put("SpawnCount", current);
|
||||
}
|
||||
|
||||
if ((current = tag.get("MaxSpawnDelay")) != null) {
|
||||
builder.put("MaxSpawnDelay", current.getValue());
|
||||
if ((current = javaNbt.get("MaxSpawnDelay")) != null) {
|
||||
bedrockNbt.put("MaxSpawnDelay", current);
|
||||
}
|
||||
|
||||
if ((current = tag.get("Delay")) != null) {
|
||||
builder.put("Delay", current.getValue());
|
||||
if ((current = javaNbt.get("Delay")) != null) {
|
||||
bedrockNbt.put("Delay", current);
|
||||
}
|
||||
|
||||
if ((current = tag.get("SpawnRange")) != null) {
|
||||
builder.put("SpawnRange", current.getValue());
|
||||
if ((current = javaNbt.get("SpawnRange")) != null) {
|
||||
bedrockNbt.put("SpawnRange", current);
|
||||
}
|
||||
|
||||
if ((current = tag.get("MinSpawnDelay")) != null) {
|
||||
builder.put("MinSpawnDelay", current.getValue());
|
||||
if ((current = javaNbt.get("MinSpawnDelay")) != null) {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
CompoundTag entityTag = spawnData.get("entity");
|
||||
if (entityTag.get("id") instanceof StringTag idTag) {
|
||||
NbtMap entityTag = spawnData.getCompound("entity");
|
||||
String entityId = entityTag.getString("id");
|
||||
if (entityId != null) {
|
||||
// As of 1.19.3, spawners can be empty
|
||||
String entityId = idTag.getValue();
|
||||
builder.put("EntityIdentifier", entityId);
|
||||
|
||||
EntityDefinition<?> definition = Registries.JAVA_ENTITY_IDENTIFIERS.get(entityId);
|
||||
if (definition != null) {
|
||||
builder.put("DisplayEntityWidth", definition.width());
|
||||
builder.put("DisplayEntityHeight", definition.height());
|
||||
builder.put("DisplayEntityScale", 1.0f);
|
||||
builder.putFloat("DisplayEntityWidth", definition.width());
|
||||
builder.putFloat("DisplayEntityHeight", definition.height());
|
||||
builder.putFloat("DisplayEntityScale", 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
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.nbt.NbtMap;
|
||||
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.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.StructureBlockUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.STRUCTURE_BLOCK)
|
||||
public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
@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 :/
|
||||
int xStructureSize = getOrDefault(tag.get("sizeX"), 0);
|
||||
int yStructureSize = getOrDefault(tag.get("sizeY"), 0);
|
||||
int zStructureSize = getOrDefault(tag.get("sizeZ"), 0);
|
||||
int xStructureSize = javaNbt.getInt("sizeX");
|
||||
int yStructureSize = javaNbt.getInt("sizeY");
|
||||
int zStructureSize = javaNbt.getInt("sizeZ");
|
||||
|
||||
Vector3i size = Vector3i.from(xStructureSize, yStructureSize, zStructureSize);
|
||||
|
||||
if (size.equals(Vector3i.ZERO)) {
|
||||
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
|
||||
UpdateBlockPacket emptyBlockPacket = new UpdateBlockPacket();
|
||||
@ -66,18 +65,18 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
|
||||
session.sendUpstreamPacket(spawnerBlockPacket);
|
||||
}
|
||||
|
||||
return super.getBlockEntityTag(session, type, x, y, z, tag, blockState);
|
||||
return super.getBlockEntityTag(session, type, x, y, z, javaNbt, blockState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
if (tag.size() < 5) {
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
if (javaNbt.size() < 5) {
|
||||
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) {
|
||||
case "LOAD" -> 2;
|
||||
case "CORNER" -> 3;
|
||||
@ -85,53 +84,53 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
|
||||
default -> 1; // SAVE
|
||||
};
|
||||
|
||||
builder.putInt("data", bedrockData);
|
||||
builder.putString("dataField", ""); // ??? possibly related to Java's "metadata"
|
||||
bedrockNbt.putInt("data", bedrockData);
|
||||
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
|
||||
String mirror = getOrDefault(tag.get("mirror"), "");
|
||||
String mirror = javaNbt.getString("mirror");
|
||||
StructureMirror bedrockMirror = switch (mirror) {
|
||||
case "FRONT_BACK" -> StructureMirror.X;
|
||||
case "LEFT_RIGHT" -> StructureMirror.Z;
|
||||
default -> StructureMirror.NONE;
|
||||
};
|
||||
builder.putByte("mirror", (byte) bedrockMirror.ordinal());
|
||||
bedrockNbt.putByte("mirror", (byte) bedrockMirror.ordinal());
|
||||
|
||||
builder.putByte("ignoreEntities", getOrDefault(tag.get("ignoreEntities"), (byte) 0));
|
||||
builder.putByte("isPowered", getOrDefault(tag.get("powered"), (byte) 0));
|
||||
builder.putLong("seed", getOrDefault(tag.get("seed"), 0L));
|
||||
builder.putByte("showBoundingBox", getOrDefault(tag.get("showboundingbox"), (byte) 0));
|
||||
bedrockNbt.putByte("ignoreEntities", javaNbt.getByte("ignoreEntities"));
|
||||
bedrockNbt.putByte("isPowered", javaNbt.getByte("powered"));
|
||||
bedrockNbt.putLong("seed", javaNbt.getLong("seed"));
|
||||
bedrockNbt.putByte("showBoundingBox", javaNbt.getByte("showboundingbox"));
|
||||
|
||||
String rotation = getOrDefault(tag.get("rotation"), "");
|
||||
String rotation = javaNbt.getString("rotation");
|
||||
StructureRotation bedrockRotation = switch (rotation) {
|
||||
case "CLOCKWISE_90" -> StructureRotation.ROTATE_90;
|
||||
case "CLOCKWISE_180" -> StructureRotation.ROTATE_180;
|
||||
case "COUNTERCLOCKWISE_90" -> StructureRotation.ROTATE_270;
|
||||
default -> StructureRotation.NONE;
|
||||
};
|
||||
builder.putByte("rotation", (byte) bedrockRotation.ordinal());
|
||||
bedrockNbt.putByte("rotation", (byte) bedrockRotation.ordinal());
|
||||
|
||||
int xStructureSize = getOrDefault(tag.get("sizeX"), 0);
|
||||
int yStructureSize = getOrDefault(tag.get("sizeY"), 0);
|
||||
int zStructureSize = getOrDefault(tag.get("sizeZ"), 0);
|
||||
int xStructureSize = javaNbt.getInt("sizeX");
|
||||
int yStructureSize = javaNbt.getInt("sizeY");
|
||||
int zStructureSize = javaNbt.getInt("sizeZ");
|
||||
|
||||
// The "positions" are also offsets on Java
|
||||
int posX = getOrDefault(tag.get("posX"), 0);
|
||||
int posY = getOrDefault(tag.get("posY"), 0);
|
||||
int posZ = getOrDefault(tag.get("posZ"), 0);
|
||||
int posX = javaNbt.getInt("posX");
|
||||
int posY = javaNbt.getInt("posY");
|
||||
int posZ = javaNbt.getInt("posZ");
|
||||
|
||||
Vector3i offset = StructureBlockUtils.calculateOffset(bedrockRotation, bedrockMirror,
|
||||
xStructureSize, zStructureSize);
|
||||
|
||||
builder.putInt("xStructureOffset", posX + offset.getX());
|
||||
builder.putInt("yStructureOffset", posY);
|
||||
builder.putInt("zStructureOffset", posZ + offset.getZ());
|
||||
bedrockNbt.putInt("xStructureOffset", posX + offset.getX());
|
||||
bedrockNbt.putInt("yStructureOffset", posY);
|
||||
bedrockNbt.putInt("zStructureOffset", posZ + offset.getZ());
|
||||
|
||||
builder.putInt("xStructureSize", xStructureSize);
|
||||
builder.putInt("yStructureSize", yStructureSize);
|
||||
builder.putInt("zStructureSize", zStructureSize);
|
||||
bedrockNbt.putInt("xStructureSize", xStructureSize);
|
||||
bedrockNbt.putInt("yStructureSize", yStructureSize);
|
||||
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
|
||||
}
|
||||
|
@ -25,23 +25,24 @@
|
||||
|
||||
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.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.TRIAL_SPAWNER)
|
||||
public class TrialSpawnerBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
if (tag == null) {
|
||||
public void translateTag(GeyserSession session, NbtMapBuilder bedrockNbt, NbtMap javaNbt, int blockState) {
|
||||
if (javaNbt == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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
|
||||
builder.put("id", "MobSpawner");
|
||||
bedrockNbt.put("id", "MobSpawner");
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,8 @@
|
||||
|
||||
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.nbt.NbtMap;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror;
|
||||
@ -71,7 +70,7 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
|
||||
packet.getNbt(), blockState), packet.getPosition());
|
||||
// Check for custom skulls.
|
||||
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);
|
||||
if (blockDefinition != null) {
|
||||
hasCustomHeadBlock = true;
|
||||
@ -107,21 +106,21 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
|
||||
&& packet.getPosition().equals(session.getStructureBlockCache().getCurrentStructureBlock())
|
||||
&& 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")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String mirror = getOrDefault(map.get("mirror"), "");
|
||||
String mirror = map.getString("mirror");
|
||||
StructureMirror bedrockMirror = switch (mirror) {
|
||||
case "FRONT_BACK" -> StructureMirror.X;
|
||||
case "LEFT_RIGHT" -> StructureMirror.Z;
|
||||
default -> StructureMirror.NONE;
|
||||
};
|
||||
|
||||
String rotation = getOrDefault(map.get("rotation"), "");
|
||||
String rotation = map.getString("rotation");
|
||||
StructureRotation bedrockRotation = switch (rotation) {
|
||||
case "CLOCKWISE_90" -> StructureRotation.ROTATE_90;
|
||||
case "CLOCKWISE_180" -> StructureRotation.ROTATE_180;
|
||||
@ -129,10 +128,10 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
|
||||
default -> StructureRotation.NONE;
|
||||
};
|
||||
|
||||
String name = getOrDefault(map.get("name"), "");
|
||||
int sizeX = getOrDefault(map.get("sizeX"), 0);
|
||||
int sizeY = getOrDefault(map.get("sizeY"), 0);
|
||||
int sizeZ = getOrDefault(map.get("sizeZ"), 0);
|
||||
String name = map.getString("name");
|
||||
int sizeX = map.getInt("sizeX");
|
||||
int sizeY = map.getInt("sizeY");
|
||||
int sizeZ = map.getInt("sizeZ");
|
||||
|
||||
session.getStructureBlockCache().setCurrentStructureBlock(null);
|
||||
|
||||
@ -149,10 +148,4 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
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.ByteBufAllocator;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
@ -385,7 +384,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||
final int chunkBlockZ = packet.getZ() << 4;
|
||||
for (BlockEntityInfo blockEntity : blockEntities) {
|
||||
BlockEntityType type = blockEntity.getType();
|
||||
CompoundTag tag = blockEntity.getNbt();
|
||||
NbtMap tag = blockEntity.getNbt();
|
||||
if (type == null) {
|
||||
// As an example: ViaVersion will send -1 if it cannot find the block entity type
|
||||
// Vanilla Minecraft gracefully handles this
|
||||
@ -422,7 +421,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (blockDefinition != null) {
|
||||
int bedrockSectionY = (y >> 4) - (bedrockDimension.minY() >> 4);
|
||||
|
@ -25,16 +25,12 @@
|
||||
|
||||
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.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
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;
|
||||
|
||||
@ -104,25 +100,14 @@ public interface BlockSoundInteractionTranslator extends SoundInteractionTransla
|
||||
return true;
|
||||
}
|
||||
|
||||
CompoundTag tag = itemInHand.getNbt();
|
||||
if (tag == null) {
|
||||
// No CanPlaceOn tag can exist
|
||||
return false;
|
||||
}
|
||||
ListTag canPlaceOn = tag.get("CanPlaceOn");
|
||||
if (canPlaceOn == null || canPlaceOn.size() == 0) {
|
||||
return false;
|
||||
var canPlaceOn = itemInHand.getComponent(DataComponentType.CAN_PLACE_ON);
|
||||
if (canPlaceOn == null || canPlaceOn.getPredicates().isEmpty()) {
|
||||
// Component doesn't exist - no restrictions apply.
|
||||
return true;
|
||||
}
|
||||
|
||||
String cleanIdentifier = BlockUtils.getCleanIdentifier(blockIdentifier);
|
||||
|
||||
for (Tag t : canPlaceOn) {
|
||||
if (t instanceof StringTag stringTag) {
|
||||
if (cleanIdentifier.equals(stringTag.getValue())) {
|
||||
// This operation would/could be a success!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (var blockPredicate : canPlaceOn.getPredicates()) {
|
||||
// I don't want to deal with this right now. TODO
|
||||
}
|
||||
|
||||
// The block in world is not present in the CanPlaceOn tag on the item
|
||||
|
@ -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) {
|
||||
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) {
|
||||
return convertMessage(message, GeyserLocale.getDefaultLocale());
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ protocol-connection = "3.0.0.Beta1-20240411.165033-128"
|
||||
raknet = "1.0.0.CR3-20240416.144209-1"
|
||||
blockstateupdater="1.20.80-20240411.142413-1"
|
||||
mcauthlib = "d9d773e"
|
||||
mcprotocollib = "1ca8808" # Revert from jitpack after release
|
||||
mcprotocollib = "98410a1" # Revert from jitpack after release
|
||||
adventure = "4.14.0"
|
||||
adventure-platform = "4.3.0"
|
||||
junit = "5.9.2"
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren