Painting re-implemented. Started on enchantments

This commit is contained in:
Camotoy 2024-06-02 20:42:53 -04:00
parent 214cc5a824
commit 65fd409a00
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
15 changed files with 187 additions and 117 deletions

View file

@ -30,6 +30,8 @@ import org.cloudburstmc.protocol.bedrock.packet.AddPaintingPacket;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.level.PaintingType;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.PaintingVariant;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
@ -49,8 +51,14 @@ public class PaintingEntity extends Entity {
// Wait until we get the metadata needed
}
public void setPaintingType(ObjectEntityMetadata<org.geysermc.mcprotocollib.protocol.data.game.entity.type.PaintingType> entityMetadata) {
PaintingType type = PaintingType.getByPaintingType(entityMetadata.getValue());
public void setPaintingType(ObjectEntityMetadata<Holder<PaintingVariant>> entityMetadata) {
if (!entityMetadata.getValue().isId()) {
return;
}
PaintingType type = session.getRegistryCache().paintings().byId(entityMetadata.getValue().id());
if (type == null) {
return;
}
AddPaintingPacket addPaintingPacket = new AddPaintingPacket();
addPaintingPacket.setUniqueEntityId(geyserId);
addPaintingPacket.setRuntimeEntityId(geyserId);
@ -79,7 +87,7 @@ public class PaintingEntity extends Entity {
private Vector3f fixOffset(PaintingType paintingName) {
Vector3f position = super.position;
position = position.add(0.5, 0.5, 0.5);
double widthOffset = paintingName.getWidth() > 1 ? 0.5 : 0;
double widthOffset = paintingName.getWidth() > 1 && paintingName.getWidth() != 3 ? 0.5 : 0;
double heightOffset = paintingName.getHeight() > 1 && paintingName.getHeight() != 3 ? 0.5 : 0;
return switch (direction) {

View file

@ -36,33 +36,25 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.inventory.item.Enchantment;
import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.type.DyeItem;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.tags.ItemTag;
import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag;
import org.geysermc.geyser.util.ItemUtils;
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.WolfVariant;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
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.item.ItemStack;
import java.util.Collections;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
public class WolfEntity extends TameableEntity {
/**
* A list of all foods a wolf can eat on Java Edition.
* Used to display interactive tag or particles if needed.
* TODO generate
*/
private static final Set<Item> WOLF_FOODS = Set.of(Items.PUFFERFISH, Items.TROPICAL_FISH, Items.CHICKEN, Items.COOKED_CHICKEN,
Items.PORKCHOP, Items.BEEF, Items.RABBIT, Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.ROTTEN_FLESH, Items.MUTTON, Items.COOKED_MUTTON,
Items.COOKED_RABBIT);
private byte collarColor = 14; // Red - default
private boolean isCurseOfBinding = false;
@ -112,12 +104,14 @@ public class WolfEntity extends TameableEntity {
}
// 1.20.5+
public void setWolfVariant(IntEntityMetadata entityMetadata) {
WolfVariant wolfVariant = session.getRegistryCache().wolfVariants().byId(entityMetadata.getPrimitiveValue());
if (wolfVariant == null) {
wolfVariant = WolfVariant.PALE;
}
dirtyMetadata.put(EntityDataTypes.VARIANT, wolfVariant.ordinal());
public void setWolfVariant(ObjectEntityMetadata<Holder<WolfVariant>> entityMetadata) {
entityMetadata.getValue().ifId(id -> {
BuiltInWolfVariant wolfVariant = session.getRegistryCache().wolfVariants().byId(id);
if (wolfVariant == null) {
wolfVariant = BuiltInWolfVariant.PALE;
}
dirtyMetadata.put(EntityDataTypes.VARIANT, wolfVariant.ordinal());
});
}
@Override
@ -187,7 +181,7 @@ public class WolfEntity extends TameableEntity {
}
// Ordered by bedrock id
public enum WolfVariant {
public enum BuiltInWolfVariant {
PALE,
ASHEN,
BLACK,
@ -198,16 +192,16 @@ public class WolfEntity extends TameableEntity {
STRIPED,
WOODS;
private static final WolfVariant[] VALUES = values();
private static final BuiltInWolfVariant[] VALUES = values();
private final String javaIdentifier;
WolfVariant() {
BuiltInWolfVariant() {
this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ROOT);
}
public static @Nullable WolfVariant getByJavaIdentifier(String javaIdentifier) {
for (WolfVariant wolfVariant : VALUES) {
public static @Nullable BuiltInWolfVariant getByJavaIdentifier(String javaIdentifier) {
for (BuiltInWolfVariant wolfVariant : VALUES) {
if (wolfVariant.javaIdentifier.equals(javaIdentifier)) {
return wolfVariant;
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2024 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.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.nbt.NbtMap;
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
/**
* @param anvilCost also as a rarity multiplier
*/
public record Enchantment(String supportedItemsTag, int maxLevel, int anvilCost, @Nullable String exclusiveSetTag) {
// Implementation note: I have a feeling the tags can be a list of items, because in vanilla they're HolderSet classes.
// I'm not sure how that's wired over the network, so we'll put it off.
public static Enchantment read(RegistryEntry entry) {
NbtMap data = entry.getData();
String supportedItems = data.getString("supported_items");
int maxLevel = data.getInt("max_level");
int anvilCost = data.getInt("anvil_cost");
String exclusiveSet = data.getString("exclusive_set", null);
return new Enchantment(supportedItems, maxLevel, anvilCost, exclusiveSet);
}
}

View file

@ -146,8 +146,8 @@ public class BannerItem extends BlockItem {
} else {
List<NbtMap> patternList = new ArrayList<>(patterns.size());
for (BannerPatternLayer patternLayer : patterns) {
patternLayer.getPattern().ifId(holder -> {
BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().byId(holder.id());
patternLayer.getPattern().ifId(id -> {
BannerPattern bannerPattern = session.getRegistryCache().bannerPatterns().byId(id);
if (bannerPattern != null) {
NbtMap tag = NbtMap.builder()
.putString("Pattern", bannerPattern.getBedrockIdentifier())

View file

@ -29,6 +29,8 @@ import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Locale;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public enum PaintingType {
@ -61,7 +63,27 @@ public enum PaintingType {
EARTH("Earth", 2, 2),
WIND("Wind", 2, 2),
WATER("Water", 2, 2),
FIRE("Fire", 2, 2);
FIRE("Fire", 2, 2),
MEDITATIVE("meditative", 1, 1),
PRAIRIE_RIDE("prairie_ride", 1, 2),
BAROQUE("baroque", 2, 2),
HUMBLE("humble", 2, 2),
UNPACKED("unpacked", 4, 4),
BACKYARD("backyard", 3, 4),
BOUQUET("bouquet", 3, 3),
CAVEBIRD("cavebird", 3, 3),
CHANGING("changing", 4, 2),
COTAN("cotan", 3, 3),
ENDBOSS("endboss", 3, 3),
FERN("fern", 3, 3),
FINDING("finding", 4, 2),
LOWMIST("lowmist", 4, 2),
ORB("orb", 4, 4),
OWLEMONS("owlemons", 3, 3),
PASSAGE("passage", 4, 2),
POND("pond", 3, 4),
SUNFLOWERS("sunflowers", 3, 3),
TIDES("tides", 3, 3);
private static final PaintingType[] VALUES = values();
private final String bedrockName;
@ -70,12 +92,8 @@ public enum PaintingType {
public static PaintingType getByName(String javaName) {
for (PaintingType paintingName : VALUES) {
if (paintingName.name().equalsIgnoreCase(javaName)) return paintingName;
if (("minecraft:" + paintingName.name().toLowerCase(Locale.ROOT)).equals(javaName)) return paintingName;
}
return KEBAB;
}
public static PaintingType getByPaintingType(org.geysermc.mcprotocollib.protocol.data.game.entity.type.PaintingType paintingType) {
return getByName(paintingType.name());
return null;
}
}

View file

@ -44,7 +44,7 @@ public class Conversion685_671 {
private static final List<String> MODIFIED_BLOCKS = Stream.of(NEW_BLOCKS, OMINOUS_BLOCKS).flatMap(List::stream).toList();
private static final List<Item> NEW_MUSIC_DISCS = List.of(Items.MUSIC_DISC_CREATOR, Items.MUSIC_DISC_CREATOR_MUSIC_BOX, Items.MUSIC_DISC_PRECIPICE);
static GeyserMappingItem remapItem(@SuppressWarnings("unused") Item item, GeyserMappingItem mapping) {
static GeyserMappingItem remapItem(Item item, GeyserMappingItem mapping) {
String identifer = mapping.getBedrockIdentifier();
if (NEW_MUSIC_DISCS.contains(item)) {

View file

@ -1302,22 +1302,28 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
}
}
/**
* Convenience method to reduce amount of duplicate code. Sends ServerboundUseItemPacket.
*/
public void useItem(Hand hand) {
sendDownstreamGamePacket(new ServerboundUseItemPacket(
hand, worldCache.nextPredictionSequence(), playerEntity.getPitch(), playerEntity.getYaw()));
}
/**
* Checks to see if a shield is in either hand to activate blocking. If so, it sets the Bedrock client to display
* blocking and sends a packet to the Java server.
*/
private boolean attemptToBlock() {
ServerboundUseItemPacket useItemPacket;
if (playerInventory.getItemInHand().asItem() == Items.SHIELD) {
useItemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND, worldCache.nextPredictionSequence());
useItem(Hand.MAIN_HAND);
} else if (playerInventory.getOffhand().asItem() == Items.SHIELD) {
useItemPacket = new ServerboundUseItemPacket(Hand.OFF_HAND, worldCache.nextPredictionSequence());
useItem(Hand.OFF_HAND);
} else {
// No blocking
return false;
}
sendDownstreamGamePacket(useItemPacket);
playerEntity.setFlag(EntityFlag.BLOCKING, true);
// Metadata should be updated later
return true;

View file

@ -38,7 +38,9 @@ import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity;
import org.geysermc.geyser.inventory.item.BannerPattern;
import org.geysermc.geyser.inventory.recipe.TrimRecipe;
import org.geysermc.geyser.item.Enchantment;
import org.geysermc.geyser.level.JavaDimension;
import org.geysermc.geyser.level.PaintingType;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.registry.JavaRegistry;
import org.geysermc.geyser.session.cache.registry.SimpleJavaRegistry;
@ -46,6 +48,7 @@ import org.geysermc.geyser.text.TextDecoration;
import org.geysermc.geyser.translator.level.BiomeTranslator;
import org.geysermc.mcprotocollib.protocol.MinecraftProtocol;
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatType;
import org.geysermc.mcprotocollib.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket;
import java.util.ArrayList;
@ -72,11 +75,13 @@ public final class RegistryCache {
static {
register("chat_type", cache -> cache.chatTypes, ($, entry) -> TextDecoration.readChatType(entry));
register("dimension_type", cache -> cache.dimensions, ($, entry) -> JavaDimension.read(entry));
register("enchantment", cache -> cache.enchantments, ($, entry) -> Enchantment.read(entry));
register("painting_variant", cache -> cache.paintings, ($, entry) -> PaintingType.getByName(entry.getId()));
register("trim_material", cache -> cache.trimMaterials, TrimRecipe::readTrimMaterial);
register("trim_pattern", cache -> cache.trimPatterns, TrimRecipe::readTrimPattern);
register("worldgen/biome", (cache, array) -> cache.biomeTranslations = array, BiomeTranslator::loadServerBiome);
register("banner_pattern", cache -> cache.bannerPatterns, ($, entry) -> BannerPattern.getByJavaIdentifier(entry.getId()));
register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.WolfVariant.getByJavaIdentifier(entry.getId()));
register("wolf_variant", cache -> cache.wolfVariants, ($, entry) -> WolfEntity.BuiltInWolfVariant.getByJavaIdentifier(entry.getId()));
// Load from MCProtocolLib's classloader
NbtMap tag = MinecraftProtocol.loadNetworkCodec();
@ -104,16 +109,18 @@ public final class RegistryCache {
* Java -> Bedrock biome network IDs.
*/
private int[] biomeTranslations;
private final JavaRegistry<TextDecoration> chatTypes = new SimpleJavaRegistry<>();
private final JavaRegistry<ChatType> chatTypes = new SimpleJavaRegistry<>();
/**
* All dimensions that the client could possibly connect to.
*/
private final JavaRegistry<JavaDimension> dimensions = new SimpleJavaRegistry<>();
private final JavaRegistry<Enchantment> enchantments = new SimpleJavaRegistry<>();
private final JavaRegistry<PaintingType> paintings = new SimpleJavaRegistry<>();
private final JavaRegistry<TrimMaterial> trimMaterials = new SimpleJavaRegistry<>();
private final JavaRegistry<TrimPattern> trimPatterns = new SimpleJavaRegistry<>();
private final JavaRegistry<BannerPattern> bannerPatterns = new SimpleJavaRegistry<>();
private final JavaRegistry<WolfEntity.WolfVariant> wolfVariants = new SimpleJavaRegistry<>();
private final JavaRegistry<WolfEntity.BuiltInWolfVariant> wolfVariants = new SimpleJavaRegistry<>();
public RegistryCache(GeyserSession session) {
this.session = session;

View file

@ -57,4 +57,9 @@ public class SimpleJavaRegistry<T> implements JavaRegistry<T> {
public List<T> values() {
return this.values;
}
@Override
public String toString() {
return this.values.toString();
}
}

View file

@ -30,21 +30,49 @@ import net.kyori.adventure.text.format.Style;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.nbt.NbtType;
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatType;
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatTypeDecoration;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.*;
public final class TextDecoration {
private final String translationKey;
private final Style style;
private final Set<Parameter> parameters;
public record TextDecoration(String translationKey, List<Parameter> parameters, Style deserializedStyle) implements ChatTypeDecoration {
public TextDecoration(NbtMap tag) {
translationKey = tag.getString("translation_key");
@Override
public NbtMap style() {
// Should not ever be called.
throw new UnsupportedOperationException();
}
NbtMap styleTag = tag.getCompound("style");
public static ChatType readChatType(RegistryEntry entry) {
// Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla.
// (This note has been passed around through several classes and iterations. It stays as a warning
// to anyone that dares to try and hardcode registry IDs.)
NbtMap tag = entry.getData();
NbtMap chat = tag.getCompound("chat", null);
if (chat != null) {
String translationKey = tag.getString("translation_key");
NbtMap styleTag = tag.getCompound("style");
Style style = deserializeStyle(styleTag);
List<ChatTypeDecoration.Parameter> parameters = new ArrayList<>();
List<String> parametersNbt = tag.getList("parameters", NbtType.STRING);
for (String parameter : parametersNbt) {
parameters.add(ChatTypeDecoration.Parameter.valueOf(parameter.toUpperCase(Locale.ROOT)));
}
return new ChatType(new TextDecoration(translationKey, parameters, style), null);
}
return new ChatType(null, null);
}
public static Style getStyle(ChatTypeDecoration decoration) {
if (decoration instanceof TextDecoration textDecoration) {
return textDecoration.deserializedStyle();
}
return deserializeStyle(decoration.style());
}
private static Style deserializeStyle(NbtMap styleTag) {
Style.Builder builder = Style.style();
if (!styleTag.isEmpty()) {
String color = styleTag.getString("color", null);
@ -57,50 +85,6 @@ public final class TextDecoration {
builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC);
}
}
style = builder.build();
this.parameters = EnumSet.noneOf(Parameter.class);
List<String> parameters = tag.getList("parameters", NbtType.STRING);
for (String parameter : parameters) {
this.parameters.add(Parameter.valueOf(parameter.toUpperCase(Locale.ROOT)));
}
}
public String translationKey() {
return translationKey;
}
public Style style() {
return style;
}
public Set<Parameter> parameters() {
return parameters;
}
@Override
public String toString() {
return "TextDecoration{" +
"translationKey='" + translationKey + '\'' +
", style=" + style +
", parameters=" + parameters +
'}';
}
public static TextDecoration readChatType(RegistryEntry entry) {
// Note: The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla.
NbtMap tag = entry.getData();
NbtMap chat = tag.getCompound("chat", null);
TextDecoration textDecoration = null;
if (chat != null) {
textDecoration = new TextDecoration(chat);
}
return textDecoration;
}
public enum Parameter {
CONTENT,
SENDER,
TARGET
return builder.build();
}
}

View file

@ -394,8 +394,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
}
}
ServerboundUseItemPacket useItemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND, session.getWorldCache().nextPredictionSequence());
session.sendDownstreamGamePacket(useItemPacket);
session.useItem(Hand.MAIN_HAND);
List<LegacySetItemSlotData> legacySlots = packet.getLegacySlots();
if (packet.getActions().size() == 1 && !legacySlots.isEmpty()) {
@ -639,8 +638,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
Vector3f target = packet.getBlockPosition().toFloat().add(packet.getClickPosition());
lookAt(session, target);
ServerboundUseItemPacket itemPacket = new ServerboundUseItemPacket(Hand.MAIN_HAND, session.getWorldCache().nextPredictionSequence());
session.sendDownstreamGamePacket(itemPacket);
session.useItem(Hand.MAIN_HAND);
return true;
}

View file

@ -25,9 +25,6 @@
package org.geysermc.geyser.translator.protocol.bedrock;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSetCarriedItemPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket;
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket;
import org.geysermc.geyser.inventory.GeyserItemStack;
@ -36,6 +33,8 @@ import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.util.CooldownUtils;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSetCarriedItemPacket;
import java.util.concurrent.TimeUnit;
@ -66,7 +65,7 @@ public class BedrockMobEquipmentTranslator extends PacketTranslator<MobEquipment
// Activate shield since we are already sneaking
// (No need to send a release item packet - Java doesn't do this when swapping items)
// Required to do it a tick later or else it doesn't register
session.scheduleInEventLoop(() -> session.sendDownstreamGamePacket(new ServerboundUseItemPacket(Hand.MAIN_HAND, session.getWorldCache().nextPredictionSequence())),
session.scheduleInEventLoop(() -> session.useItem(Hand.MAIN_HAND),
50, TimeUnit.MILLISECONDS);
}

View file

@ -53,7 +53,7 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
entity.resetMetadata();
}
if (!packet.isKeepAttributes()) {
if (!packet.isKeepAttributeModifiers()) {
entity.resetAttributes();
}

View file

@ -25,8 +25,6 @@
package org.geysermc.geyser.translator.text;
import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer;
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ScoreComponent;
import net.kyori.adventure.text.TranslatableComponent;
@ -41,6 +39,11 @@ import org.cloudburstmc.protocol.bedrock.packet.TextPacket;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.*;
import org.geysermc.mcprotocollib.protocol.data.DefaultComponentSerializer;
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatType;
import org.geysermc.mcprotocollib.protocol.data.game.chat.ChatTypeDecoration;
import org.geysermc.mcprotocollib.protocol.data.game.scoreboard.TeamColor;
import java.util.*;
@ -321,7 +324,7 @@ public class MessageTranslator {
return PlainTextComponentSerializer.plainText().serialize(messageComponent);
}
public static void handleChatPacket(GeyserSession session, Component message, int chatType, Component targetName, Component sender) {
public static void handleChatPacket(GeyserSession session, Component message, Holder<ChatType> chatTypeHolder, Component targetName, Component sender) {
TextPacket textPacket = new TextPacket();
textPacket.setPlatformChatId("");
textPacket.setSourceName("");
@ -330,14 +333,15 @@ public class MessageTranslator {
textPacket.setNeedsTranslation(false);
TextDecoration decoration = session.getRegistryCache().chatTypes().byId(chatType);
if (decoration != null) {
ChatType chatType = chatTypeHolder.getOrCompute(session.getRegistryCache().chatTypes()::byId);
if (chatType != null && chatType.chat() != null) {
var chat = chatType.chat();
// As of 1.19 - do this to apply all the styling for signed messages
// Though, Bedrock cannot care about the signed stuff.
TranslatableComponent.Builder withDecoration = Component.translatable()
.key(decoration.translationKey())
.style(decoration.style());
Set<TextDecoration.Parameter> parameters = decoration.parameters();
.key(chat.translationKey())
.style(TextDecoration.getStyle(chat));
List<ChatTypeDecoration.Parameter> parameters = chat.parameters();
List<Component> args = new ArrayList<>(3);
if (parameters.contains(TextDecoration.Parameter.TARGET)) {
args.add(targetName);
@ -348,7 +352,7 @@ public class MessageTranslator {
if (parameters.contains(TextDecoration.Parameter.CONTENT)) {
args.add(message);
}
withDecoration.args(args);
withDecoration.arguments(args);
textPacket.setMessage(MessageTranslator.convertMessage(withDecoration.build(), session.locale()));
} else {
session.getGeyser().getLogger().debug("Likely illegal chat type detection found.");

View file

@ -13,7 +13,7 @@ websocket = "1.5.1"
protocol = "3.0.0.Beta2-20240520.153053-5"
raknet = "1.0.0.CR3-20240416.144209-1"
mcauthlib = "e5b0bcc"
mcprotocollib = "1.20.6-2-20240520.030045-8"
mcprotocollib = "1.21-SNAPSHOT"
adventure = "4.14.0"
adventure-platform = "4.3.0"
junit = "5.9.2"