mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-19 14:59:27 +00:00
Support new tooltip display component and other 1.21.5 things (#5417)
* Work on supporting new tooltip display component * Fix some stuff and allow any item to function as saddle with the right components * Some fixes and TODOs * Re-implement tropical fish variant tooltip * Fix hiding advanced tooltips * Fix ominous banner tooltip, custom name and some TODOs * Implement RegistryEntryData to allow getting an object from registry cache by its key * Fix goat horns (I think) * We prefer checkers for the nullable/nonnull annotations * Remove unused NotNull import Co-authored-by: chris <github@onechris.mozmail.com> --------- Co-authored-by: chris <github@onechris.mozmail.com>
This commit is contained in:
@@ -26,7 +26,7 @@ dependencies {
|
||||
}
|
||||
|
||||
repositories {
|
||||
// mavenLocal()
|
||||
mavenLocal()
|
||||
|
||||
mavenCentral()
|
||||
|
||||
@@ -69,6 +69,4 @@ repositories {
|
||||
maven("https://jitpack.io") {
|
||||
content { includeGroupByRegex("com\\.github\\..*") }
|
||||
}
|
||||
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
@@ -59,7 +60,8 @@ public class FireworkEntity extends Entity {
|
||||
// TODO this looked the same, so I'm going to assume it is and (keep below comment if true)
|
||||
// Translate using item methods to get firework NBT for Bedrock
|
||||
BedrockItemBuilder builder = new BedrockItemBuilder();
|
||||
Items.FIREWORK_ROCKET.translateComponentsToBedrock(session, components, builder);
|
||||
TooltipOptions tooltip = TooltipOptions.fromComponents(components);
|
||||
Items.FIREWORK_ROCKET.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
dirtyMetadata.put(EntityDataTypes.DISPLAY_FIREWORK, builder.build());
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.scoreboard.Team;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@@ -51,6 +53,7 @@ import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.geyser.util.AttributeUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
@@ -62,6 +65,8 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.Object
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Equippable;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ColorParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
|
||||
@@ -133,7 +138,16 @@ public class LivingEntity extends Entity {
|
||||
|
||||
public void setSaddle(ItemStack stack) {
|
||||
this.saddle = ItemTranslator.translateToBedrock(session, stack);
|
||||
updateSaddled(stack.getId() == Items.SADDLE.javaId());
|
||||
|
||||
boolean saddled = false;
|
||||
Item item = Registries.JAVA_ITEMS.get(stack.getId());
|
||||
if (item != null) {
|
||||
DataComponents components = item.gatherComponents(stack.getDataComponentsPatch());
|
||||
Equippable equippable = components.get(DataComponentTypes.EQUIPPABLE);
|
||||
saddled = equippable != null && equippable.slot() == EquipmentSlot.SADDLE;
|
||||
}
|
||||
|
||||
updateSaddled(saddled);
|
||||
}
|
||||
|
||||
public void setHand(ItemStack stack) {
|
||||
|
||||
@@ -61,6 +61,10 @@ public class TropicalFishEntity extends AbstractFishEntity {
|
||||
dirtyMetadata.put(EntityDataTypes.COLOR_2, getPatternColor(varNumber)); // Pattern color 0-15
|
||||
}
|
||||
|
||||
public static int getPackedVariant(int pattern, int baseColor, int patternColor) {
|
||||
return pattern & 65535 | (baseColor & 0xFF) << 16 | (patternColor & 0xFF) << 24;
|
||||
}
|
||||
|
||||
public static int getShape(int variant) {
|
||||
return Math.min(variant & 0xFF, 1);
|
||||
}
|
||||
|
||||
@@ -89,14 +89,19 @@ public interface GeyserInstrument {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO 1.21.5
|
||||
// TODO test in 1.21.5
|
||||
static GeyserInstrument fromComponent(GeyserSession session, InstrumentComponent component) {
|
||||
if (component.instrumentLocation() != null) {
|
||||
return session.getRegistryCache().instruments().byKey(component.instrumentLocation());
|
||||
} else if (component.instrumentHolder() != null) {
|
||||
if (component.instrumentHolder().isId()) {
|
||||
return session.getRegistryCache().instruments().byId(component.instrumentHolder().id());
|
||||
}
|
||||
InstrumentComponent.Instrument custom = component.instrumentHolder().custom();
|
||||
return new Wrapper(custom, session.locale());
|
||||
}
|
||||
throw new IllegalStateException("InstrumentComponent must have either a location or a holder");
|
||||
}
|
||||
|
||||
record Wrapper(InstrumentComponent.Instrument instrument, String locale) implements GeyserInstrument {
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2025 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.geyser.item;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.TooltipDisplay;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface TooltipOptions {
|
||||
|
||||
TooltipOptions ALL_SHOWN = component -> true;
|
||||
|
||||
TooltipOptions ALL_HIDDEN = component -> false;
|
||||
|
||||
boolean showInTooltip(DataComponentType<?> component);
|
||||
|
||||
static TooltipOptions fromComponents(DataComponents components) {
|
||||
TooltipDisplay display = components.get(DataComponentTypes.TOOLTIP_DISPLAY);
|
||||
if (display == null) {
|
||||
return ALL_SHOWN;
|
||||
} else if (display.hideTooltip()) {
|
||||
return ALL_HIDDEN;
|
||||
} else if (display.hiddenComponents().isEmpty()) {
|
||||
return ALL_SHOWN;
|
||||
}
|
||||
|
||||
return component -> !display.hiddenComponents().contains(component);
|
||||
}
|
||||
|
||||
static boolean hideTooltip(DataComponents components) {
|
||||
TooltipDisplay display = components.get(DataComponentTypes.TOOLTIP_DISPLAY);
|
||||
return display != null && display.hideTooltip();
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.TrimMaterial;
|
||||
import org.cloudburstmc.protocol.bedrock.data.TrimPattern;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ArmorTrim;
|
||||
@@ -43,8 +44,8 @@ public class ArmorItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
ArmorTrim trim = components.get(DataComponentTypes.TRIM);
|
||||
if (trim != null) {
|
||||
@@ -54,6 +55,7 @@ public class ArmorItem extends Item {
|
||||
// discard custom trim patterns/materials to prevent visual glitches on bedrock
|
||||
if (!getNamespace(material.getMaterialId()).equals("minecraft")
|
||||
|| !getNamespace(pattern.getPatternId()).equals("minecraft")) {
|
||||
// TODO - how is this shown in tooltip? should we add a custom trim tooltip to the lore here
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
@@ -37,8 +38,8 @@ public class AxolotlBucketItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
// Bedrock Edition displays the properties of the axolotl. Java does not.
|
||||
// To work around this, set the custom name to the Axolotl translation and it's displayed correctly
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.inventory.item.BannerPattern;
|
||||
import org.geysermc.geyser.inventory.item.DyeColor;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@@ -46,6 +47,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.Holder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.TooltipDisplay;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -202,8 +204,8 @@ public class BannerItem extends BlockItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
List<BannerPatternLayer> patterns = components.get(DataComponentTypes.BANNER_PATTERNS);
|
||||
if (patterns != null) {
|
||||
@@ -225,7 +227,8 @@ public class BannerItem extends BlockItem {
|
||||
}
|
||||
|
||||
components.put(DataComponentTypes.BANNER_PATTERNS, patternLayers);
|
||||
// TODO 1.21.5 hide components???
|
||||
// The ominous banner item in the Java creative menu just has banner patterns hidden as of 1.21.5
|
||||
components.put(DataComponentTypes.TOOLTIP_DISPLAY, new TooltipDisplay(false, List.of(DataComponentTypes.BANNER_PATTERNS)));
|
||||
components.put(DataComponentTypes.ITEM_NAME, Component
|
||||
.translatable("block.minecraft.ominous_banner")
|
||||
.style(Style.style(TextColor.color(16755200)))
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@@ -59,8 +60,8 @@ public class CompassItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
LodestoneTracker tracker = components.get(DataComponentTypes.LODESTONE_TRACKER);
|
||||
if (tracker != null) {
|
||||
|
||||
@@ -28,6 +28,7 @@ package org.geysermc.geyser.item.type;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
@@ -44,8 +45,8 @@ public class CrossbowItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
List<ItemStack> chargedProjectiles = components.get(DataComponentTypes.CHARGED_PROJECTILES);
|
||||
if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) {
|
||||
|
||||
@@ -27,6 +27,7 @@ package org.geysermc.geyser.item.type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@@ -44,8 +45,8 @@ public class DecoratedPotItem extends BlockItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
List<Integer> decorations = components.get(DataComponentTypes.POT_DECORATIONS); // TODO maybe unbox in MCProtocolLib
|
||||
if (decorations != null) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
@@ -36,8 +37,8 @@ public class DyeableArmorItem extends ArmorItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
// Note that this is handled as of 1.20.5 in the ItemColors class.
|
||||
// But horse leather armor and body leather armor are now both armor items. So it works!
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.item.BedrockEnchantment;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.item.enchantment.Enchantment;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@@ -50,8 +51,8 @@ public class EnchantedBookItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
List<NbtMap> bedrockEnchants = new ArrayList<>();
|
||||
ItemEnchantments enchantments = components.get(DataComponentTypes.STORED_ENCHANTMENTS);
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.level.FireworkColor;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@@ -48,8 +49,8 @@ public class FireworkRocketItem extends Item implements BedrockRequiresTagItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
Fireworks fireworks = components.get(DataComponentTypes.FIREWORKS);
|
||||
if (fireworks == null) {
|
||||
|
||||
@@ -27,6 +27,7 @@ package org.geysermc.geyser.item.type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
@@ -40,8 +41,8 @@ public class FireworkStarItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
Fireworks.FireworkExplosion explosion = components.get(DataComponentTypes.FIREWORK_EXPLOSION);
|
||||
if (explosion != null) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
@@ -36,8 +37,8 @@ public class FishingRodItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
// Fix damage inconsistency
|
||||
builder.getDamage().ifPresent(damage -> builder.setDamage(getBedrockDamage(damage)));
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.item.GeyserInstrument;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@@ -63,12 +64,11 @@ public class GoatHornItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
InstrumentComponent component = components.get(DataComponentTypes.INSTRUMENT);
|
||||
// TODO 1.21.5 hiding????
|
||||
if (component != null) {
|
||||
if (component != null && tooltip.showInTooltip(DataComponentTypes.INSTRUMENT)) {
|
||||
GeyserInstrument instrument = GeyserInstrument.fromComponent(session, component);
|
||||
if (instrument.bedrockInstrument() == null) {
|
||||
builder.getOrCreateLore().add(instrument.description());
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.item.BedrockEnchantment;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.item.enchantment.Enchantment;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
@@ -46,6 +47,7 @@ import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.ChatColor;
|
||||
import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.MinecraftKey;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
@@ -155,15 +157,14 @@ public class Item {
|
||||
/**
|
||||
* Takes components from Java Edition and map them into Bedrock.
|
||||
*/
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
List<Component> loreComponents = components.get(DataComponentTypes.LORE);
|
||||
// TODO 1.21.5
|
||||
// if (loreComponents != null && components.get(DataComponentTypes.HIDE_TOOLTIP) == null) {
|
||||
// List<String> lore = builder.getOrCreateLore();
|
||||
// for (Component loreComponent : loreComponents) {
|
||||
// lore.add(MessageTranslator.convertMessage(loreComponent, session.locale()));
|
||||
// }
|
||||
// }
|
||||
if (loreComponents != null && tooltip.showInTooltip(DataComponentTypes.LORE)) {
|
||||
List<String> lore = builder.getOrCreateLore();
|
||||
for (Component loreComponent : loreComponents) {
|
||||
lore.add(MessageTranslator.convertMessage(loreComponent, session.locale()));
|
||||
}
|
||||
}
|
||||
|
||||
Integer damage = components.get(DataComponentTypes.DAMAGE);
|
||||
if (damage != null) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
@@ -37,8 +38,8 @@ public class MapItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
Integer mapValue = components.get(DataComponentTypes.MAP_ID);
|
||||
if (mapValue == null) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.item.components.Rarity;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@@ -42,8 +43,8 @@ public class PlayerHeadItem extends BlockItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
// Use the correct color, determined by the rarity of the item
|
||||
char rarity = Rarity.fromId(components.get(DataComponentTypes.RARITY)).getColor();
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.BannerPatternLayer;
|
||||
@@ -40,8 +41,8 @@ public class ShieldItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
List<BannerPatternLayer> patterns = components.get(DataComponentTypes.BANNER_PATTERNS);
|
||||
if (patterns != null) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
import org.geysermc.geyser.inventory.item.Potion;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
@@ -53,8 +54,8 @@ public class ShulkerBoxItem extends BlockItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
List<ItemStack> contents = components.get(DataComponentTypes.CONTAINER);
|
||||
if (contents == null || contents.isEmpty()) {
|
||||
|
||||
@@ -30,8 +30,8 @@ import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.geyser.entity.type.living.animal.TropicalFishEntity;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
@@ -49,37 +49,54 @@ public class TropicalFishBucketItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
// Prevent name from appearing as "Bucket of"
|
||||
builder.putByte("AppendCustomName", (byte) 1);
|
||||
builder.putString("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale()));
|
||||
|
||||
// Add Java's client side lore tag
|
||||
// Do you know how frequently Java NBT used to be before 1.20.5? It was a lot. And now it's just this lowly check.
|
||||
NbtMap entityTag = components.get(DataComponentTypes.BUCKET_ENTITY_DATA);
|
||||
if (entityTag != null && !entityTag.isEmpty()) {
|
||||
//TODO test
|
||||
int bucketVariant = entityTag.getInt("BucketVariantTag");
|
||||
Integer pattern = components.get(DataComponentTypes.TROPICAL_FISH_PATTERN);
|
||||
Integer baseColor = components.get(DataComponentTypes.TROPICAL_FISH_BASE_COLOR);
|
||||
Integer patternColor = components.get(DataComponentTypes.TROPICAL_FISH_PATTERN_COLOR);
|
||||
|
||||
// The pattern component decides whether to show the tooltip of all 3 components, as of Java 1.21.5
|
||||
if ((pattern != null || (baseColor != null && patternColor != null)) && tooltip.showInTooltip(DataComponentTypes.TROPICAL_FISH_PATTERN)) {
|
||||
//TODO test this for 1.21.5
|
||||
int packedVariant = getPackedVariant(pattern, baseColor, patternColor);
|
||||
List<String> lore = builder.getOrCreateLore();
|
||||
|
||||
int predefinedVariantId = TropicalFishEntity.getPredefinedId(bucketVariant);
|
||||
int predefinedVariantId = TropicalFishEntity.getPredefinedId(packedVariant);
|
||||
if (predefinedVariantId != -1) {
|
||||
Component tooltip = Component.translatable("entity.minecraft.tropical_fish.predefined." + predefinedVariantId, LORE_STYLE);
|
||||
lore.add(0, MessageTranslator.convertMessage(tooltip, session.locale()));
|
||||
Component line = Component.translatable("entity.minecraft.tropical_fish.predefined." + predefinedVariantId, LORE_STYLE);
|
||||
lore.add(0, MessageTranslator.convertMessage(line, session.locale()));
|
||||
} else {
|
||||
Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(bucketVariant), LORE_STYLE);
|
||||
Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(packedVariant), LORE_STYLE);
|
||||
lore.add(0, MessageTranslator.convertMessage(typeTooltip, session.locale()));
|
||||
|
||||
byte baseColor = TropicalFishEntity.getBaseColor(bucketVariant);
|
||||
byte patternColor = TropicalFishEntity.getPatternColor(bucketVariant);
|
||||
Component colorTooltip = Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(baseColor), LORE_STYLE);
|
||||
if (baseColor != patternColor) {
|
||||
if (baseColor != null && patternColor != null) {
|
||||
Component colorTooltip = Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(baseColor.byteValue()), LORE_STYLE);
|
||||
if (!baseColor.equals(patternColor)) {
|
||||
colorTooltip = colorTooltip.append(Component.text(", ", LORE_STYLE))
|
||||
.append(Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(patternColor), LORE_STYLE));
|
||||
.append(Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(patternColor.byteValue()), LORE_STYLE));
|
||||
}
|
||||
lore.add(1, MessageTranslator.convertMessage(colorTooltip, session.locale()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int getPackedVariant(Integer pattern, Integer baseColor, Integer patternColor) {
|
||||
if (pattern == null) {
|
||||
pattern = 0;
|
||||
}
|
||||
if (baseColor == null) {
|
||||
baseColor = 0;
|
||||
}
|
||||
if (patternColor == null) {
|
||||
patternColor = 0;
|
||||
}
|
||||
return TropicalFishEntity.getPackedVariant(pattern, baseColor, patternColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package org.geysermc.geyser.item.type;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
@@ -36,8 +37,8 @@ public class WolfArmorItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
// Note that this is handled as of 1.21 in the ItemColors class.
|
||||
translateDyedColor(components, builder);
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
@@ -46,8 +47,8 @@ public class WritableBookItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
WritableBookContent bookContent = components.get(DataComponentTypes.WRITABLE_BOOK_CONTENT);
|
||||
if (bookContent == null) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
@@ -51,8 +52,8 @@ public class WrittenBookItem extends Item {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, builder);
|
||||
public void translateComponentsToBedrock(@NonNull GeyserSession session, @NonNull DataComponents components, @NonNull TooltipOptions tooltip, @NonNull BedrockItemBuilder builder) {
|
||||
super.translateComponentsToBedrock(session, components, tooltip, builder);
|
||||
|
||||
WrittenBookContent bookContent = components.get(DataComponentTypes.WRITTEN_BOOK_CONTENT);
|
||||
if (bookContent == null) {
|
||||
|
||||
@@ -51,6 +51,7 @@ import org.geysermc.geyser.session.cache.registry.JavaRegistries;
|
||||
import org.geysermc.geyser.session.cache.registry.JavaRegistry;
|
||||
import org.geysermc.geyser.session.cache.registry.JavaRegistryKey;
|
||||
import org.geysermc.geyser.session.cache.registry.RegistryEntryContext;
|
||||
import org.geysermc.geyser.session.cache.registry.RegistryEntryData;
|
||||
import org.geysermc.geyser.session.cache.registry.SimpleJavaRegistry;
|
||||
import org.geysermc.geyser.text.ChatDecoration;
|
||||
import org.geysermc.geyser.translator.level.BiomeTranslator;
|
||||
@@ -189,7 +190,7 @@ public final class RegistryCache {
|
||||
entryIdMap.put(entries.get(i).getId(), i);
|
||||
}
|
||||
|
||||
List<T> builder = new ArrayList<>(entries.size());
|
||||
List<RegistryEntryData<T>> builder = new ArrayList<>(entries.size());
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
RegistryEntry entry = entries.get(i);
|
||||
// If the data is null, that's the server telling us we need to use our default values.
|
||||
@@ -203,7 +204,7 @@ public final class RegistryCache {
|
||||
RegistryEntryContext context = new RegistryEntryContext(entry, entryIdMap, registryCache.session);
|
||||
// This is what Geyser wants to keep as a value for this registry.
|
||||
T cacheEntry = reader.apply(context);
|
||||
builder.add(i, cacheEntry);
|
||||
builder.add(i, new RegistryEntryData<>(entry.getId(), cacheEntry));
|
||||
}
|
||||
localCache.reset(builder);
|
||||
});
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
package org.geysermc.geyser.session.cache.registry;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
|
||||
import java.util.List;
|
||||
@@ -39,15 +40,30 @@ public interface JavaRegistry<T> {
|
||||
*/
|
||||
T byId(@NonNegative int id);
|
||||
|
||||
/**
|
||||
* Looks up a registry entry by its key. The object can be null, or not present.
|
||||
*/
|
||||
T byKey(Key key);
|
||||
|
||||
/**
|
||||
* Looks up a registry entry by its ID, and returns it wrapped in {@link RegistryEntryData} so that its registered key is also known. The object can be null, or not present.
|
||||
*/
|
||||
RegistryEntryData<T> entryById(@NonNegative int id);
|
||||
|
||||
/**
|
||||
* Reverse looks-up an object to return its network ID, or -1.
|
||||
*/
|
||||
int byValue(T value);
|
||||
|
||||
/**
|
||||
* Reverse looks-up an object to return it wrapped in {@link RegistryEntryData}, or null.
|
||||
*/
|
||||
RegistryEntryData<T> entryByValue(T value);
|
||||
|
||||
/**
|
||||
* Resets the objects by these IDs.
|
||||
*/
|
||||
void reset(List<T> values);
|
||||
void reset(List<RegistryEntryData<T>> values);
|
||||
|
||||
/**
|
||||
* All values of this registry, as a list.
|
||||
|
||||
@@ -26,10 +26,9 @@
|
||||
package org.geysermc.geyser.session.cache.registry;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Defines a Java registry, which can be hardcoded or data-driven. This class doesn't store registry contents itself, that is handled by {@link org.geysermc.geyser.session.cache.RegistryCache} in the case of
|
||||
* data-driven registries and other classes in the case of hardcoded registries.
|
||||
|
||||
31
core/src/main/java/org/geysermc/geyser/session/cache/registry/RegistryEntryData.java
vendored
Normal file
31
core/src/main/java/org/geysermc/geyser/session/cache/registry/RegistryEntryData.java
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2025 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.geyser.session.cache.registry;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
|
||||
public record RegistryEntryData<T>(Key key, T data) {
|
||||
}
|
||||
@@ -26,15 +26,34 @@
|
||||
package org.geysermc.geyser.session.cache.registry;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleJavaRegistry<T> implements JavaRegistry<T> {
|
||||
protected final ObjectArrayList<T> values = new ObjectArrayList<>();
|
||||
protected final ObjectArrayList<RegistryEntryData<T>> values = new ObjectArrayList<>();
|
||||
|
||||
@Override
|
||||
public T byId(@NonNegative int id) {
|
||||
if (id < 0 || id >= this.values.size()) {
|
||||
return null;
|
||||
}
|
||||
return this.values.get(id).data();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T byKey(Key key) {
|
||||
for (RegistryEntryData<T> entry : values) {
|
||||
if (entry.key().equals(key)) {
|
||||
return entry.data();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryEntryData<T> entryById(@NonNegative int id) {
|
||||
if (id < 0 || id >= this.values.size()) {
|
||||
return null;
|
||||
}
|
||||
@@ -43,11 +62,26 @@ public class SimpleJavaRegistry<T> implements JavaRegistry<T> {
|
||||
|
||||
@Override
|
||||
public int byValue(T value) {
|
||||
return this.values.indexOf(value);
|
||||
for (int i = 0; i < this.values.size(); i++) {
|
||||
if (values.get(i).data().equals(value)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<T> values) {
|
||||
public RegistryEntryData<T> entryByValue(T value) {
|
||||
for (RegistryEntryData<T> entry : this.values) {
|
||||
if (entry.data().equals(value)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(List<RegistryEntryData<T>> values) {
|
||||
this.values.clear();
|
||||
this.values.addAll(values);
|
||||
this.values.trim();
|
||||
@@ -55,7 +89,7 @@ public class SimpleJavaRegistry<T> implements JavaRegistry<T> {
|
||||
|
||||
@Override
|
||||
public List<T> values() {
|
||||
return this.values;
|
||||
return this.values.stream().map(RegistryEntryData::data).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -43,8 +43,10 @@ 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.TooltipOptions;
|
||||
import org.geysermc.geyser.item.components.Rarity;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.item.type.PotionItem;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
@@ -168,37 +170,32 @@ public final class ItemTranslator {
|
||||
public static ItemData.@NonNull Builder translateToBedrock(GeyserSession session, Item javaItem, ItemMapping bedrockItem, int count, @Nullable DataComponents customComponents) {
|
||||
BedrockItemBuilder nbtBuilder = new BedrockItemBuilder();
|
||||
|
||||
// TODO 1.21.5:
|
||||
// - Hiding components
|
||||
|
||||
// Populates default components that aren't sent over the network
|
||||
DataComponents components = javaItem.gatherComponents(customComponents);
|
||||
TooltipOptions tooltip = TooltipOptions.fromComponents(components);
|
||||
|
||||
// Translate item-specific components
|
||||
javaItem.translateComponentsToBedrock(session, components, nbtBuilder);
|
||||
javaItem.translateComponentsToBedrock(session, components, tooltip, nbtBuilder);
|
||||
|
||||
Rarity rarity = Rarity.fromId(components.getOrDefault(DataComponentTypes.RARITY, 0));
|
||||
String customName = getCustomName(session, customComponents, bedrockItem, rarity.getColor(), false, false);
|
||||
if (customName != null) {
|
||||
PotionContents potionContents = components.get(DataComponentTypes.POTION_CONTENTS);
|
||||
// Make custom effect information visible
|
||||
// Ignore when item have "hide_additional_tooltip" component
|
||||
if (potionContents != null) { // && components.get(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) == null) {
|
||||
customName += getPotionEffectInfo(potionContents, session.locale());
|
||||
// Make custom effect information visible when shown in tooltip
|
||||
if (potionContents != null && tooltip.showInTooltip(DataComponentTypes.POTION_CONTENTS)) {
|
||||
customName += getPotionEffectInfo(potionContents, session.locale()); // TODO should this be done with lore instead?
|
||||
}
|
||||
|
||||
nbtBuilder.setCustomName(customName);
|
||||
}
|
||||
|
||||
//boolean hideTooltips = components.get(DataComponentTypes.HIDE_TOOLTIP) != null;
|
||||
|
||||
ItemAttributeModifiers attributeModifiers = components.get(DataComponentTypes.ATTRIBUTE_MODIFIERS);
|
||||
if (attributeModifiers != null) { //&& attributeModifiers.isShowInTooltip() && !hideTooltips) {
|
||||
if (attributeModifiers != null && tooltip.showInTooltip(DataComponentTypes.ATTRIBUTE_MODIFIERS )) {
|
||||
// only add if attribute modifiers do not indicate to hide them
|
||||
addAttributeLore(session, attributeModifiers, nbtBuilder, session.locale());
|
||||
}
|
||||
|
||||
if (session.isAdvancedTooltips()) { //&& !hideTooltips) {
|
||||
if (session.isAdvancedTooltips() && !TooltipOptions.hideTooltip(components)) {
|
||||
addAdvancedTooltips(components, nbtBuilder, javaItem, session.locale());
|
||||
}
|
||||
|
||||
@@ -391,7 +388,7 @@ public final class ItemTranslator {
|
||||
return finalText.toString();
|
||||
}
|
||||
|
||||
public static String getPotionName(PotionContents contents, ItemMapping mapping, boolean hideAdditionalTooltip, String language) {
|
||||
public static String getPotionName(PotionContents contents, ItemMapping mapping, String language) {
|
||||
String customPotionName = contents.getCustomName();
|
||||
Potion potion = Potion.getByJavaId(contents.getPotionId());
|
||||
|
||||
@@ -401,22 +398,10 @@ public final class ItemTranslator {
|
||||
Component.translatable(mapping.getJavaItem().translationKey() + ".effect." + customPotionName),
|
||||
language);
|
||||
}
|
||||
if (!hideAdditionalTooltip && !contents.getCustomEffects().isEmpty()) {
|
||||
if (!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);
|
||||
String potionName = potion == null ? "empty" : potion.toString().toLowerCase(Locale.ROOT);
|
||||
return MessageTranslator.convertMessage(Component.translatable(mapping.getJavaItem().translationKey() + ".effect." + potionName), language);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -538,22 +523,31 @@ 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 customNameOnly, boolean includeAll) {
|
||||
public static String getCustomName(GeyserSession session, DataComponents components, ItemMapping mapping,
|
||||
char translationColor, boolean customNameOnly, boolean includeAll) {
|
||||
if (components != null) {
|
||||
// If the tooltip is hidden entirely, return an empty custom name
|
||||
if (TooltipOptions.hideTooltip(components)) {
|
||||
return ""; // TODO test this
|
||||
}
|
||||
|
||||
// ItemStack#getHoverName as of 1.20.5
|
||||
Component customName = components.get(DataComponentTypes.CUSTOM_NAME);
|
||||
if (customName != null) {
|
||||
return MessageTranslator.convertMessage(customName, session.locale());
|
||||
}
|
||||
|
||||
if (!customNameOnly) {
|
||||
if (mapping.getJavaItem() instanceof PotionItem) {
|
||||
PotionContents potionContents = components.get(DataComponentTypes.POTION_CONTENTS);
|
||||
if (potionContents != null) {
|
||||
// TODO 1.21.5
|
||||
String potionName = getPotionName(potionContents, mapping, false /*components.get(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP) != null */, session.locale());
|
||||
String potionName = getPotionName(potionContents, mapping, session.locale()); // TODO also test this
|
||||
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(DataComponentTypes.WRITTEN_BOOK_CONTENT);
|
||||
@@ -561,6 +555,7 @@ public final class ItemTranslator {
|
||||
return ChatColor.RESET + ChatColor.ESCAPE + translationColor + bookContent.getTitle().getRaw();
|
||||
}
|
||||
}
|
||||
|
||||
customName = components.get(DataComponentTypes.ITEM_NAME);
|
||||
if (customName != null) {
|
||||
// Get the translated name and prefix it with a reset char to prevent italics - matches Java Edition
|
||||
|
||||
@@ -30,6 +30,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
||||
import org.cloudburstmc.math.vector.Vector3d;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
@@ -40,6 +41,8 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.InventoryTra
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.transaction.LegacySetItemSlotData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.InventoryTransactionPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
@@ -49,6 +52,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.click.Click;
|
||||
import org.geysermc.geyser.inventory.item.GeyserInstrument;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.BlockItem;
|
||||
import org.geysermc.geyser.item.type.BoatItem;
|
||||
@@ -74,12 +78,15 @@ import org.geysermc.geyser.util.CooldownUtils;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
import org.geysermc.geyser.util.SoundUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.InstrumentComponent;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerClickPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket;
|
||||
@@ -380,30 +387,29 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
session.setCurrentBook(packet.getItemInHand());
|
||||
} else if (session.getPlayerInventory().getItemInHand().asItem() == Items.GOAT_HORN) {
|
||||
// Temporary workaround while we don't have full item/block use tracking.
|
||||
// TODO 1.21.5
|
||||
if (!session.getWorldCache().hasCooldown(session.getPlayerInventory().getItemInHand())) {
|
||||
// Holder<Instrument> holder = session.getPlayerInventory()
|
||||
// .getItemInHand()
|
||||
// .getComponent(DataComponentTypes.INSTRUMENT);
|
||||
// if (holder != null) {
|
||||
// GeyserInstrument instrument = GeyserInstrument.fromComponent(session, holder);
|
||||
// if (instrument.bedrockInstrument() != null) {
|
||||
// // BDS uses a LevelSoundEvent2Packet, but that doesn't work here... (as of 1.21.20)
|
||||
// LevelSoundEventPacket soundPacket = new LevelSoundEventPacket();
|
||||
// soundPacket.setSound(SoundEvent.valueOf("GOAT_CALL_" + instrument.bedrockInstrument().ordinal()));
|
||||
// soundPacket.setPosition(session.getPlayerEntity().getPosition());
|
||||
// soundPacket.setIdentifier("minecraft:player");
|
||||
// soundPacket.setExtraData(-1);
|
||||
// session.sendUpstreamPacket(soundPacket);
|
||||
// } else {
|
||||
// PlaySoundPacket playSoundPacket = new PlaySoundPacket();
|
||||
// playSoundPacket.setPosition(session.getPlayerEntity().position());
|
||||
// playSoundPacket.setSound(SoundUtils.translatePlaySound(instrument.soundEvent()));
|
||||
// playSoundPacket.setPitch(1.0F);
|
||||
// playSoundPacket.setVolume(instrument.range() / 16.0F);
|
||||
// session.sendUpstreamPacket(playSoundPacket);
|
||||
// }
|
||||
// }
|
||||
InstrumentComponent component = session.getPlayerInventory()
|
||||
.getItemInHand()
|
||||
.getComponent(DataComponentTypes.INSTRUMENT);
|
||||
if (component != null) {
|
||||
GeyserInstrument instrument = GeyserInstrument.fromComponent(session, component);
|
||||
if (instrument.bedrockInstrument() != null) {
|
||||
// BDS uses a LevelSoundEvent2Packet, but that doesn't work here... (as of 1.21.20)
|
||||
LevelSoundEventPacket soundPacket = new LevelSoundEventPacket();
|
||||
soundPacket.setSound(SoundEvent.valueOf("GOAT_CALL_" + instrument.bedrockInstrument().ordinal()));
|
||||
soundPacket.setPosition(session.getPlayerEntity().getPosition());
|
||||
soundPacket.setIdentifier("minecraft:player");
|
||||
soundPacket.setExtraData(-1);
|
||||
session.sendUpstreamPacket(soundPacket);
|
||||
} else {
|
||||
PlaySoundPacket playSoundPacket = new PlaySoundPacket();
|
||||
playSoundPacket.setPosition(session.getPlayerEntity().position());
|
||||
playSoundPacket.setSound(SoundUtils.translatePlaySound(instrument.soundEvent()));
|
||||
playSoundPacket.setPitch(1.0F);
|
||||
playSoundPacket.setVolume(instrument.range() / 16.0F);
|
||||
session.sendUpstreamPacket(playSoundPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user