3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2025-01-08 14:20:11 +01:00

Fix item_name component not working, improve display of custom effects and shulker box tooltips for item names (#5255)

* Show custom effects information in HUD, and be able to hide it using hide_additional_tooltip component

* Make vanilla default components no longer affect the translation of custom name (Fix item_name component not work)

* Fix book title display in tooltips of shulker box

* Fix colored item name display in tooltips of shulker box

* Add some code comments

* Block vanilla potion name translation when has hide_additional_tooltip component

* Add some brackets
Dieser Commit ist enthalten in:
BugTeaON 2025-01-05 19:41:35 +08:00 committet von GitHub
Ursprung f1ed841e07
Commit a19f0305fb
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: B5690EEEBB952194
5 geänderte Dateien mit 85 neuen und 52 gelöschten Zeilen

Datei anzeigen

@ -118,7 +118,17 @@ public class ItemFrameEntity extends Entity {
NbtMapBuilder builder = NbtMap.builder();
builder.putByte("Count", (byte) itemData.getCount());
NbtMap itemDataTag = itemData.getTag();
if (itemData.getTag() != null) {
if (itemDataTag != null) {
// Remove custom name that Geyser sets for items due to translating non-"custom_name" components
String customName = ItemTranslator.getCustomName(session, heldItem.getDataComponents(),
session.getItemMappings().getMapping(heldItem), 'f', true, false);
if (customName == null) {
// No custom name found, must modify tag if custom name exists
NbtMapBuilder copy = itemDataTag.toBuilder();
copy.remove("display"); // Also removes lore, but, should not matter
itemDataTag = copy.build();
}
builder.put("tag", itemDataTag);
}
builder.putShort("Damage", (short) itemData.getDamage());

Datei anzeigen

@ -34,9 +34,7 @@ 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.session.GeyserSession;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.item.CustomItemTranslator;
import org.geysermc.geyser.translator.item.ItemTranslator;
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;
@ -70,17 +68,6 @@ public class PotionItem extends Item {
return super.translateToBedrock(session, count, components, mapping, mappings);
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
// Make custom effect information visible
PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS);
if (potionContents != null) {
ItemTranslator.addPotionEffectLore(potionContents, builder, session.locale());
}
super.translateComponentsToBedrock(session, components, builder);
}
@Override
public @NonNull GeyserItemStack translateToJava(GeyserSession session, @NonNull ItemData itemData, @NonNull ItemMapping mapping, @NonNull ItemMappings mappings) {
Potion potion = Potion.getByBedrockId(itemData.getDamage());

Datei anzeigen

@ -35,6 +35,7 @@ import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.level.block.type.Block;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
import org.geysermc.geyser.translator.item.CustomItemTranslator;
import org.geysermc.geyser.translator.item.ItemTranslator;
@ -98,8 +99,12 @@ public class ShulkerBoxItem extends BlockItem {
// Only the display name is what we have interest in, so just translate that if relevant
if (boxComponents != null) {
String customName = ItemTranslator.getCustomName(session, boxComponents, boxMapping, '7', true);
String customName = ItemTranslator.getCustomName(session, boxComponents, boxMapping, '7', false, true);
if (customName != null) {
// Fix count display (e.g., x16) with incorrect color due to some items with colored names
if (customName.contains("" + ChatColor.ESCAPE)) {
customName += ChatColor.RESET + ChatColor.GRAY;
}
boxItemNbt.putCompound("tag", NbtMap.builder()
.putCompound("display", NbtMap.builder()
.putString("Name", customName)

Datei anzeigen

@ -25,15 +25,12 @@
package org.geysermc.geyser.item.type;
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.item.Potion;
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.geyser.translator.item.ItemTranslator;
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;
@ -60,15 +57,4 @@ public class TippedArrowItem extends ArrowItem {
}
return super.translateToBedrock(session, count, components, mapping, mappings);
}
@Override
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
// Make custom effect information visible
PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS);
if (potionContents != null) {
ItemTranslator.addPotionEffectLore(potionContents, builder, session.locale());
}
super.translateComponentsToBedrock(session, components, builder);
}
}

Datei anzeigen

@ -41,6 +41,7 @@ import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.block.custom.CustomBlockData;
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.item.Potion;
import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.components.Rarity;
import org.geysermc.geyser.item.type.Item;
@ -70,6 +71,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemAttribut
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectDetails;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.MobEffectInstance;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.WrittenBookContent;
import java.text.DecimalFormat;
import java.util.ArrayList;
@ -163,18 +165,25 @@ public final class ItemTranslator {
.build();
}
public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, @Nullable DataComponents components) {
public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, @Nullable DataComponents customComponents) {
BedrockItemBuilder nbtBuilder = new BedrockItemBuilder();
// Populates default components that aren't sent over the network
components = javaItem.gatherComponents(components);
DataComponents components = javaItem.gatherComponents(customComponents);
// Translate item-specific components
javaItem.translateComponentsToBedrock(session, components, nbtBuilder);
Rarity rarity = Rarity.fromId(components.getOrDefault(DataComponentType.RARITY, 0));
String customName = getCustomName(session, components, bedrockItem, rarity.getColor(), false);
String customName = getCustomName(session, customComponents, bedrockItem, rarity.getColor(), false, false);
if (customName != null) {
PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS);
// Make custom effect information visible
// Ignore when item have "hide_additional_tooltip" component
if (potionContents != null && components.get(DataComponentType.HIDE_ADDITIONAL_TOOLTIP) == null) {
customName += getPotionEffectInfo(potionContents, session.locale());
}
nbtBuilder.setCustomName(customName);
}
@ -336,7 +345,8 @@ public final class ItemTranslator {
Effect.INFESTED
);
public static void addPotionEffectLore(PotionContents contents, BedrockItemBuilder builder, String language) {
public static String getPotionEffectInfo(PotionContents contents, String language) {
StringBuilder finalText = new StringBuilder();
List<MobEffectInstance> effectInstanceList = contents.getCustomEffects();
for (MobEffectInstance effectInstance : effectInstanceList) {
Effect effect = effectInstance.getEffect();
@ -372,8 +382,40 @@ public final class ItemTranslator {
.color((negativeEffectList.contains(effect)) ? NamedTextColor.RED : NamedTextColor.BLUE)
.append(appendTranslatable)
.build();
builder.getOrCreateLore().add(MessageTranslator.convertMessage(component, language));
// Bedrock supports wrap lines with '\n' in a single string in custom name
finalText.append('\n').append(MessageTranslator.convertMessage(component, language));
}
return finalText.toString();
}
public static String getPotionName(PotionContents contents, ItemMapping mapping, boolean hideAdditionalTooltip, String language) {
String customPotionName = contents.getCustomName();
Potion potion = Potion.getByJavaId(contents.getPotionId());
if (customPotionName != null) {
// "custom_name" tag in "potion_contents" component
return MessageTranslator.convertMessage(
Component.translatable(mapping.getJavaItem().translationKey() + ".effect." + customPotionName),
language);
}
if (!hideAdditionalTooltip && !contents.getCustomEffects().isEmpty()) {
// Make a name when has custom effects
String potionName;
if (potion != null) {
potionName = potion.toString().toLowerCase(Locale.ROOT);
if (potionName.startsWith("strong_")) {
potionName = potionName.substring(6);
} else if (potionName.startsWith("long_")) {
potionName = potionName.substring(4);
}
} else {
potionName = "empty";
}
return MessageTranslator.convertMessage(
Component.translatable(mapping.getJavaItem().translationKey() + ".effect." + potionName),
language);
}
return null;
}
private static void addAdvancedTooltips(@Nullable DataComponents components, BedrockItemBuilder builder, Item item, String language) {
@ -493,31 +535,34 @@ public final class ItemTranslator {
* @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 String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping, char translationColor, boolean includeDefault) {
public static String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping, char translationColor, boolean customNameOnly, boolean includeAll) {
if (components != null) {
// ItemStack#getHoverName as of 1.20.5
Component customName = components.get(DataComponentType.CUSTOM_NAME);
if (customName != null) {
return MessageTranslator.convertMessage(customName, session.locale());
}
PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS);
if (potionContents != null) {
// "custom_name" tag in "potion_contents" component
String customPotionName = potionContents.getCustomName();
if (customPotionName != null) {
Component component = Component.text()
.resetStyle()
.color(NamedTextColor.WHITE)
.append(Component.translatable(mapping.getJavaItem().translationKey() + ".effect." + customPotionName))
.build();
return MessageTranslator.convertMessage(component, session.locale());
if (!customNameOnly) {
PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS);
if (potionContents != null) {
String potionName = getPotionName(potionContents, mapping, components.get(DataComponentType.HIDE_ADDITIONAL_TOOLTIP) != null, session.locale());
if (potionName != null) {
return ChatColor.RESET + ChatColor.ESCAPE + translationColor + potionName;
}
}
if (includeAll) {
// Fix book title display in tooltips of shulker box
WrittenBookContent bookContent = components.get(DataComponentType.WRITTEN_BOOK_CONTENT);
if (bookContent != null) {
return ChatColor.RESET + ChatColor.ESCAPE + translationColor + bookContent.getTitle().getRaw();
}
}
customName = components.get(DataComponentType.ITEM_NAME);
if (customName != null) {
// Get the translated name and prefix it with a reset char to prevent italics - matches Java Edition
// behavior as of 1.21
return ChatColor.RESET + ChatColor.ESCAPE + translationColor + MessageTranslator.convertMessage(customName, session.locale());
}
}
customName = components.get(DataComponentType.ITEM_NAME);
if (customName != null && includeDefault) {
// Get the translated name and prefix it with a reset char to prevent italics - matches Java Edition
// behavior as of 1.21
return ChatColor.RESET + ChatColor.ESCAPE + translationColor + MessageTranslator.convertMessage(customName, session.locale());
}
}