Skip to content

Commit

Permalink
Properly support differently setup chat registries
Browse files Browse the repository at this point in the history
ViaVersion has two entries in its fake chat registry that are not in the same order as Java. This commit supports that properly and renders subtitled text correctly.

Resolves GeyserMC#3023
  • Loading branch information
Camotoy committed Jun 9, 2022
1 parent 78bb69b commit 72a9df5
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 26 deletions.
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
<dependency>
<groupId>com.github.GeyserMC</groupId>
<artifactId>MCProtocolLib</artifactId>
<version>bf3919a</version>
<version>3023c4d</version>
<scope>compile</scope>
<exclusions>
<exclusion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
import org.geysermc.geyser.session.auth.BedrockClientData;
import org.geysermc.geyser.session.cache.*;
import org.geysermc.geyser.skin.FloodgateSkinUploader;
import org.geysermc.geyser.text.ChatTypeEntry;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.text.TextDecoration;
Expand Down Expand Up @@ -336,7 +337,7 @@ public class GeyserSession implements GeyserConnection, CommandSender {
*/
private final Map<String, JavaDimension> dimensions = new Object2ObjectOpenHashMap<>(3);

private final Map<MessageType, TextDecoration> chatTypes = new EnumMap<>(MessageType.class);
private final Int2ObjectMap<ChatTypeEntry> chatTypes = new Int2ObjectOpenHashMap<>(7);

@Setter
private int breakingBlock;
Expand Down
34 changes: 34 additions & 0 deletions core/src/main/java/org/geysermc/geyser/text/ChatTypeEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.nukkitx.protocol.bedrock.packet.TextPacket;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public record ChatTypeEntry(@Nonnull TextPacket.Type bedrockChatType, @Nullable TextDecoration textDecoration) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,20 @@
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.nukkitx.protocol.bedrock.data.GameRuleData;
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket;
import com.nukkitx.protocol.bedrock.packet.GameRulesChangedPacket;
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
import com.nukkitx.protocol.bedrock.packet.TextPacket;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
import org.geysermc.geyser.level.JavaDimension;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.auth.AuthType;
import org.geysermc.geyser.text.ChatTypeEntry;
import org.geysermc.geyser.text.TextDecoration;
import org.geysermc.geyser.translator.level.BiomeTranslator;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
Expand All @@ -64,21 +68,29 @@ public void translate(GeyserSession session, ClientboundLoginPacket packet) {

JavaDimension.load(packet.getRegistry(), dimensions);

Map<MessageType, TextDecoration> chatTypes = session.getChatTypes();
Int2ObjectMap<ChatTypeEntry> chatTypes = session.getChatTypes();
chatTypes.clear();
for (CompoundTag tag : JavaCodecEntry.iterateAsTag(packet.getRegistry().get("minecraft:chat_type"))) {
// The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla.
int id = ((IntTag) tag.get("id")).getValue();
CompoundTag element = tag.get("element");
CompoundTag chat = element.get("chat");
if (chat == null) {
continue;
TextDecoration textDecoration = null;
if (chat != null) {
CompoundTag decorationTag = chat.get("decoration");
if (decorationTag != null) {
textDecoration = new TextDecoration(decorationTag);
}
}
CompoundTag decoration = chat.get("decoration");
if (decoration == null) {
continue;
}
MessageType type = MessageType.from(id);
chatTypes.put(type, new TextDecoration(decoration));
MessageType type = MessageType.from(((StringTag) tag.get("name")).getValue());
// TODO new types?
TextPacket.Type bedrockType = switch (type) {
case CHAT -> TextPacket.Type.CHAT;
case SYSTEM -> TextPacket.Type.SYSTEM;
case GAME_INFO -> TextPacket.Type.TIP;
default -> TextPacket.Type.RAW;
};
chatTypes.put(id, new ChatTypeEntry(bedrockType, textDecoration));
}

// If the player is already initialized and a join game packet is sent, they
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatTypeEntry;
import org.geysermc.geyser.text.TextDecoration;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
Expand All @@ -44,22 +45,18 @@ public class JavaPlayerChatTranslator extends PacketTranslator<ClientboundPlayer

@Override
public void translate(GeyserSession session, ClientboundPlayerChatPacket packet) {
ChatTypeEntry entry = session.getChatTypes().get(packet.getTypeId());

TextPacket textPacket = new TextPacket();
textPacket.setPlatformChatId("");
textPacket.setSourceName("");
textPacket.setXuid(session.getAuthData().xuid());
// TODO new types
textPacket.setType(switch (packet.getType()) {
case CHAT -> TextPacket.Type.CHAT;
case SYSTEM -> TextPacket.Type.SYSTEM;
case GAME_INFO -> TextPacket.Type.TIP;
default -> TextPacket.Type.RAW;
});
textPacket.setType(entry.bedrockChatType());

textPacket.setNeedsTranslation(false);
Component message = packet.getUnsignedContent() == null ? packet.getSignedContent() : packet.getUnsignedContent();

TextDecoration decoration = session.getChatTypes().get(packet.getType());
TextDecoration decoration = entry.textDecoration();
if (decoration != null) {
// As of 1.19 - do this to apply all the styling for signed messages
// Though, Bedrock cannot care about the signed stuff.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,7 @@ public void translate(GeyserSession session, ClientboundSystemChatPacket packet)
textPacket.setPlatformChatId("");
textPacket.setSourceName("");
textPacket.setXuid(session.getAuthData().xuid());
// TODO new types
textPacket.setType(switch (packet.getType()) {
case CHAT -> TextPacket.Type.CHAT;
case SYSTEM -> TextPacket.Type.SYSTEM;
case GAME_INFO -> TextPacket.Type.TIP;
default -> TextPacket.Type.RAW;
});
textPacket.setType(session.getChatTypes().get(packet.getTypeId()).bedrockChatType());

textPacket.setNeedsTranslation(false);
textPacket.setMessage(MessageTranslator.convertMessage(packet.getContent(), session.getLocale()));
Expand Down

0 comments on commit 72a9df5

Please sign in to comment.