From e7f933ba6c23e58cea0e96a875ed6374084b33c8 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 26 Apr 2021 14:44:16 -0400 Subject: [PATCH] Show proper names for Java-only items (#2159) Spectral arrows and knowledge books, if unnamed, will now show their correct, translated names. --- .../translators/item/ItemRegistry.java | 8 +++- .../translators/item/ItemTranslator.java | 42 +++++++++++++++++-- .../item/TranslatableItemEntry.java | 41 ++++++++++++++++++ .../nbt/ShulkerBoxItemTranslator.java | 17 ++++---- 4 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/item/TranslatableItemEntry.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index 7550bc818..10c14074f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -408,6 +408,13 @@ public class ItemRegistry { "", bedrockBlockId, stackSize); } + } else if (entry.getKey().equals("minecraft:spectral_arrow") || entry.getKey().equals("minecraft:knowledge_book")) { + // These items don't exist on Java, so set up a container that indicates they should have custom names + itemEntry = new TranslatableItemEntry( + entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, + entry.getValue().get("bedrock_data").intValue(), + bedrockBlockId, + stackSize); } else { itemEntry = new ItemEntry( entry.getKey(), bedrockIdentifier, itemIndex, bedrockId, @@ -471,7 +478,6 @@ public class ItemRegistry { } itemNames.add("minecraft:furnace_minecart"); - itemNames.add("minecraft:spectral_arrow"); if (lodestoneCompassId == 0) { throw new RuntimeException("Lodestone compass not found in item palette!"); 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 2cd1aad94..78bfd07ce 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 @@ -40,6 +40,7 @@ import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.chat.MessageTranslator; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LanguageUtils; +import org.geysermc.connector.utils.LocaleUtils; import org.reflections.Reflections; import java.util.*; @@ -137,8 +138,6 @@ public abstract class ItemTranslator { nbt.put(new IntTag("map", 0)); } - ItemStack itemStack = new ItemStack(stack.getId(), stack.getAmount(), nbt); - if (nbt != null) { for (NbtItemStackTranslator translator : NBT_TRANSLATORS) { if (translator.acceptItem(bedrockItem)) { @@ -147,7 +146,9 @@ public abstract class ItemTranslator { } } - translateDisplayProperties(session, nbt); + nbt = translateDisplayProperties(session, nbt, bedrockItem); + + ItemStack itemStack = new ItemStack(stack.getId(), stack.getAmount(), nbt); ItemData.Builder builder; ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId()); @@ -393,8 +394,20 @@ public abstract class ItemTranslator { * Translates the display name of the item * @param session the Bedrock client's session * @param tag the tag to translate + * @param itemEntry the item entry, in case it requires translation + * + * @return the new tag to use, should the current one be null */ - public static void translateDisplayProperties(GeyserSession session, CompoundTag tag) { + public static CompoundTag translateDisplayProperties(GeyserSession session, CompoundTag tag, ItemEntry itemEntry) { + return translateDisplayProperties(session, tag, itemEntry, 'f'); + } + + /** + * @param translationColor if this item is not available on Java, the color that the new name should be. + * Normally, this should just be white, but for shulker boxes this should be gray. + */ + public static CompoundTag translateDisplayProperties(GeyserSession session, CompoundTag tag, ItemEntry itemEntry, char translationColor) { + boolean hasCustomName = false; if (tag != null) { CompoundTag display = tag.get("display"); if (display != null && display.contains("Name")) { @@ -405,11 +418,32 @@ public abstract class ItemTranslator { // Add the new name tag display.put(new StringTag("Name", name)); + // Indicate that a custom name is present + hasCustomName = true; // Add to the new root tag tag.put(display); } } + + if (!hasCustomName && itemEntry instanceof TranslatableItemEntry) { + // No custom name, but we need to localize the item's name + if (tag == null) { + tag = new CompoundTag(""); + } + CompoundTag display = tag.get("display"); + if (display == null) { + display = new CompoundTag("display"); + // Add to the new root tag + tag.put(display); + } + + String translationKey = ((TranslatableItemEntry) itemEntry).getTranslationString(); + // Reset formatting since Bedrock defaults to italics + display.put(new StringTag("Name", "§r§" + translationColor + LocaleUtils.getLocaleString(translationKey, session.getLocale()))); + } + + return tag; } /** diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/TranslatableItemEntry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/TranslatableItemEntry.java new file mode 100644 index 000000000..b4ea92a0e --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/TranslatableItemEntry.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019-2021 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; + +import lombok.Getter; + +/** + * Used when an item should have a custom name applied, if there already isn't one. + */ +public class TranslatableItemEntry extends ItemEntry { + @Getter + private final String translationString; + + public TranslatableItemEntry(String javaIdentifier, String bedrockIdentifier, int javaId, int bedrockId, int bedrockData, int bedrockBlockId, int stackSize) { + super(javaIdentifier, bedrockIdentifier, javaId, bedrockId, bedrockData, bedrockBlockId, stackSize); + this.translationString = "item." + javaIdentifier.replace(":", "."); + } +} 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 index 5ddaa9975..197e119fc 100644 --- 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 @@ -28,10 +28,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.ItemRegistry; -import org.geysermc.connector.network.translators.item.ItemTranslator; -import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; +import org.geysermc.connector.network.translators.item.*; @ItemRemapper public class ShulkerBoxItemTranslator extends NbtItemStackTranslator { @@ -54,11 +51,13 @@ public class ShulkerBoxItemTranslator extends NbtItemStackTranslator { boxItemTag.put(new StringTag("Name", boxItemEntry.getBedrockIdentifier())); 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); + // Only the display name is what we have interest in, so just translate that if relevant + CompoundTag displayTag = itemData.get("tag"); + if (displayTag == null && boxItemEntry instanceof TranslatableItemEntry) { + displayTag = new CompoundTag("tag"); + } + if (displayTag != null) { + boxItemTag.put(ItemTranslator.translateDisplayProperties(session, displayTag, boxItemEntry, '7')); } itemsList.add(boxItemTag);