From 1f8c8dcd948e425cbe1f67678141e2f637c3f8b2 Mon Sep 17 00:00:00 2001 From: Leymooo Date: Sat, 25 Aug 2018 04:33:27 +0300 Subject: [PATCH 1/2] Add Header and Footer. Resolves #50 --- .../api/event/ResultedEvent.java | 1 - .../api/event/connection/PreLoginEvent.java | 1 - .../com/velocitypowered/api/proxy/Player.java | 14 ++++- .../velocitypowered/api/util/GameProfile.java | 2 +- .../connection/client/ConnectedPlayer.java | 11 +++- .../client/LoginSessionHandler.java | 7 +-- .../proxy/protocol/StateRegistry.java | 7 +++ .../protocol/packet/HeaderAndFooter.java | 57 +++++++++++++++++++ 8 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java diff --git a/api/src/main/java/com/velocitypowered/api/event/ResultedEvent.java b/api/src/main/java/com/velocitypowered/api/event/ResultedEvent.java index 28bc71c2b..43500eebc 100644 --- a/api/src/main/java/com/velocitypowered/api/event/ResultedEvent.java +++ b/api/src/main/java/com/velocitypowered/api/event/ResultedEvent.java @@ -1,7 +1,6 @@ package com.velocitypowered.api.event; import com.google.common.base.Preconditions; - import net.kyori.text.Component; import net.kyori.text.serializer.ComponentSerializers; import org.checkerframework.checker.nullness.qual.NonNull; diff --git a/api/src/main/java/com/velocitypowered/api/event/connection/PreLoginEvent.java b/api/src/main/java/com/velocitypowered/api/event/connection/PreLoginEvent.java index 9c052df96..4c1cef16f 100644 --- a/api/src/main/java/com/velocitypowered/api/event/connection/PreLoginEvent.java +++ b/api/src/main/java/com/velocitypowered/api/event/connection/PreLoginEvent.java @@ -7,7 +7,6 @@ import com.velocitypowered.api.proxy.InboundConnection; import net.kyori.text.Component; - import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/api/src/main/java/com/velocitypowered/api/proxy/Player.java b/api/src/main/java/com/velocitypowered/api/proxy/Player.java index e70c37a6d..e1be76ee6 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java @@ -1,16 +1,13 @@ package com.velocitypowered.api.proxy; import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.event.connection.LoginEvent; import com.velocitypowered.api.proxy.messages.ChannelMessageSink; import com.velocitypowered.api.proxy.messages.ChannelMessageSource; import com.velocitypowered.api.server.ServerInfo; -import com.velocitypowered.api.util.GameProfile.Property; import com.velocitypowered.api.util.MessagePosition; import net.kyori.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.List; import java.util.Optional; import java.util.UUID; @@ -58,5 +55,16 @@ public interface Player extends CommandSource, InboundConnection, ChannelMessage */ ConnectionRequestBuilder createConnectionRequest(@NonNull ServerInfo info); + /** + * Sets a header and footer to the player + * @param header component with header + * @param footer component with footer + */ + void setHeaderAndFooter(@NonNull Component header, @NonNull Component footer); + + /** + * Disconnects the player with the reason + * @param reason component with the reason + */ void disconnect(Component reason); } diff --git a/api/src/main/java/com/velocitypowered/api/util/GameProfile.java b/api/src/main/java/com/velocitypowered/api/util/GameProfile.java index 362cdb6fc..f77b991f3 100644 --- a/api/src/main/java/com/velocitypowered/api/util/GameProfile.java +++ b/api/src/main/java/com/velocitypowered/api/util/GameProfile.java @@ -25,7 +25,7 @@ public class GameProfile { public UUID idAsUuid() { return UuidUtils.fromUndashed(id); } - + public String getName() { return name; } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java index 4653bd4cc..ac65b4571 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java @@ -9,14 +9,12 @@ import com.velocitypowered.api.proxy.ConnectionRequestBuilder; import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.messages.ChannelIdentifier; import com.velocitypowered.api.util.MessagePosition; -import com.velocitypowered.api.util.UuidUtils; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation; import com.velocitypowered.proxy.connection.util.ConnectionMessages; import com.velocitypowered.proxy.connection.util.ConnectionRequestResults; import com.velocitypowered.api.util.GameProfile; -import com.velocitypowered.proxy.protocol.StateRegistry; import com.velocitypowered.proxy.protocol.packet.Chat; import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; @@ -25,6 +23,8 @@ import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.util.ThrowableUtils; import com.velocitypowered.api.server.ServerInfo; import com.velocitypowered.proxy.protocol.packet.Disconnect; +import com.velocitypowered.proxy.protocol.packet.HeaderAndFooter; + import net.kyori.text.Component; import net.kyori.text.TextComponent; import net.kyori.text.TranslatableComponent; @@ -137,6 +137,13 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { return new ConnectionRequestBuilderImpl(info); } + @Override + public void setHeaderAndFooter(@NonNull Component header, @NonNull Component footer) { + Preconditions.checkNotNull(header, "header"); + Preconditions.checkNotNull(footer, "footer"); + connection.write(HeaderAndFooter.create(header, footer)); + } + @Override public void disconnect(Component reason) { connection.closeWith(Disconnect.create(reason)); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java index 0765bcdcd..2757f3be6 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java @@ -10,7 +10,6 @@ import com.velocitypowered.api.proxy.InboundConnection; import com.velocitypowered.api.server.ServerInfo; import com.velocitypowered.proxy.connection.VelocityConstants; import com.velocitypowered.api.util.GameProfile; -import com.velocitypowered.api.util.UuidUtils; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolConstants; import com.velocitypowered.proxy.protocol.StateRegistry; @@ -100,14 +99,14 @@ public class LoginSessionHandler implements MinecraftSessionHandler { // The player disconnected after we authenticated them. return; } + try { inbound.enableEncryption(decryptedSharedSecret); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } - + initializePlayer(VelocityServer.GSON.fromJson(profileResponse, GameProfile.class), true); - }, inbound.getChannel().eventLoop()) .exceptionally(exception -> { logger.error("Unable to enable encryption", exception); @@ -137,7 +136,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { inbound.closeWith(Disconnect.create(event.getResult().getReason().get())); return; } - + if (VelocityServer.getServer().getConfiguration().isOnlineMode() || result.isOnlineModeAllowed()) { // Request encryption. EncryptionRequest request = generateRequest(); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java index 5ae96abc5..701ec301d 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java @@ -106,6 +106,13 @@ public enum StateRegistry { map(0x34, MINECRAFT_1_12, true), map(0x35, MINECRAFT_1_12_2, true), map(0x38, MINECRAFT_1_13, true)); + CLIENTBOUND.register(HeaderAndFooter.class, HeaderAndFooter::new, + map(0x47, MINECRAFT_1_8, true), + map(0x48, MINECRAFT_1_9, true), + map(0x47, MINECRAFT_1_9_4, true), + map(0x49, MINECRAFT_1_12, true), + map(0x4A, MINECRAFT_1_12_1, true), + map(0x4E, MINECRAFT_1_13, true)); CLIENTBOUND.register(ScoreboardDisplay.class, ScoreboardDisplay::new, map(0x3D, MINECRAFT_1_8, true), map(0x38, MINECRAFT_1_9, true), diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java new file mode 100644 index 000000000..2b3141cb1 --- /dev/null +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java @@ -0,0 +1,57 @@ +package com.velocitypowered.proxy.protocol.packet; + +import com.velocitypowered.proxy.protocol.MinecraftPacket; +import com.velocitypowered.proxy.protocol.ProtocolConstants.Direction; +import static com.velocitypowered.proxy.protocol.ProtocolUtils.writeString; + +import io.netty.buffer.ByteBuf; +import net.kyori.text.Component; +import net.kyori.text.serializer.ComponentSerializer; +import net.kyori.text.serializer.ComponentSerializers; + +public class HeaderAndFooter implements MinecraftPacket { + + private String header; + private String footer; + + public HeaderAndFooter() { + } + + public HeaderAndFooter(String header, String footer) { + this.header = header; + this.footer = footer; + } + + public String getHeader() { + return header; + } + + public void setHeader(String header) { + this.header = header; + } + + public String getFooter() { + return footer; + } + + public void setFooter(String footer) { + this.footer = footer; + } + + @Override + public void decode(ByteBuf buf, Direction direction, int protocolVersion) { + // We dont handle this packet from backend + } + + @Override + public void encode(ByteBuf buf, Direction direction, int protocolVersion) { + writeString(buf, header); + writeString(buf, footer); + } + + public static HeaderAndFooter create(Component header, Component footer) { + ComponentSerializer json = ComponentSerializers.JSON; + return new HeaderAndFooter(json.serialize(header), json.serialize(footer)); + } + +} From d65e4ed29682b4330914c3ef4ce13d09edd59bd4 Mon Sep 17 00:00:00 2001 From: Leymooo Date: Sat, 25 Aug 2018 04:45:10 +0300 Subject: [PATCH 2/2] add method to clear header and footer --- .../main/java/com/velocitypowered/api/proxy/Player.java | 9 +++++++-- .../proxy/connection/client/ConnectedPlayer.java | 5 +++++ .../proxy/protocol/packet/HeaderAndFooter.java | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/com/velocitypowered/api/proxy/Player.java b/api/src/main/java/com/velocitypowered/api/proxy/Player.java index e1be76ee6..e90a34c13 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java @@ -60,8 +60,13 @@ public interface Player extends CommandSource, InboundConnection, ChannelMessage * @param header component with header * @param footer component with footer */ - void setHeaderAndFooter(@NonNull Component header, @NonNull Component footer); - + void setHeaderAndFooter(Component header, Component footer); + + /** + * Clears a header and footer for the player + */ + void clearHeaderAndFooter(); + /** * Disconnects the player with the reason * @param reason component with the reason diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java index ac65b4571..91c88ce8b 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java @@ -144,6 +144,11 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { connection.write(HeaderAndFooter.create(header, footer)); } + @Override + public void clearHeaderAndFooter() { + connection.write(HeaderAndFooter.reset()); + } + @Override public void disconnect(Component reason) { connection.closeWith(Disconnect.create(reason)); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java index 2b3141cb1..35c75af30 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java @@ -11,6 +11,8 @@ import net.kyori.text.serializer.ComponentSerializers; public class HeaderAndFooter implements MinecraftPacket { + private static final HeaderAndFooter RESET = new HeaderAndFooter("{\"translate\":\"\"}", "{\"translate\":\"\"}"); + private String header; private String footer; @@ -40,7 +42,7 @@ public class HeaderAndFooter implements MinecraftPacket { @Override public void decode(ByteBuf buf, Direction direction, int protocolVersion) { - // We dont handle this packet from backend + throw new UnsupportedOperationException("Decode is not implemented"); } @Override @@ -54,4 +56,7 @@ public class HeaderAndFooter implements MinecraftPacket { return new HeaderAndFooter(json.serialize(header), json.serialize(footer)); } + public static HeaderAndFooter reset() { + return RESET; + } }