From 1a7b57018e3040d2bcdee27ed496ca2ddf17663f Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Wed, 25 May 2022 21:48:38 -0400 Subject: [PATCH] Chat messages now show up correctly. --- .../geysermc/geyser/level/JavaDimension.java | 2 +- .../geyser/session/GeyserSession.java | 3 +- .../geysermc/geyser/text/TextDecoration.java | 93 +++++++++++++++++++ .../translator/level/BiomeTranslator.java | 2 +- .../event/SoundEventEventTranslator.java | 2 +- .../protocol/java/JavaLoginTranslator.java | 28 ++---- .../java/JavaPlayerChatTranslator.java | 32 ++++++- .../java/JavaSystemChatTranslator.java | 1 - .../geysermc/geyser/util/JavaCodecEntry.java | 4 +- 9 files changed, 139 insertions(+), 28 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/text/TextDecoration.java diff --git a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java index 45ccf3821..5f3c96b86 100644 --- a/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java +++ b/core/src/main/java/org/geysermc/geyser/level/JavaDimension.java @@ -39,7 +39,7 @@ import java.util.Map; public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale) { public static void load(CompoundTag tag, Map map) { - for (CompoundTag dimension : JavaCodecEntry.iterateOverTag(tag.get("minecraft:dimension_type"))) { + for (CompoundTag dimension : JavaCodecEntry.iterateAsTag(tag.get("minecraft:dimension_type"))) { CompoundTag elements = dimension.get("element"); int minY = ((IntTag) elements.get("min_y")).getValue(); int maxY = ((IntTag) elements.get("height")).getValue(); diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 357e964ea..13f00e68f 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -121,6 +121,7 @@ import org.geysermc.geyser.session.cache.*; import org.geysermc.geyser.skin.FloodgateSkinUploader; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.MinecraftLocale; +import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.*; @@ -333,7 +334,7 @@ public class GeyserSession implements GeyserConnection, CommandSender { */ private final Map dimensions = new Object2ObjectOpenHashMap<>(3); - private final Map chatTypes = new EnumMap<>(MessageType.class); + private final Map chatTypes = new EnumMap<>(MessageType.class); @Setter private int breakingBlock; diff --git a/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java new file mode 100644 index 000000000..296cacaf5 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/text/TextDecoration.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019-2022 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.text; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; + +import java.util.EnumSet; +import java.util.Locale; +import java.util.Set; + +public final class TextDecoration { + private final String translationKey; + private final Style style; + private final Set parameters; + + public TextDecoration(CompoundTag tag) { + translationKey = (String) tag.get("translation_key").getValue(); + + CompoundTag styleTag = tag.get("style"); + Style.Builder builder = Style.style(); + StringTag color = styleTag.get("color"); + if (color != null) { + builder.color(NamedTextColor.NAMES.value(color.getValue())); + } + //TODO implement the rest + Tag italic = styleTag.get("italic"); + if (italic != null && ((Number) italic.getValue()).byteValue() == (byte) 1) { + builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC); + } + style = builder.build(); + + this.parameters = EnumSet.noneOf(Parameter.class); + ListTag parameters = tag.get("parameters"); + for (Tag parameter : parameters) { + this.parameters.add(Parameter.valueOf(((String) parameter.getValue()).toUpperCase(Locale.ROOT))); + } + } + + public String translationKey() { + return translationKey; + } + + public Style style() { + return style; + } + + public Set parameters() { + return parameters; + } + + @Override + public String toString() { + return "TextDecoration{" + + "translationKey='" + translationKey + '\'' + + ", style=" + style + + ", parameters=" + parameters + + '}'; + } + + public enum Parameter { + CONTENT, + SENDER, + TEAM_NAME + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java index 24b6f950f..537c93a41 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/BiomeTranslator.java @@ -56,7 +56,7 @@ public class BiomeTranslator { ListTag serverBiomes = worldGen.get("value"); session.setBiomeGlobalPalette(MathUtils.getGlobalPaletteForSize(serverBiomes.size())); - for (CompoundTag biomeTag : JavaCodecEntry.iterateOverTag(worldGen)) { + for (CompoundTag biomeTag : JavaCodecEntry.iterateAsTag(worldGen)) { String javaIdentifier = ((StringTag) biomeTag.get("name")).getValue(); int bedrockId = Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0); int javaId = ((IntTag) biomeTag.get("id")).getValue(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java index 049870114..1cb3670fb 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/level/event/SoundEventEventTranslator.java @@ -40,7 +40,7 @@ public record SoundEventEventTranslator(SoundEvent soundEvent, levelSoundEvent.setIdentifier(identifier); levelSoundEvent.setExtraData(extraData); levelSoundEvent.setRelativeVolumeDisabled(packet.isBroadcast()); - levelSoundEvent.setPosition(Vector3f.from(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ()).add(0.5f, 0.5f, 0.5f)); + levelSoundEvent.setPosition(Vector3f.from(packet.getPosition().getX() + 0.5f, packet.getPosition().getY() + 0.5f, packet.getPosition().getZ() + 0.5f)); levelSoundEvent.setBabySound(false); session.sendUpstreamPacket(levelSoundEvent); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java index 5a8eaaaa6..46e9b2f12 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java @@ -28,7 +28,6 @@ package org.geysermc.geyser.translator.protocol.java; import com.github.steveice10.mc.protocol.data.game.MessageType; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket; -import com.github.steveice10.opennbt.SNBTIO; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.nukkitx.protocol.bedrock.data.GameRuleData; @@ -41,6 +40,7 @@ import org.geysermc.geyser.entity.type.player.PlayerEntity; import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.auth.AuthType; +import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.level.BiomeTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -49,9 +49,6 @@ import org.geysermc.geyser.util.DimensionUtils; import org.geysermc.geyser.util.JavaCodecEntry; import org.geysermc.geyser.util.PluginMessageUtils; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.Map; @Translator(packet = ClientboundLoginPacket.class) @@ -67,28 +64,21 @@ public class JavaLoginTranslator extends PacketTranslator chatTypes = session.getChatTypes(); + chatTypes.clear(); + for (CompoundTag tag : JavaCodecEntry.iterateAsTag(packet.getDimensionCodec().get("minecraft:chat_type"))) { int id = ((IntTag) tag.get("id")).getValue(); - MessageType type = MessageType.values()[id]; CompoundTag element = tag.get("element"); CompoundTag chat = element.get("chat"); if (chat == null) { continue; } - - try (ByteArrayOutputStream out = new ByteArrayOutputStream(); SNBTIO.StringifiedNBTWriter nbtWriter = new SNBTIO.StringifiedNBTWriter(out)) { - nbtWriter.writeTag(chat, false); - System.out.println(out.toString(StandardCharsets.UTF_8)); - } catch (IOException e) { - e.printStackTrace(); + CompoundTag decoration = chat.get("decoration"); + if (decoration == null) { + continue; } + MessageType type = MessageType.VALUES[id]; + chatTypes.put(type, new TextDecoration(decoration)); } // If the player is already initialized and a join game packet is sent, they diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java index 22e4d95ac..be1635fdd 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaPlayerChatTranslator.java @@ -28,17 +28,22 @@ package org.geysermc.geyser.translator.protocol.java; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerChatPacket; import com.nukkitx.protocol.bedrock.packet.TextPacket; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TranslatableComponent; import org.geysermc.geyser.session.GeyserSession; +import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.text.MessageTranslator; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + @Translator(packet = ClientboundPlayerChatPacket.class) public class JavaPlayerChatTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, ClientboundPlayerChatPacket packet) { - System.out.println(packet); TextPacket textPacket = new TextPacket(); textPacket.setPlatformChatId(""); textPacket.setSourceName(""); @@ -53,7 +58,30 @@ public class JavaPlayerChatTranslator extends PacketTranslator parameters = decoration.parameters(); + List args = new ArrayList<>(3); + if (parameters.contains(TextDecoration.Parameter.TEAM_NAME)) { + args.add(packet.getSenderTeamName()); + } + if (parameters.contains(TextDecoration.Parameter.SENDER)) { + args.add(packet.getSenderName()); + } + if (parameters.contains(TextDecoration.Parameter.CONTENT)) { + args.add(message); + } + withDecoration.args(args); + textPacket.setMessage(MessageTranslator.convertMessage(withDecoration.build(), session.getLocale())); + } else { + textPacket.setMessage(MessageTranslator.convertMessage(message, session.getLocale())); + } session.sendUpstreamPacket(textPacket); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java index a22360e30..b82f2e194 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaSystemChatTranslator.java @@ -37,7 +37,6 @@ public class JavaSystemChatTranslator extends PacketTranslator iterateOverTag(CompoundTag tag) { + public static Iterable iterateAsTag(CompoundTag tag) { ListTag value = tag.get("value"); Iterator originalIterator = value.iterator(); return new Iterable<>() {