Properly support differently setup chat registries

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 #3023
This commit is contained in:
Camotoy 2022-06-08 22:30:34 -04:00
parent 78bb69be42
commit 72a9df58e0
No known key found for this signature in database
GPG Key ID: 7EEFB66FE798081F
6 changed files with 64 additions and 26 deletions

View File

@ -155,7 +155,7 @@
<dependency>
<groupId>com.github.GeyserMC</groupId>
<artifactId>MCProtocolLib</artifactId>
<version>bf3919a</version>
<version>3023c4d</version>
<scope>compile</scope>
<exclusions>
<exclusion>

View File

@ -121,6 +121,7 @@ import org.geysermc.geyser.session.auth.AuthType;
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;
@ -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;

View File

@ -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) {
}

View File

@ -30,16 +30,20 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLo
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;
@ -64,21 +68,29 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
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

View File

@ -30,6 +30,7 @@ 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.ChatTypeEntry;
import org.geysermc.geyser.text.TextDecoration;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
@ -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.

View File

@ -41,13 +41,7 @@ public class JavaSystemChatTranslator extends PacketTranslator<ClientboundSystem
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()));