diff --git a/connector/pom.xml b/connector/pom.xml index d7017b0d..6da797b3 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -110,13 +110,17 @@ com.github.steveice10 mcprotocollib - 86e1901be5 + 26201a4 compile io.netty netty-all + + net.kyori + adventure-text-serializer-gson + @@ -136,21 +140,21 @@ 2.1.3 - com.github.kyoripowered.adventure + net.kyori adventure-api - 7acd956 + 4.2.0 compile - com.github.kyoripowered.adventure + net.kyori adventure-text-serializer-gson - 7acd956 + 4.2.0 compile - com.github.kyoripowered.adventure + net.kyori adventure-text-serializer-legacy - 7acd956 + 4.2.0 compile diff --git a/connector/src/main/java/org/geysermc/connector/entity/CommandBlockMinecartEntity.java b/connector/src/main/java/org/geysermc/connector/entity/CommandBlockMinecartEntity.java index 7d34cc79..634dfa65 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/CommandBlockMinecartEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/CommandBlockMinecartEntity.java @@ -28,6 +28,7 @@ package org.geysermc.connector.entity; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import net.kyori.adventure.text.Component; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockTranslator; @@ -50,7 +51,7 @@ public class CommandBlockMinecartEntity extends DefaultBlockMinecartEntity { metadata.put(EntityData.COMMAND_BLOCK_COMMAND, entityMetadata.getValue()); } if (entityMetadata.getId() == 14) { - metadata.put(EntityData.COMMAND_BLOCK_LAST_OUTPUT, MessageTranslator.convertMessage(entityMetadata.getValue().toString())); + metadata.put(EntityData.COMMAND_BLOCK_LAST_OUTPUT, MessageTranslator.convertMessage((Component) entityMetadata.getValue())); } super.updateBedrockMetadata(entityMetadata, session); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/Entity.java b/connector/src/main/java/org/geysermc/connector/entity/Entity.java index 8f153e6a..592165ab 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -32,7 +32,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace; -import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket; import com.nukkitx.math.vector.Vector3f; @@ -45,6 +44,7 @@ import com.nukkitx.protocol.bedrock.packet.*; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import lombok.Getter; import lombok.Setter; +import net.kyori.adventure.text.Component; import org.geysermc.connector.entity.attribute.Attribute; import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.living.ArmorStandEntity; @@ -313,11 +313,11 @@ public class Entity { } break; case 2: // custom name - if (entityMetadata.getValue() instanceof Message) { - Message message = (Message) entityMetadata.getValue(); + if (entityMetadata.getValue() instanceof Component) { + Component message = (Component) entityMetadata.getValue(); if (message != null) // Always translate even if it's a TextMessage since there could be translatable parameters - metadata.put(EntityData.NAMETAG, MessageTranslator.convertMessage(message.toString(), session.getLocale())); + metadata.put(EntityData.NAMETAG, MessageTranslator.convertMessage(message, session.getLocale())); } break; case 3: // is custom name visible diff --git a/connector/src/main/java/org/geysermc/connector/entity/player/PlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/player/PlayerEntity.java index 283cf3b4..54ae492a 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/player/PlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/player/PlayerEntity.java @@ -27,7 +27,6 @@ package org.geysermc.connector.entity.player; import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; @@ -43,6 +42,7 @@ import com.nukkitx.protocol.bedrock.packet.SetEntityLinkPacket; import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket; import lombok.Getter; import lombok.Setter; +import net.kyori.adventure.text.Component; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.LivingEntity; import org.geysermc.connector.entity.attribute.Attribute; @@ -252,9 +252,9 @@ public class PlayerEntity extends LivingEntity { if (entityMetadata.getId() == 2) { String username = this.username; - TextMessage name = (TextMessage) entityMetadata.getValue(); + Component name = (Component) entityMetadata.getValue(); if (name != null) { - username = MessageTranslator.convertMessage(name.toString()); + username = MessageTranslator.convertMessage(name); } Team team = session.getWorldCache().getScoreboard().getTeamFor(username); if (team != null) { diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java index 7eadb794..877ae50c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java @@ -25,13 +25,13 @@ package org.geysermc.connector.network.session.cache; -import com.github.steveice10.mc.protocol.data.message.Message; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; import com.nukkitx.protocol.bedrock.packet.BossEventPacket; import com.nukkitx.protocol.bedrock.packet.RemoveEntityPacket; import lombok.AllArgsConstructor; +import net.kyori.adventure.text.Component; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.chat.MessageTranslator; @@ -41,7 +41,7 @@ public class BossBar { private GeyserSession session; private long entityId; - private Message title; + private Component title; private float health; private int color; private int overlay; @@ -58,7 +58,7 @@ public class BossBar { BossEventPacket bossEventPacket = new BossEventPacket(); bossEventPacket.setBossUniqueEntityId(entityId); bossEventPacket.setAction(BossEventPacket.Action.CREATE); - bossEventPacket.setTitle(MessageTranslator.convertMessage(title.toString(), session.getLocale())); + bossEventPacket.setTitle(MessageTranslator.convertMessage(title, session.getLocale())); bossEventPacket.setHealthPercentage(health); bossEventPacket.setColor(color); //ignored by client bossEventPacket.setOverlay(overlay); @@ -67,12 +67,12 @@ public class BossBar { session.sendUpstreamPacket(bossEventPacket); } - public void updateTitle(Message title) { + public void updateTitle(Component title) { this.title = title; BossEventPacket bossEventPacket = new BossEventPacket(); bossEventPacket.setBossUniqueEntityId(entityId); bossEventPacket.setAction(BossEventPacket.Action.UPDATE_NAME); - bossEventPacket.setTitle(MessageTranslator.convertMessage(title.toString(), session.getLocale())); + bossEventPacket.setTitle(MessageTranslator.convertMessage(title, session.getLocale())); session.sendUpstreamPacket(bossEventPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/chat/MessageTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/chat/MessageTranslator.java index 9d2e694b..c650e582 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/chat/MessageTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/chat/MessageTranslator.java @@ -26,12 +26,13 @@ package org.geysermc.connector.network.translators.chat; import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; -import com.github.steveice10.mc.protocol.data.message.style.ChatColor; -import com.github.steveice10.mc.protocol.data.message.style.ChatFormat; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.renderer.TranslatableComponentRenderer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.LanguageUtils; @@ -42,30 +43,24 @@ public class MessageTranslator { // These are used for handling the translations of the messages private static final TranslatableComponentRenderer RENDERER = TranslatableComponentRenderer.usingTranslationSource(new MinecraftTranslationRegistry()); + // Construct our own {@link GsonComponentSerializer} encase we need to change anything + private static final GsonComponentSerializer GSON_SERIALIZER = GsonComponentSerializer.builder() + .build(); + // Store team colors for player names - private static final Map TEAM_COLORS = new HashMap<>(); + private static final Map TEAM_FORMATS = new HashMap<>(); + + // Legacy formatting character + private static final String BASE = "\u00a7"; + + // Reset character + private static final String RESET = BASE + "r"; static { - TEAM_COLORS.put(TeamColor.BLACK, getColor(ChatColor.BLACK)); - TEAM_COLORS.put(TeamColor.DARK_BLUE, getColor(ChatColor.DARK_BLUE)); - TEAM_COLORS.put(TeamColor.DARK_GREEN, getColor(ChatColor.DARK_GREEN)); - TEAM_COLORS.put(TeamColor.DARK_AQUA, getColor(ChatColor.DARK_AQUA)); - TEAM_COLORS.put(TeamColor.DARK_RED, getColor(ChatColor.DARK_RED)); - TEAM_COLORS.put(TeamColor.DARK_PURPLE, getColor(ChatColor.DARK_PURPLE)); - TEAM_COLORS.put(TeamColor.GOLD, getColor(ChatColor.GOLD)); - TEAM_COLORS.put(TeamColor.GRAY, getColor(ChatColor.GRAY)); - TEAM_COLORS.put(TeamColor.DARK_GRAY, getColor(ChatColor.DARK_GRAY)); - TEAM_COLORS.put(TeamColor.BLUE, getColor(ChatColor.BLUE)); - TEAM_COLORS.put(TeamColor.GREEN, getColor(ChatColor.GREEN)); - TEAM_COLORS.put(TeamColor.AQUA, getColor(ChatColor.AQUA)); - TEAM_COLORS.put(TeamColor.RED, getColor(ChatColor.RED)); - TEAM_COLORS.put(TeamColor.LIGHT_PURPLE, getColor(ChatColor.LIGHT_PURPLE)); - TEAM_COLORS.put(TeamColor.YELLOW, getColor(ChatColor.YELLOW)); - TEAM_COLORS.put(TeamColor.WHITE, getColor(ChatColor.WHITE)); - TEAM_COLORS.put(TeamColor.OBFUSCATED, getFormat(ChatFormat.OBFUSCATED)); - TEAM_COLORS.put(TeamColor.BOLD, getFormat(ChatFormat.BOLD)); - TEAM_COLORS.put(TeamColor.STRIKETHROUGH, getFormat(ChatFormat.STRIKETHROUGH)); - TEAM_COLORS.put(TeamColor.ITALIC, getFormat(ChatFormat.ITALIC)); + TEAM_FORMATS.put(TeamColor.OBFUSCATED, TextDecoration.OBFUSCATED); + TEAM_FORMATS.put(TeamColor.BOLD, TextDecoration.BOLD); + TEAM_FORMATS.put(TeamColor.STRIKETHROUGH, TextDecoration.STRIKETHROUGH); + TEAM_FORMATS.put(TeamColor.ITALIC, TextDecoration.ITALIC); } /** @@ -75,30 +70,43 @@ public class MessageTranslator { * @param locale Locale to use for translation strings * @return Parsed and formatted message for bedrock */ + public static String convertMessage(Component message, String locale) { + try { + // Get a Locale from the given locale string + Locale localeCode = Locale.forLanguageTag(locale.replace('_', '-')); + message = RENDERER.render(message, localeCode); + + String legacy = LegacyComponentSerializer.legacySection().serialize(message); + + // Strip strikethrough and underline as they are not supported on bedrock + legacy = legacy.replaceAll("\u00a7[mn]", ""); + + // Make color codes reset formatting like Java + // See https://minecraft.gamepedia.com/Formatting_codes#Usage + legacy = legacy.replaceAll("\u00a7([0-9a-f])", "\u00a7r\u00a7$1"); + legacy = legacy.replaceAll("\u00a7r\u00a7r", "\u00a7r"); + + return legacy; + } catch (Exception e) { + GeyserConnector.getInstance().getLogger().debug(GSON_SERIALIZER.serialize(message)); + GeyserConnector.getInstance().getLogger().error("Failed to parse message", e); + + return ""; + } + } + public static String convertMessage(String message, String locale) { - Component component = GsonComponentSerializer.gson().deserialize(message); - - // Get a Locale from the given locale string - Locale localeCode = Locale.forLanguageTag(locale.replace('_', '-')); - component = RENDERER.render(component, localeCode); - - String legacy = LegacyComponentSerializer.legacySection().serialize(component); - - // Strip strikethrough and underline as they are not supported on bedrock - legacy = legacy.replaceAll("\u00a7[mn]", ""); - - // Make color codes reset formatting like Java - // See https://minecraft.gamepedia.com/Formatting_codes#Usage - legacy = legacy.replaceAll("\u00a7([0-9a-f])", "\u00a7r\u00a7$1"); - legacy = legacy.replaceAll("\u00a7r\u00a7r", "\u00a7r"); - - return legacy; + return convertMessage(GSON_SERIALIZER.deserialize(message), locale); } public static String convertMessage(String message) { return convertMessage(message, LanguageUtils.getDefaultLocale()); } + public static String convertMessage(Component message) { + return convertMessage(message, LanguageUtils.getDefaultLocale()); + } + /** * Verifies the message is valid JSON in case it's plaintext. Works around GsonComponentSeraializer not using lenient mode. * See https://wiki.vg/Chat for messages sent in lenient mode, and for a description on leniency. @@ -108,14 +116,18 @@ public class MessageTranslator { * @return Bedrock formatted message */ public static String convertMessageLenient(String message, String locale) { - if (isMessage(message)) { + if (message.trim().isEmpty()) { + return message; + } + + try { return convertMessage(message, locale); - } else { + } catch (Exception ignored) { String convertedMessage = convertMessage(convertToJavaMessage(message), locale); // We have to do this since Adventure strips the starting reset character - if (message.startsWith(getColor(ChatColor.RESET)) && !convertedMessage.startsWith(getColor(ChatColor.RESET))) { - convertedMessage = getColor(ChatColor.RESET) + convertedMessage; + if (message.startsWith(RESET) && !convertedMessage.startsWith(RESET)) { + convertedMessage = RESET + convertedMessage; } return convertedMessage; @@ -134,138 +146,100 @@ public class MessageTranslator { */ public static String convertToJavaMessage(String message) { Component component = LegacyComponentSerializer.legacySection().deserialize(message); - return GsonComponentSerializer.gson().serialize(component); + return GSON_SERIALIZER.serialize(component); } /** - * Checks if the given text string is a JSON message + * Convert a {@link NamedTextColor} into a string for inserting into messages * - * @param text String to test - * @return True if its a valid message JSON string, false if not - */ - public static boolean isMessage(String text) { - if (text.trim().isEmpty()) { - return false; - } - - try { - GsonComponentSerializer.gson().deserialize(text); - } catch (Exception ex) { - return false; - } - - return true; - } - - /** - * Convert a {@link ChatColor} into a string for inserting into messages - * - * @param color {@link ChatColor} to convert + * @param color {@link NamedTextColor} to convert * @return The converted color string */ - private static String getColor(String color) { - String base = "\u00a7"; - switch (color) { - case ChatColor.BLACK: - base += "0"; - break; - case ChatColor.DARK_BLUE: - base += "1"; - break; - case ChatColor.DARK_GREEN: - base += "2"; - break; - case ChatColor.DARK_AQUA: - base += "3"; - break; - case ChatColor.DARK_RED: - base += "4"; - break; - case ChatColor.DARK_PURPLE: - base += "5"; - break; - case ChatColor.GOLD: - base += "6"; - break; - case ChatColor.GRAY: - base += "7"; - break; - case ChatColor.DARK_GRAY: - base += "8"; - break; - case ChatColor.BLUE: - base += "9"; - break; - case ChatColor.GREEN: - base += "a"; - break; - case ChatColor.AQUA: - base += "b"; - break; - case ChatColor.RED: - base += "c"; - break; - case ChatColor.LIGHT_PURPLE: - base += "d"; - break; - case ChatColor.YELLOW: - base += "e"; - break; - case ChatColor.WHITE: - base += "f"; - break; - case ChatColor.RESET: - base += "r"; - break; - default: - return ""; + private static String getColor(NamedTextColor color) { + StringBuilder str = new StringBuilder(BASE); + if (color.equals(NamedTextColor.BLACK)) { + str.append("0"); + } else if (color.equals(NamedTextColor.DARK_BLUE)) { + str.append("1"); + } else if (color.equals(NamedTextColor.DARK_GREEN)) { + str.append("2"); + } else if (color.equals(NamedTextColor.DARK_AQUA)) { + str.append("3"); + } else if (color.equals(NamedTextColor.DARK_RED)) { + str.append("4"); + } else if (color.equals(NamedTextColor.DARK_PURPLE)) { + str.append("5"); + } else if (color.equals(NamedTextColor.GOLD)) { + str.append("6"); + } else if (color.equals(NamedTextColor.GRAY)) { + str.append("7"); + } else if (color.equals(NamedTextColor.DARK_GRAY)) { + str.append("8"); + } else if (color.equals(NamedTextColor.BLUE)) { + str.append("9"); + } else if (color.equals(NamedTextColor.GREEN)) { + str.append("a"); + } else if (color.equals(NamedTextColor.AQUA)) { + str.append("b"); + } else if (color.equals(NamedTextColor.RED)) { + str.append("c"); + } else if (color.equals(NamedTextColor.LIGHT_PURPLE)) { + str.append("d"); + } else if (color.equals(NamedTextColor.YELLOW)) { + str.append("e"); + } else if (color.equals(NamedTextColor.WHITE)) { + str.append("f"); + } else { + return ""; } - return base; + return str.toString(); } /** - * Convert a {@link ChatFormat} into a string for inserting into messages + * Convert a {@link TextDecoration} into a string for inserting into messages * - * @param format {@link ChatFormat} to convert + * @param format {@link TextDecoration} to convert * @return The converted chat formatting string */ - private static String getFormat(ChatFormat format) { - StringBuilder str = new StringBuilder(); - String base = "\u00a7"; + private static String getFormat(TextDecoration format) { + StringBuilder str = new StringBuilder(BASE); switch (format) { case OBFUSCATED: - base += "k"; + str.append("k"); break; case BOLD: - base += "l"; + str.append("l"); break; case STRIKETHROUGH: - base += "m"; + str.append("m"); break; case UNDERLINED: - base += "n"; + str.append("n"); break; case ITALIC: - base += "o"; + str.append("o"); break; default: return ""; } - str.append(base); - return str.toString(); } /** * Convert a team color to a chat color * - * @param teamColor + * @param teamColor Color or format to convert * @return The chat color character */ public static String toChatColor(TeamColor teamColor) { - return TEAM_COLORS.getOrDefault(teamColor, ""); + NamedTextColor textColor = NamedTextColor.NAMES.value(teamColor.name().toLowerCase()); + if (textColor != null) { + return getColor(textColor); + } + + return getFormat(TEAM_FORMATS.get(teamColor)); } /** diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java index f5128ed6..bc10e2c8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java @@ -57,7 +57,7 @@ public class JavaChatTranslator extends PacketTranslator { } textPacket.setNeedsTranslation(false); - textPacket.setMessage(MessageTranslator.convertMessage(packet.getMessage().toString(), session.getLocale())); + textPacket.setMessage(MessageTranslator.convertMessage(packet.getMessage(), session.getLocale())); session.sendUpstreamPacket(textPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDisconnectPacket.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDisconnectPacket.java index 1945a8e1..02e730be 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDisconnectPacket.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDisconnectPacket.java @@ -36,6 +36,6 @@ public class JavaDisconnectPacket extends PacketTranslator { if (packet.getTitle() == null) { text = " "; } else { - text = MessageTranslator.convertMessage(packet.getTitle().toString(), locale); + text = MessageTranslator.convertMessage(packet.getTitle(), locale); } switch (packet.getAction()) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaScoreboardObjectiveTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaScoreboardObjectiveTranslator.java index 1996f696..8cc01662 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaScoreboardObjectiveTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaScoreboardObjectiveTranslator.java @@ -54,7 +54,7 @@ public class JavaScoreboardObjectiveTranslator extends PacketTranslator { switch (packet.getAction()) { case CREATE: scoreboard.registerNewTeam(packet.getTeamName(), toPlayerSet(packet.getPlayers())) - .setName(MessageTranslator.convertMessage(packet.getDisplayName().toString())) + .setName(MessageTranslator.convertMessage(packet.getDisplayName())) .setColor(packet.getColor()) .setNameTagVisibility(packet.getNameTagVisibility()) - .setPrefix(MessageTranslator.convertMessage(packet.getPrefix().toString(), session.getLocale())) - .setSuffix(MessageTranslator.convertMessage(packet.getSuffix().toString(), session.getLocale())); + .setPrefix(MessageTranslator.convertMessage(packet.getPrefix(), session.getLocale())) + .setSuffix(MessageTranslator.convertMessage(packet.getSuffix(), session.getLocale())); break; case UPDATE: if (team == null) { @@ -74,11 +74,11 @@ public class JavaTeamTranslator extends PacketTranslator { return; } - team.setName(MessageTranslator.convertMessage(packet.getDisplayName().toString())) + team.setName(MessageTranslator.convertMessage(packet.getDisplayName())) .setColor(packet.getColor()) .setNameTagVisibility(packet.getNameTagVisibility()) - .setPrefix(MessageTranslator.convertMessage(packet.getPrefix().toString(), session.getLocale())) - .setSuffix(MessageTranslator.convertMessage(packet.getSuffix().toString(), session.getLocale())) + .setPrefix(MessageTranslator.convertMessage(packet.getPrefix(), session.getLocale())) + .setSuffix(MessageTranslator.convertMessage(packet.getSuffix(), session.getLocale())) .setUpdateType(UpdateType.UPDATE); break; case ADD_PLAYER: