From 6e8106eeec7b4d68f5eb7a75df098e1fee90026e Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Mon, 24 Aug 2020 22:05:39 -0400 Subject: [PATCH] Add shulker box item tooltip translating (#1189) * Add shulker box item tooltip translating This commit adds support for previewing the items inside of a shulker box. This does not do a full translation, and only does enough to translate the item information to the client, so as to prevent any accidental item modifying/removing on creative mode. * Swap values --- .../translators/item/ItemTranslator.java | 69 +++++++------- .../item/NbtItemStackTranslator.java | 18 +++- .../translators/nbt/BasicItemTranslator.java | 3 +- .../translators/nbt/BookPagesTranslator.java | 3 +- .../translators/nbt/CrossbowTranslator.java | 3 +- .../nbt/EnchantedBookTranslator.java | 3 +- .../nbt/EnchantmentTranslator.java | 3 +- .../translators/nbt/FireworkTranslator.java | 3 +- .../nbt/LeatherArmorTranslator.java | 3 +- .../translators/nbt/MapItemTranslator.java | 3 +- .../nbt/ShulkerBoxItemTranslator.java | 90 +++++++++++++++++++ 11 files changed, 158 insertions(+), 43 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/ShulkerBoxItemTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index 37dd066e..dce0f4b4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -138,11 +138,13 @@ public abstract class ItemTranslator { if (nbt != null) { for (NbtItemStackTranslator translator : NBT_TRANSLATORS) { if (translator.acceptItem(bedrockItem)) { - translator.translateToBedrock(nbt, bedrockItem); + translator.translateToBedrock(session, nbt, bedrockItem); } } } + translateDisplayProperties(session, nbt); + ItemData itemData; ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId()); if (itemStackTranslator != null) { @@ -151,39 +153,6 @@ public abstract class ItemTranslator { itemData = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem); } - - // Get the display name of the item - NbtMap tag = itemData.getTag(); - if (tag != null) { - NbtMap display = tag.getCompound("display"); - if (display != null && !display.isEmpty() && display.containsKey("Name")) { - String name = display.getString("Name"); - - // If its not a message convert it - if (!MessageUtils.isMessage(name)) { - TextComponent component = LegacyComponentSerializer.legacySection().deserialize(name); - name = GsonComponentSerializer.gson().serialize(component); - } - - // Check if its a message to translate - if (MessageUtils.isMessage(name)) { - // Get the translated name - name = MessageUtils.getTranslatedBedrockMessage(MessageSerializer.fromString(name), session.getClientData().getLanguageCode()); - - // Build the new display tag - NbtMapBuilder displayBuilder = display.toBuilder(); - displayBuilder.putString("Name", name); - - // Build the new root tag - NbtMapBuilder builder = tag.toBuilder(); - builder.put("display", displayBuilder.build()); - - // Create a new item with the original data + updated name - itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.build()); - } - } - } - return itemData; } @@ -375,6 +344,38 @@ public abstract class ItemTranslator { return null; } + /** + * Translates the display name of the item + * @param session the Bedrock client's session + * @param tag the tag to translate + */ + public static void translateDisplayProperties(GeyserSession session, CompoundTag tag) { + if (tag != null) { + CompoundTag display = tag.get("display"); + if (display != null && !display.isEmpty() && display.contains("Name")) { + String name = ((StringTag) display.get("Name")).getValue(); + + // If its not a message convert it + if (!MessageUtils.isMessage(name)) { + TextComponent component = LegacyComponentSerializer.legacySection().deserialize(name); + name = GsonComponentSerializer.gson().serialize(component); + } + + // Check if its a message to translate + if (MessageUtils.isMessage(name)) { + // Get the translated name + name = MessageUtils.getTranslatedBedrockMessage(MessageSerializer.fromString(name), session.getClientData().getLanguageCode()); + + // Add the new name tag + display.put(new StringTag("Name", name)); + + // Add to the new root tag + tag.put(display); + } + } + } + } + /** * Checks if an {@link ItemStack} is equal to another item stack * diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/NbtItemStackTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/NbtItemStackTranslator.java index 3c0b75b7..89d41e98 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/NbtItemStackTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/NbtItemStackTranslator.java @@ -26,17 +26,33 @@ package org.geysermc.connector.network.translators.item; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import org.geysermc.connector.network.session.GeyserSession; public class NbtItemStackTranslator { - public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) { + /** + * Translate the item NBT to Bedrock + * @param session the client's current session + * @param itemTag the item's CompoundTag + * @param itemEntry Geyser's item entry + */ + public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) { } + /** + * Translate the item NBT to Java. + * @param itemTag the item's CompoundTag + * @param itemEntry Geyser's item entry + */ public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) { } + /** + * @param itemEntry Geyser's item entry + * @return if the item should be processed under this class + */ public boolean acceptItem(ItemEntry itemEntry) { return true; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BasicItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BasicItemTranslator.java index b30031eb..e4556626 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BasicItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BasicItemTranslator.java @@ -33,6 +33,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; @@ -45,7 +46,7 @@ import java.util.List; public class BasicItemTranslator extends NbtItemStackTranslator { @Override - public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) { + public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) { if (!itemTag.contains("display")) { return; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BookPagesTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BookPagesTranslator.java index e802f017..41ee4fbc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BookPagesTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BookPagesTranslator.java @@ -29,6 +29,7 @@ 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.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.ItemEntry; @@ -41,7 +42,7 @@ import java.util.List; public class BookPagesTranslator extends NbtItemStackTranslator { @Override - public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) { + public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) { if (!itemTag.contains("pages")) { return; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java index 3c5271eb..979c5a20 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/CrossbowTranslator.java @@ -29,6 +29,7 @@ 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.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.ItemEntry; @@ -37,7 +38,7 @@ import org.geysermc.connector.network.translators.item.ItemEntry; public class CrossbowTranslator extends NbtItemStackTranslator { @Override - public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) { + public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) { if (itemTag.get("ChargedProjectiles") != null) { ListTag chargedProjectiles = itemTag.get("ChargedProjectiles"); if (!chargedProjectiles.getValue().isEmpty()) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantedBookTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantedBookTranslator.java index 63ac6c51..990d5a7a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantedBookTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantedBookTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.connector.network.translators.item.translators.nbt; 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.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.ItemEntry; @@ -36,7 +37,7 @@ import org.geysermc.connector.network.translators.item.ItemEntry; public class EnchantedBookTranslator extends NbtItemStackTranslator { @Override - public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) { + public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) { if (!itemTag.contains("StoredEnchantments")) { return; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java index 6bd9cc77..6884c00b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java @@ -27,6 +27,7 @@ package org.geysermc.connector.network.translators.item.translators.nbt; import com.github.steveice10.opennbt.tag.builtin.*; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.Enchantment; @@ -40,7 +41,7 @@ import java.util.Map; public class EnchantmentTranslator extends NbtItemStackTranslator { @Override - public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) { + public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) { List newTags = new ArrayList<>(); if (itemTag.contains("Enchantments")) { ListTag enchantmentTag = itemTag.get("Enchantments"); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/FireworkTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/FireworkTranslator.java index 0e23169f..6023d77d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/FireworkTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/FireworkTranslator.java @@ -26,6 +26,7 @@ package org.geysermc.connector.network.translators.item.translators.nbt; import com.github.steveice10.opennbt.tag.builtin.*; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; @@ -36,7 +37,7 @@ import org.geysermc.connector.utils.MathUtils; public class FireworkTranslator extends NbtItemStackTranslator { @Override - public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) { + public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) { if (!itemTag.contains("Fireworks")) { return; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/LeatherArmorTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/LeatherArmorTranslator.java index 9f864ccf..93af3e70 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/LeatherArmorTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/LeatherArmorTranslator.java @@ -27,6 +27,7 @@ package org.geysermc.connector.network.translators.item.translators.nbt; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.ItemEntry; @@ -37,7 +38,7 @@ public class LeatherArmorTranslator extends NbtItemStackTranslator { private static final String[] ITEMS = new String[]{"minecraft:leather_helmet", "minecraft:leather_chestplate", "minecraft:leather_leggings", "minecraft:leather_boots"}; @Override - public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) { + public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) { if (!itemTag.contains("display")) { return; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/MapItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/MapItemTranslator.java index 4a36880c..c9b49efd 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/MapItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/MapItemTranslator.java @@ -29,6 +29,7 @@ import com.github.steveice10.opennbt.tag.builtin.ByteTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.LongTag; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; @@ -37,7 +38,7 @@ import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; public class MapItemTranslator extends NbtItemStackTranslator { @Override - public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) { + public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) { IntTag mapId = itemTag.get("map"); if (mapId != null) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/ShulkerBoxItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/ShulkerBoxItemTranslator.java new file mode 100644 index 00000000..1780537c --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/ShulkerBoxItemTranslator.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.item.translators.nbt; + +import com.github.steveice10.opennbt.tag.builtin.*; +import com.nukkitx.protocol.bedrock.packet.StartGamePacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.ItemRemapper; +import org.geysermc.connector.network.translators.item.ItemEntry; +import org.geysermc.connector.network.translators.item.ItemRegistry; +import org.geysermc.connector.network.translators.item.ItemTranslator; +import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; + +@ItemRemapper +public class ShulkerBoxItemTranslator extends NbtItemStackTranslator { + + @Override + public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) { + if (!itemTag.contains("BlockEntityTag")) return; // Empty shulker box + + CompoundTag blockEntityTag = itemTag.get("BlockEntityTag"); + ListTag itemsList = new ListTag("Items"); + for (Tag item : (ListTag) blockEntityTag.get("Items")) { + CompoundTag itemData = (CompoundTag) item; // Information about the item + CompoundTag boxItemTag = new CompoundTag(""); // Final item tag to add to the list + boxItemTag.put(new ByteTag("Slot", ((ByteTag) itemData.get("Slot")).getValue())); + boxItemTag.put(new ByteTag("WasPickedUp", (byte) 0)); // ??? + + ItemEntry boxItemEntry = ItemRegistry.getItemEntry(((StringTag) itemData.get("id")).getValue()); + String blockName = ""; + for (StartGamePacket.ItemEntry startGamePacketItemEntry : ItemRegistry.ITEMS) { + if (startGamePacketItemEntry.getId() == (short) boxItemEntry.getBedrockId()) { + blockName = startGamePacketItemEntry.getIdentifier(); // Find the Bedrock string name + break; + } + } + + boxItemTag.put(new StringTag("Name", blockName)); + boxItemTag.put(new ShortTag("Damage", (short) boxItemEntry.getBedrockData())); + boxItemTag.put(new ByteTag("Count", ((ByteTag) itemData.get("Count")).getValue())); + if (itemData.contains("tag")) { + // Only the display name is what we have interest in, so just translate that if relevant + CompoundTag displayTag = itemData.get("tag"); + ItemTranslator.translateDisplayProperties(session, displayTag); + boxItemTag.put(displayTag); + } + + itemsList.add(boxItemTag); + } + itemTag.put(itemsList); + // Don't actually bother with removing the block entity tag. Too risky to translate + // if the user is on creative and messing with a shulker box + //itemTag.remove("BlockEntityTag"); + } + + @Override + public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) { + if (itemTag.contains("Items")) { // Remove any extraneous Bedrock tag and don't touch the Java one + itemTag.remove("Items"); + } + } + + @Override + public boolean acceptItem(ItemEntry itemEntry) { + return itemEntry.getJavaIdentifier().contains("shulker_box"); + } +}