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:
Ursprung
f1ed841e07
Commit
a19f0305fb
@ -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());
|
||||
|
@ -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());
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren