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
This commit is contained in:
Camotoy 2020-08-24 22:05:39 -04:00 committed by GitHub
parent 65c45386b9
commit 6e8106eeec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 158 additions and 43 deletions

View File

@ -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
*

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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()) {

View File

@ -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;
}

View File

@ -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<Tag> newTags = new ArrayList<>();
if (itemTag.contains("Enchantments")) {
ListTag enchantmentTag = itemTag.get("Enchantments");

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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");
}
}