Initial 1.19.1 Java support

This commit is contained in:
Camotoy 2022-07-24 19:32:22 -04:00
parent 41273001d8
commit a18ac29a91
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
8 changed files with 35 additions and 62 deletions

View file

@ -161,9 +161,9 @@
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.GeyserMC</groupId> <groupId>com.github.steveice10</groupId>
<artifactId>MCProtocolLib</artifactId> <artifactId>mcprotocollib</artifactId>
<version>ecc04fd</version> <version>1.19.1-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>

View file

@ -123,9 +123,9 @@ import org.geysermc.geyser.session.auth.AuthType;
import org.geysermc.geyser.session.auth.BedrockClientData; import org.geysermc.geyser.session.auth.BedrockClientData;
import org.geysermc.geyser.session.cache.*; import org.geysermc.geyser.session.cache.*;
import org.geysermc.geyser.skin.FloodgateSkinUploader; import org.geysermc.geyser.skin.FloodgateSkinUploader;
import org.geysermc.geyser.text.ChatTypeEntry;
import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.text.TextDecoration;
import org.geysermc.geyser.translator.inventory.InventoryTranslator; import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.ChunkUtils; import org.geysermc.geyser.util.ChunkUtils;
@ -341,7 +341,7 @@ public class GeyserSession implements GeyserConnection, CommandSender {
*/ */
private final Map<String, JavaDimension> dimensions = new Object2ObjectOpenHashMap<>(3); private final Map<String, JavaDimension> dimensions = new Object2ObjectOpenHashMap<>(3);
private final Int2ObjectMap<ChatTypeEntry> chatTypes = new Int2ObjectOpenHashMap<>(8); private final Int2ObjectMap<TextDecoration> chatTypes = new Int2ObjectOpenHashMap<>(7);
@Setter @Setter
private int breakingBlock; private int breakingBlock;
@ -564,8 +564,6 @@ public class GeyserSession implements GeyserConnection, CommandSender {
this.playerEntity = new SessionPlayerEntity(this); this.playerEntity = new SessionPlayerEntity(this);
collisionManager.updatePlayerBoundingBox(this.playerEntity.getPosition()); collisionManager.updatePlayerBoundingBox(this.playerEntity.getPosition());
ChatTypeEntry.applyDefaults(chatTypes);
this.playerInventory = new PlayerInventory(); this.playerInventory = new PlayerInventory();
this.openInventory = null; this.openInventory = null;
this.craftingRecipes = new Int2ObjectOpenHashMap<>(); this.craftingRecipes = new Int2ObjectOpenHashMap<>();
@ -1388,14 +1386,14 @@ public class GeyserSession implements GeyserConnection, CommandSender {
* Sends a chat message to the Java server. * Sends a chat message to the Java server.
*/ */
public void sendChat(String message) { public void sendChat(String message) {
sendDownstreamPacket(new ServerboundChatPacket(message, Instant.now().toEpochMilli(), 0L, ByteArrays.EMPTY_ARRAY, false)); sendDownstreamPacket(new ServerboundChatPacket(message, Instant.now().toEpochMilli(), 0L, ByteArrays.EMPTY_ARRAY, false, Collections.emptyList(), null));
} }
/** /**
* Sends a command to the Java server. * Sends a command to the Java server.
*/ */
public void sendCommand(String command) { public void sendCommand(String command) {
sendDownstreamPacket(new ServerboundChatCommandPacket(command, Instant.now().toEpochMilli(), 0L, Collections.emptyMap(), false)); sendDownstreamPacket(new ServerboundChatCommandPacket(command, Instant.now().toEpochMilli(), 0L, Collections.emptyList(), false, Collections.emptyList(), null));
} }
public void setServerRenderDistance(int renderDistance) { public void setServerRenderDistance(int renderDistance) {

View file

@ -34,9 +34,7 @@ import javax.annotation.Nullable;
public record ChatTypeEntry(@Nonnull TextPacket.Type bedrockChatType, @Nullable TextDecoration textDecoration) { public record ChatTypeEntry(@Nonnull TextPacket.Type bedrockChatType, @Nullable TextDecoration textDecoration) {
private static final ChatTypeEntry CHAT = new ChatTypeEntry(TextPacket.Type.CHAT, null); private static final ChatTypeEntry CHAT = new ChatTypeEntry(TextPacket.Type.CHAT, null);
private static final ChatTypeEntry SYSTEM = new ChatTypeEntry(TextPacket.Type.CHAT, null); private static final ChatTypeEntry RAW = new ChatTypeEntry(TextPacket.Type.RAW, null);
private static final ChatTypeEntry TIP = new ChatTypeEntry(TextPacket.Type.CHAT, null);
private static final ChatTypeEntry RAW = new ChatTypeEntry(TextPacket.Type.CHAT, null);
/** /**
* Apply defaults to a map so it isn't empty in the event a chat message is sent before the login packet. * Apply defaults to a map so it isn't empty in the event a chat message is sent before the login packet.
@ -46,12 +44,11 @@ public record ChatTypeEntry(@Nonnull TextPacket.Type bedrockChatType, @Nullable
// But, the only way this happens is if a chat message is sent to us before the login packet, which is rare. // But, the only way this happens is if a chat message is sent to us before the login packet, which is rare.
// So we'll just make sure chat ends up in the right place. // So we'll just make sure chat ends up in the right place.
chatTypes.put(BuiltinChatType.CHAT.ordinal(), CHAT); chatTypes.put(BuiltinChatType.CHAT.ordinal(), CHAT);
chatTypes.put(BuiltinChatType.SYSTEM.ordinal(), SYSTEM);
chatTypes.put(BuiltinChatType.GAME_INFO.ordinal(), TIP);
chatTypes.put(BuiltinChatType.SAY_COMMAND.ordinal(), RAW); chatTypes.put(BuiltinChatType.SAY_COMMAND.ordinal(), RAW);
chatTypes.put(BuiltinChatType.MSG_COMMAND.ordinal(), RAW); chatTypes.put(BuiltinChatType.MSG_COMMAND_INCOMING.ordinal(), RAW);
chatTypes.put(BuiltinChatType.TEAM_MSG_COMMAND.ordinal(), RAW); chatTypes.put(BuiltinChatType.MSG_COMMAND_OUTGOING.ordinal(), RAW);
chatTypes.put(BuiltinChatType.TEAM_MSG_COMMAND_INCOMING.ordinal(), RAW);
chatTypes.put(BuiltinChatType.TEAM_MSG_COMMAND_OUTGOING.ordinal(), RAW);
chatTypes.put(BuiltinChatType.EMOTE_COMMAND.ordinal(), RAW); chatTypes.put(BuiltinChatType.EMOTE_COMMAND.ordinal(), RAW);
chatTypes.put(BuiltinChatType.TELLRAW_COMMAND.ordinal(), RAW);
} }
} }

View file

@ -46,6 +46,7 @@ public final class TextDecoration {
CompoundTag styleTag = tag.get("style"); CompoundTag styleTag = tag.get("style");
Style.Builder builder = Style.style(); Style.Builder builder = Style.style();
if (styleTag != null) {
StringTag color = styleTag.get("color"); StringTag color = styleTag.get("color");
if (color != null) { if (color != null) {
builder.color(NamedTextColor.NAMES.value(color.getValue())); builder.color(NamedTextColor.NAMES.value(color.getValue()));
@ -55,6 +56,7 @@ public final class TextDecoration {
if (italic != null && ((Number) italic.getValue()).byteValue() == (byte) 1) { if (italic != null && ((Number) italic.getValue()).byteValue() == (byte) 1) {
builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC); builder.decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC);
} }
}
style = builder.build(); style = builder.build();
this.parameters = EnumSet.noneOf(Parameter.class); this.parameters = EnumSet.noneOf(Parameter.class);
@ -88,6 +90,6 @@ public final class TextDecoration {
public enum Parameter { public enum Parameter {
CONTENT, CONTENT,
SENDER, SENDER,
TEAM_NAME TARGET
} }
} }

View file

@ -131,7 +131,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
CommandNode node = nodes[nodeIndex]; CommandNode node = nodes[nodeIndex];
// Make sure we don't have duplicated commands (happens if there is more than 1 root node) // Make sure we don't have duplicated commands (happens if there is more than 1 root node)
if (!commandNodes.add(nodeIndex) || !knownAliases.add(node.getName().toLowerCase())) continue; if (!commandNodes.add(nodeIndex) || !knownAliases.add(node.getName().toLowerCase(Locale.ROOT))) continue;
// Get and update the commandArgs list with the found arguments // Get and update the commandArgs list with the found arguments
if (node.getChildIndices().length >= 1) { if (node.getChildIndices().length >= 1) {
@ -319,7 +319,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
CommandParam type = null; CommandParam type = null;
boolean optional = this.paramNode.isExecutable(); boolean optional = this.paramNode.isExecutable();
if (mappedType instanceof String[]) { if (mappedType instanceof String[]) {
enumData = new CommandEnumData(paramNode.getParser().name().toLowerCase(), (String[]) mappedType, false); enumData = new CommandEnumData(paramNode.getParser().name().toLowerCase(Locale.ROOT), (String[]) mappedType, false);
} else { } else {
type = (CommandParam) mappedType; type = (CommandParam) mappedType;
// Bedrock throws a fit if an optional message comes after a string or target // Bedrock throws a fit if an optional message comes after a string or target

View file

@ -25,25 +25,21 @@
package org.geysermc.geyser.translator.protocol.java; package org.geysermc.geyser.translator.protocol.java;
import com.github.steveice10.mc.protocol.data.game.BuiltinChatType;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket; 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.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag; 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.GameRuleData;
import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.data.PlayerPermission;
import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket; import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket;
import com.nukkitx.protocol.bedrock.packet.GameRulesChangedPacket; import com.nukkitx.protocol.bedrock.packet.GameRulesChangedPacket;
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
import com.nukkitx.protocol.bedrock.packet.TextPacket;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.geysermc.floodgate.pluginmessage.PluginMessageChannels; import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
import org.geysermc.geyser.level.JavaDimension; import org.geysermc.geyser.level.JavaDimension;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.auth.AuthType; import org.geysermc.geyser.session.auth.AuthType;
import org.geysermc.geyser.text.ChatTypeEntry;
import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.text.TextDecoration;
import org.geysermc.geyser.translator.level.BiomeTranslator; import org.geysermc.geyser.translator.level.BiomeTranslator;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
@ -68,7 +64,7 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
JavaDimension.load(packet.getRegistry(), dimensions); JavaDimension.load(packet.getRegistry(), dimensions);
Int2ObjectMap<ChatTypeEntry> chatTypes = session.getChatTypes(); Int2ObjectMap<TextDecoration> chatTypes = session.getChatTypes();
chatTypes.clear(); chatTypes.clear();
for (CompoundTag tag : JavaCodecEntry.iterateAsTag(packet.getRegistry().get("minecraft:chat_type"))) { 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. // The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla.
@ -77,21 +73,9 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
CompoundTag chat = element.get("chat"); CompoundTag chat = element.get("chat");
TextDecoration textDecoration = null; TextDecoration textDecoration = null;
if (chat != null) { if (chat != null) {
CompoundTag decorationTag = chat.get("decoration"); textDecoration = new TextDecoration(chat);
if (decorationTag != null) {
textDecoration = new TextDecoration(decorationTag);
} }
} chatTypes.put(id, textDecoration);
BuiltinChatType type = BuiltinChatType.from(((StringTag) tag.get("name")).getValue());
// TODO new types?
// The built-in type can be null if custom plugins/mods add in new types
TextPacket.Type bedrockType = type != null ? switch (type) {
case CHAT -> TextPacket.Type.CHAT;
case SYSTEM -> TextPacket.Type.SYSTEM;
case GAME_INFO -> TextPacket.Type.TIP;
default -> TextPacket.Type.RAW;
} : TextPacket.Type.RAW;
chatTypes.put(id, new ChatTypeEntry(bedrockType, textDecoration));
} }
// If the player is already initialized and a join game packet is sent, they // If the player is already initialized and a join game packet is sent, they

View file

@ -30,7 +30,6 @@ import com.nukkitx.protocol.bedrock.packet.TextPacket;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent; import net.kyori.adventure.text.TranslatableComponent;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatTypeEntry;
import org.geysermc.geyser.text.TextDecoration; import org.geysermc.geyser.text.TextDecoration;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.Translator;
@ -45,18 +44,16 @@ public class JavaPlayerChatTranslator extends PacketTranslator<ClientboundPlayer
@Override @Override
public void translate(GeyserSession session, ClientboundPlayerChatPacket packet) { public void translate(GeyserSession session, ClientboundPlayerChatPacket packet) {
ChatTypeEntry entry = session.getChatTypes().get(packet.getTypeId());
TextPacket textPacket = new TextPacket(); TextPacket textPacket = new TextPacket();
textPacket.setPlatformChatId(""); textPacket.setPlatformChatId("");
textPacket.setSourceName(""); textPacket.setSourceName("");
textPacket.setXuid(session.getAuthData().xuid()); textPacket.setXuid(session.getAuthData().xuid());
textPacket.setType(entry.bedrockChatType()); textPacket.setType(TextPacket.Type.CHAT);
textPacket.setNeedsTranslation(false); textPacket.setNeedsTranslation(false);
Component message = packet.getUnsignedContent() == null ? packet.getSignedContent() : packet.getUnsignedContent(); Component message = packet.getUnsignedContent() == null ? packet.getMessageDecorated() : packet.getUnsignedContent();
TextDecoration decoration = entry.textDecoration(); TextDecoration decoration = session.getChatTypes().get(packet.getChatType());
if (decoration != null) { if (decoration != null) {
// As of 1.19 - do this to apply all the styling for signed messages // As of 1.19 - do this to apply all the styling for signed messages
// Though, Bedrock cannot care about the signed stuff. // Though, Bedrock cannot care about the signed stuff.
@ -65,11 +62,11 @@ public class JavaPlayerChatTranslator extends PacketTranslator<ClientboundPlayer
.style(decoration.style()); .style(decoration.style());
Set<TextDecoration.Parameter> parameters = decoration.parameters(); Set<TextDecoration.Parameter> parameters = decoration.parameters();
List<Component> args = new ArrayList<>(3); List<Component> args = new ArrayList<>(3);
if (parameters.contains(TextDecoration.Parameter.TEAM_NAME)) { if (parameters.contains(TextDecoration.Parameter.TARGET)) {
args.add(packet.getSenderTeamName()); args.add(packet.getTargetName());
} }
if (parameters.contains(TextDecoration.Parameter.SENDER)) { if (parameters.contains(TextDecoration.Parameter.SENDER)) {
args.add(packet.getSenderName()); args.add(packet.getName());
} }
if (parameters.contains(TextDecoration.Parameter.CONTENT)) { if (parameters.contains(TextDecoration.Parameter.CONTENT)) {
args.add(message); args.add(message);

View file

@ -28,7 +28,6 @@ package org.geysermc.geyser.translator.protocol.java;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket;
import com.nukkitx.protocol.bedrock.packet.TextPacket; import com.nukkitx.protocol.bedrock.packet.TextPacket;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatTypeEntry;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.translator.text.MessageTranslator;
@ -38,15 +37,11 @@ public class JavaSystemChatTranslator extends PacketTranslator<ClientboundSystem
@Override @Override
public void translate(GeyserSession session, ClientboundSystemChatPacket packet) { public void translate(GeyserSession session, ClientboundSystemChatPacket packet) {
ChatTypeEntry chatTypeEntry = session.getChatTypes().get(packet.getTypeId());
// This probably isn't proper but system chat won't care about the registry in 1.19.1 anyway
TextPacket.Type chatType = chatTypeEntry == null ? TextPacket.Type.RAW : chatTypeEntry.bedrockChatType();
TextPacket textPacket = new TextPacket(); TextPacket textPacket = new TextPacket();
textPacket.setPlatformChatId(""); textPacket.setPlatformChatId("");
textPacket.setSourceName(""); textPacket.setSourceName("");
textPacket.setXuid(session.getAuthData().xuid()); textPacket.setXuid(session.getAuthData().xuid());
textPacket.setType(chatType); textPacket.setType(packet.isOverlay() ? TextPacket.Type.TIP : TextPacket.Type.SYSTEM);
textPacket.setNeedsTranslation(false); textPacket.setNeedsTranslation(false);
textPacket.setMessage(MessageTranslator.convertMessage(packet.getContent(), session.getLocale())); textPacket.setMessage(MessageTranslator.convertMessage(packet.getContent(), session.getLocale()));