forked from GeyserMC/Geyser
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:
parent
65c45386b9
commit
6e8106eeec
11 changed files with 158 additions and 43 deletions
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue