mirror of
https://github.com/PaperMC/Velocity.git
synced 2026-02-19 15:37:42 +01:00
@@ -32,6 +32,7 @@ dependencies {
|
|||||||
api "net.kyori:adventure-text-serializer-gson:${adventureVersion}"
|
api "net.kyori:adventure-text-serializer-gson:${adventureVersion}"
|
||||||
api "net.kyori:adventure-text-serializer-legacy:${adventureVersion}"
|
api "net.kyori:adventure-text-serializer-legacy:${adventureVersion}"
|
||||||
api "net.kyori:adventure-text-serializer-plain:${adventureVersion}"
|
api "net.kyori:adventure-text-serializer-plain:${adventureVersion}"
|
||||||
|
api("net.kyori:coffee:1.0.0-SNAPSHOT")
|
||||||
|
|
||||||
api "org.slf4j:slf4j-api:${slf4jVersion}"
|
api "org.slf4j:slf4j-api:${slf4jVersion}"
|
||||||
api 'com.google.inject:guice:4.2.3'
|
api 'com.google.inject:guice:4.2.3'
|
||||||
@@ -75,13 +76,13 @@ javadoc {
|
|||||||
options.encoding = 'UTF-8'
|
options.encoding = 'UTF-8'
|
||||||
options.charSet = 'UTF-8'
|
options.charSet = 'UTF-8'
|
||||||
options.source = '8'
|
options.source = '8'
|
||||||
options.links(
|
// options.links(
|
||||||
'https://www.slf4j.org/apidocs/',
|
// 'https://www.slf4j.org/apidocs/',
|
||||||
'https://guava.dev/releases/30.0-jre/api/docs/',
|
// 'https://guava.dev/releases/30.0-jre/api/docs/',
|
||||||
'https://google.github.io/guice/api-docs/4.2/javadoc/',
|
// 'https://google.github.io/guice/api-docs/4.2/javadoc/',
|
||||||
'https://docs.oracle.com/javase/8/docs/api/',
|
// 'https://docs.oracle.com/javase/8/docs/api/',
|
||||||
'https://jd.adventure.kyori.net/api/4.0.0/'
|
// 'https://jd.adventure.kyori.net/api/4.0.0/'
|
||||||
)
|
// )
|
||||||
|
|
||||||
// Disable the crazy super-strict doclint tool in Java 8
|
// Disable the crazy super-strict doclint tool in Java 8
|
||||||
options.addStringOption('Xdoclint:none', '-quiet')
|
options.addStringOption('Xdoclint:none', '-quiet')
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ import java.util.EnumSet;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import net.kyori.coffee.Ordered;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents each Minecraft protocol version.
|
* Represents each Minecraft protocol version.
|
||||||
*/
|
*/
|
||||||
public enum ProtocolVersion {
|
public enum ProtocolVersion implements Ordered<ProtocolVersion> {
|
||||||
UNKNOWN(-1, "Unknown"),
|
UNKNOWN(-1, "Unknown"),
|
||||||
LEGACY(-2, "Legacy"),
|
LEGACY(-2, "Legacy"),
|
||||||
MINECRAFT_1_7_2(4, "1.7.2"),
|
MINECRAFT_1_7_2(4, "1.7.2"),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.github.jengelman.gradle.plugins:shadow:5.0.0'
|
classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,10 @@
|
|||||||
<property name="eachLine" value="true"/>
|
<property name="eachLine" value="true"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
<module name="SuppressionFilter">
|
||||||
|
<property name="file" value="${configDirectory}/suppressions.xml"/>
|
||||||
|
</module>
|
||||||
|
|
||||||
<module name="TreeWalker">
|
<module name="TreeWalker">
|
||||||
<module name="OuterTypeFilename"/>
|
<module name="OuterTypeFilename"/>
|
||||||
<!-- <module name="IllegalTokenText">
|
<!-- <module name="IllegalTokenText">
|
||||||
@@ -42,7 +46,7 @@
|
|||||||
<property name="allowNonPrintableEscapes" value="true"/>
|
<property name="allowNonPrintableEscapes" value="true"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="LineLength">
|
<module name="LineLength">
|
||||||
<property name="max" value="100"/>
|
<property name="max" value="150"/>
|
||||||
<property name="ignorePattern"
|
<property name="ignorePattern"
|
||||||
value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
||||||
</module>
|
</module>
|
||||||
|
|||||||
6
config/checkstyle/suppressions.xml
Normal file
6
config/checkstyle/suppressions.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE suppressions PUBLIC "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" "http://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||||
|
<suppressions>
|
||||||
|
<!-- no javadoc warning for implementation -->
|
||||||
|
<suppress files="src[\\/]main[\\/]java[\\/]com[\\/]velocitypowered[\\/]proxy[\\/].*" checks="JavadocMethod"/>
|
||||||
|
</suppressions>
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
checkstyle {
|
checkstyle {
|
||||||
|
def configDirectory = new File(project.rootDir, ["config", "checkstyle"].join(File.separator))
|
||||||
|
|
||||||
toolVersion '8.14'
|
toolVersion '8.14'
|
||||||
configFile new File(project.rootDir, ['config', 'checkstyle', 'checkstyle.xml'].join(File.separator))
|
configFile new File(configDirectory, "checkstyle.xml")
|
||||||
|
configProperties = [configDirectory: configDirectory.getAbsolutePath()]
|
||||||
|
|
||||||
// The build should immediately fail if we have errors.
|
// The build should immediately fail if we have errors.
|
||||||
maxErrors = 0
|
maxErrors = 0
|
||||||
maxWarnings = 0
|
maxWarnings = 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ import com.velocitypowered.proxy.config.VelocityConfiguration;
|
|||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import com.velocitypowered.proxy.console.VelocityConsole;
|
import com.velocitypowered.proxy.console.VelocityConsole;
|
||||||
import com.velocitypowered.proxy.network.ConnectionManager;
|
import com.velocitypowered.proxy.network.ConnectionManager;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.serialization.FaviconSerializer;
|
||||||
|
import com.velocitypowered.proxy.network.serialization.GameProfileSerializer;
|
||||||
import com.velocitypowered.proxy.plugin.VelocityEventManager;
|
import com.velocitypowered.proxy.plugin.VelocityEventManager;
|
||||||
import com.velocitypowered.proxy.plugin.VelocityPluginManager;
|
import com.velocitypowered.proxy.plugin.VelocityPluginManager;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
|
||||||
import com.velocitypowered.proxy.protocol.util.FaviconSerializer;
|
|
||||||
import com.velocitypowered.proxy.protocol.util.GameProfileSerializer;
|
|
||||||
import com.velocitypowered.proxy.scheduler.VelocityScheduler;
|
import com.velocitypowered.proxy.scheduler.VelocityScheduler;
|
||||||
import com.velocitypowered.proxy.server.ServerMap;
|
import com.velocitypowered.proxy.server.ServerMap;
|
||||||
import com.velocitypowered.proxy.util.AddressUtil;
|
import com.velocitypowered.proxy.util.AddressUtil;
|
||||||
@@ -645,7 +645,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Gson getPingGsonInstance(ProtocolVersion version) {
|
public static Gson getPingGsonInstance(ProtocolVersion version) {
|
||||||
return version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0 ? POST_1_16_PING_SERIALIZER
|
return version.gte(ProtocolVersion.MINECRAFT_1_16) ? POST_1_16_PING_SERIALIZER
|
||||||
: PRE_1_16_PING_SERIALIZER;
|
: PRE_1_16_PING_SERIALIZER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,15 +19,15 @@ import com.velocitypowered.proxy.VelocityServer;
|
|||||||
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
|
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
|
||||||
import com.velocitypowered.proxy.connection.client.LoginSessionHandler;
|
import com.velocitypowered.proxy.connection.client.LoginSessionHandler;
|
||||||
import com.velocitypowered.proxy.connection.client.StatusSessionHandler;
|
import com.velocitypowered.proxy.connection.client.StatusSessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCipherDecoder;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundSetCompressionPacket;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCipherEncoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftCipherDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCompressDecoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftCipherEncoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCompressEncoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftCompressDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftCompressEncoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftEncoder;
|
||||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
@@ -224,8 +224,8 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
*/
|
*/
|
||||||
public void closeWith(Object msg) {
|
public void closeWith(Object msg) {
|
||||||
if (channel.isActive()) {
|
if (channel.isActive()) {
|
||||||
boolean is17 = this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) < 0
|
boolean is17 = this.getProtocolVersion().lt(ProtocolVersion.MINECRAFT_1_8)
|
||||||
&& this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_7_2) >= 0;
|
&& this.getProtocolVersion().gte(ProtocolVersion.MINECRAFT_1_7_2);
|
||||||
if (is17 && this.getState() != StateRegistry.STATUS) {
|
if (is17 && this.getState() != StateRegistry.STATUS) {
|
||||||
channel.eventLoop().execute(() -> {
|
channel.eventLoop().execute(() -> {
|
||||||
// 1.7.x versions have a race condition with switching protocol states, so just explicitly
|
// 1.7.x versions have a race condition with switching protocol states, so just explicitly
|
||||||
@@ -369,7 +369,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the compression threshold on the connection. You are responsible for sending
|
* Sets the compression threshold on the connection. You are responsible for sending
|
||||||
* {@link SetCompressionPacket} beforehand.
|
* {@link ClientboundSetCompressionPacket} beforehand.
|
||||||
* @param threshold the compression threshold to use
|
* @param threshold the compression threshold to use
|
||||||
*/
|
*/
|
||||||
public void setCompressionThreshold(int threshold) {
|
public void setCompressionThreshold(int threshold) {
|
||||||
|
|||||||
@@ -1,192 +1,39 @@
|
|||||||
package com.velocitypowered.proxy.connection;
|
package com.velocitypowered.proxy.connection;
|
||||||
|
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.ChatPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionResponsePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.HeaderAndFooterPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessagePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponsePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.PlayerListItemPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequestPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusRequestPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusResponsePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.TitlePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyHandshakePacket;
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyPingPacket;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
public interface MinecraftSessionHandler {
|
public interface MinecraftSessionHandler extends PacketHandler {
|
||||||
|
|
||||||
default boolean beforeHandle() {
|
default boolean beforeHandle() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
default void handleGeneric(Packet packet) {
|
default void handleGeneric(Packet packet) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void handleUnknown(ByteBuf buf) {
|
default void handleUnknown(ByteBuf buf) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void connected() {
|
default void connected() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void disconnected() {
|
default void disconnected() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void activated() {
|
default void activated() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void deactivated() {
|
default void deactivated() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void exception(Throwable throwable) {
|
default void exception(Throwable throwable) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void writabilityChanged() {
|
default void writabilityChanged() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void readCompleted() {
|
default void readCompleted() {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(AvailableCommandsPacket commands) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(BossBarPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(ChatPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(ClientSettingsPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(DisconnectPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(EncryptionRequestPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(EncryptionResponsePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(HandshakePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(HeaderAndFooterPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(JoinGamePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(KeepAlivePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(LegacyHandshakePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(LegacyPingPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(LoginPluginMessagePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(LoginPluginResponsePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(PluginMessagePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(RespawnPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(ServerLoginPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(ServerLoginSuccessPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(SetCompressionPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(StatusPingPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(StatusRequestPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(StatusResponsePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(TabCompleteRequestPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(TabCompleteResponsePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(TitlePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(PlayerListItemPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(ResourcePackRequestPacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean handle(ResourcePackResponsePacket packet) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.velocitypowered.proxy.connection.backend;
|
|||||||
|
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeHandshakeBackendPhase;
|
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeHandshakeBackendPhase;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides connection phase specific actions.
|
* Provides connection phase specific actions.
|
||||||
@@ -21,7 +21,7 @@ public interface BackendConnectionPhase {
|
|||||||
*/
|
*/
|
||||||
default boolean handle(VelocityServerConnection server,
|
default boolean handle(VelocityServerConnection server,
|
||||||
ConnectedPlayer player,
|
ConnectedPlayer player,
|
||||||
PluginMessagePacket message) {
|
AbstractPluginMessagePacket<?> message) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.velocitypowered.proxy.connection.backend;
|
|||||||
|
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeHandshakeBackendPhase;
|
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeHandshakeBackendPhase;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains Vanilla {@link BackendConnectionPhase}s.
|
* Contains Vanilla {@link BackendConnectionPhase}s.
|
||||||
@@ -29,7 +29,7 @@ public final class BackendConnectionPhases {
|
|||||||
@Override
|
@Override
|
||||||
public boolean handle(VelocityServerConnection serverConn,
|
public boolean handle(VelocityServerConnection serverConn,
|
||||||
ConnectedPlayer player,
|
ConnectedPlayer player,
|
||||||
PluginMessagePacket message) {
|
AbstractPluginMessagePacket<?> message) {
|
||||||
// The connection may be legacy forge. If so, the Forge handler will deal with this
|
// The connection may be legacy forge. If so, the Forge handler will deal with this
|
||||||
// for us. Otherwise, we have nothing to do.
|
// for us. Otherwise, we have nothing to do.
|
||||||
return LegacyForgeHandshakeBackendPhase.NOT_STARTED.handle(serverConn, player, message);
|
return LegacyForgeHandshakeBackendPhase.NOT_STARTED.handle(serverConn, player, message);
|
||||||
|
|||||||
@@ -16,15 +16,16 @@ import com.velocitypowered.proxy.connection.MinecraftConnection;
|
|||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
||||||
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
|
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
||||||
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundAvailableCommandsPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundBossBarPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PlayerListItemPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundKeepAlivePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPlayerListItemPacket;
|
||||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTabCompleteResponsePacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufUtil;
|
import io.netty.buffer.ByteBufUtil;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@@ -64,7 +65,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
serverConn.getServer().addPlayer(serverConn.getPlayer());
|
serverConn.getServer().addPlayer(serverConn.getPlayer());
|
||||||
MinecraftConnection serverMc = serverConn.ensureConnected();
|
MinecraftConnection serverMc = serverConn.ensureConnected();
|
||||||
serverMc.write(PluginMessageUtil.constructChannelsPacket(serverMc.getProtocolVersion(),
|
serverMc.write(PluginMessageUtil.constructChannelsPacket(serverMc.getProtocolVersion(),
|
||||||
ImmutableList.of(getBungeeCordChannel(serverMc.getProtocolVersion()))
|
ImmutableList.of(getBungeeCordChannel(serverMc.getProtocolVersion())), ClientboundPluginMessagePacket.FACTORY
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,30 +80,30 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(KeepAlivePacket packet) {
|
public boolean handle(ClientboundKeepAlivePacket packet) {
|
||||||
serverConn.setLastPingId(packet.getRandomId());
|
serverConn.setLastPingId(packet.getRandomId());
|
||||||
return false; // forwards on
|
return false; // forwards on
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(DisconnectPacket packet) {
|
public boolean handle(ClientboundDisconnectPacket packet) {
|
||||||
serverConn.disconnect();
|
serverConn.disconnect();
|
||||||
serverConn.getPlayer().handleConnectionException(serverConn.getServer(), packet, true);
|
serverConn.getPlayer().handleConnectionException(serverConn.getServer(), packet, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(BossBarPacket packet) {
|
public boolean handle(ClientboundBossBarPacket packet) {
|
||||||
if (packet.getAction() == BossBarPacket.ADD) {
|
if (packet.getAction() == ClientboundBossBarPacket.ADD) {
|
||||||
playerSessionHandler.getServerBossBars().add(packet.getUuid());
|
playerSessionHandler.getServerBossBars().add(packet.getUuid());
|
||||||
} else if (packet.getAction() == BossBarPacket.REMOVE) {
|
} else if (packet.getAction() == ClientboundBossBarPacket.REMOVE) {
|
||||||
playerSessionHandler.getServerBossBars().remove(packet.getUuid());
|
playerSessionHandler.getServerBossBars().remove(packet.getUuid());
|
||||||
}
|
}
|
||||||
return false; // forward
|
return false; // forward
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(PluginMessagePacket packet) {
|
public boolean handle(ClientboundPluginMessagePacket packet) {
|
||||||
if (bungeecordMessageResponder.process(packet)) {
|
if (bungeecordMessageResponder.process(packet)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -123,8 +124,8 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (PluginMessageUtil.isMcBrand(packet)) {
|
if (PluginMessageUtil.isMcBrand(packet)) {
|
||||||
PluginMessagePacket rewritten = PluginMessageUtil.rewriteMinecraftBrand(packet,
|
AbstractPluginMessagePacket<?> rewritten = PluginMessageUtil.rewriteMinecraftBrand(packet,
|
||||||
server.getVersion(), playerConnection.getProtocolVersion());
|
server.getVersion(), playerConnection.getProtocolVersion(), ClientboundPluginMessagePacket.FACTORY);
|
||||||
playerConnection.write(rewritten);
|
playerConnection.write(rewritten);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -145,7 +146,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
server.getEventManager().fire(event)
|
server.getEventManager().fire(event)
|
||||||
.thenAcceptAsync(pme -> {
|
.thenAcceptAsync(pme -> {
|
||||||
if (pme.getResult().isAllowed() && !playerConnection.isClosed()) {
|
if (pme.getResult().isAllowed() && !playerConnection.isClosed()) {
|
||||||
PluginMessagePacket copied = new PluginMessagePacket(packet.getChannel(),
|
ClientboundPluginMessagePacket copied = new ClientboundPluginMessagePacket(packet.getChannel(),
|
||||||
Unpooled.wrappedBuffer(copy));
|
Unpooled.wrappedBuffer(copy));
|
||||||
playerConnection.write(copied);
|
playerConnection.write(copied);
|
||||||
}
|
}
|
||||||
@@ -158,19 +159,19 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(TabCompleteResponsePacket packet) {
|
public boolean handle(ClientboundTabCompleteResponsePacket packet) {
|
||||||
playerSessionHandler.handleTabCompleteResponse(packet);
|
playerSessionHandler.handleTabCompleteResponse(packet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(PlayerListItemPacket packet) {
|
public boolean handle(ClientboundPlayerListItemPacket packet) {
|
||||||
serverConn.getPlayer().getTabList().processBackendPacket(packet);
|
serverConn.getPlayer().getTabList().processBackendPacket(packet);
|
||||||
return false; //Forward packet to player
|
return false; //Forward packet to player
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(AvailableCommandsPacket commands) {
|
public boolean handle(ClientboundAvailableCommandsPacket commands) {
|
||||||
RootCommandNode<CommandSource> rootNode = commands.getRootNode();
|
RootCommandNode<CommandSource> rootNode = commands.getRootNode();
|
||||||
if (server.getConfiguration().isAnnounceProxyCommands()) {
|
if (server.getConfiguration().isAnnounceProxyCommands()) {
|
||||||
// Inject commands from the proxy.
|
// Inject commands from the proxy.
|
||||||
@@ -244,8 +245,8 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleGeneric(Packet packet) {
|
public void handleGeneric(Packet packet) {
|
||||||
if (packet instanceof PluginMessagePacket) {
|
if (packet instanceof AbstractPluginMessagePacket<?>) {
|
||||||
((PluginMessagePacket) packet).retain();
|
((AbstractPluginMessagePacket<?>) packet).retain();
|
||||||
}
|
}
|
||||||
playerConnection.delayedWrite(packet);
|
playerConnection.delayedWrite(packet);
|
||||||
}
|
}
|
||||||
@@ -277,7 +278,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
if (!serverConn.isGracefulDisconnect() && !exceptionTriggered) {
|
if (!serverConn.isGracefulDisconnect() && !exceptionTriggered) {
|
||||||
if (server.getConfiguration().isFailoverOnUnexpectedServerDisconnect()) {
|
if (server.getConfiguration().isFailoverOnUnexpectedServerDisconnect()) {
|
||||||
serverConn.getPlayer().handleConnectionException(serverConn.getServer(),
|
serverConn.getPlayer().handleConnectionException(serverConn.getServer(),
|
||||||
DisconnectPacket.create(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR,
|
ClientboundDisconnectPacket.create(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR,
|
||||||
ProtocolVersion.MINECRAFT_1_16), true);
|
ProtocolVersion.MINECRAFT_1_16), true);
|
||||||
} else {
|
} else {
|
||||||
serverConn.getPlayer().disconnect(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
|
serverConn.getPlayer().disconnect(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
|
||||||
|
|||||||
@@ -9,9 +9,10 @@ import com.velocitypowered.api.util.UuidUtils;
|
|||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.buffer.ByteBufDataInput;
|
||||||
import com.velocitypowered.proxy.protocol.util.ByteBufDataInput;
|
import com.velocitypowered.proxy.network.buffer.ByteBufDataOutput;
|
||||||
import com.velocitypowered.proxy.protocol.util.ByteBufDataOutput;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
@@ -45,7 +46,7 @@ public class BungeeCordMessageResponder {
|
|||||||
this.player = player;
|
this.player = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isBungeeCordMessage(PluginMessagePacket message) {
|
public static boolean isBungeeCordMessage(AbstractPluginMessagePacket<?> message) {
|
||||||
return MODERN_CHANNEL.getId().equals(message.getChannel()) || LEGACY_CHANNEL.getId()
|
return MODERN_CHANNEL.getId().equals(message.getChannel()) || LEGACY_CHANNEL.getId()
|
||||||
.equals(message.getChannel());
|
.equals(message.getChannel());
|
||||||
}
|
}
|
||||||
@@ -303,7 +304,7 @@ public class BungeeCordMessageResponder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static String getBungeeCordChannel(ProtocolVersion version) {
|
static String getBungeeCordChannel(ProtocolVersion version) {
|
||||||
return version.compareTo(ProtocolVersion.MINECRAFT_1_13) >= 0 ? MODERN_CHANNEL.getId()
|
return version.gte(ProtocolVersion.MINECRAFT_1_13) ? MODERN_CHANNEL.getId()
|
||||||
: LEGACY_CHANNEL.getId();
|
: LEGACY_CHANNEL.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +313,7 @@ public class BungeeCordMessageResponder {
|
|||||||
MinecraftConnection serverConnection = player.ensureAndGetCurrentServer().ensureConnected();
|
MinecraftConnection serverConnection = player.ensureAndGetCurrentServer().ensureConnected();
|
||||||
String chan = getBungeeCordChannel(serverConnection.getProtocolVersion());
|
String chan = getBungeeCordChannel(serverConnection.getProtocolVersion());
|
||||||
|
|
||||||
PluginMessagePacket msg = null;
|
ServerboundPluginMessagePacket msg = null;
|
||||||
boolean released = false;
|
boolean released = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -322,7 +323,7 @@ public class BungeeCordMessageResponder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MinecraftConnection serverConn = vsc.ensureConnected();
|
MinecraftConnection serverConn = vsc.ensureConnected();
|
||||||
msg = new PluginMessagePacket(chan, buf);
|
msg = new ServerboundPluginMessagePacket(chan, buf);
|
||||||
serverConn.write(msg);
|
serverConn.write(msg);
|
||||||
released = true;
|
released = true;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -332,7 +333,7 @@ public class BungeeCordMessageResponder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean process(PluginMessagePacket message) {
|
boolean process(AbstractPluginMessagePacket<?> message) {
|
||||||
if (!proxy.getConfiguration().isBungeePluginChannelEnabled()) {
|
if (!proxy.getConfiguration().isBungeePluginChannelEnabled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
|||||||
import com.velocitypowered.proxy.connection.VelocityConstants;
|
import com.velocitypowered.proxy.connection.VelocityConstants;
|
||||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
|
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
|
||||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.network.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundEncryptionRequestPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundLoginPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponsePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundServerLoginSuccessPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundSetCompressionPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundLoginPluginResponsePacket;
|
||||||
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@@ -49,12 +49,12 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(EncryptionRequestPacket packet) {
|
public boolean handle(ClientboundEncryptionRequestPacket packet) {
|
||||||
throw new IllegalStateException("Backend server is online-mode!");
|
throw new IllegalStateException("Backend server is online-mode!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(LoginPluginMessagePacket packet) {
|
public boolean handle(ClientboundLoginPluginMessagePacket packet) {
|
||||||
MinecraftConnection mc = serverConn.ensureConnected();
|
MinecraftConnection mc = serverConn.ensureConnected();
|
||||||
VelocityConfiguration configuration = server.getConfiguration();
|
VelocityConfiguration configuration = server.getConfiguration();
|
||||||
if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN && packet
|
if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN && packet
|
||||||
@@ -62,32 +62,33 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
ByteBuf forwardingData = createForwardingData(configuration.getForwardingSecret(),
|
ByteBuf forwardingData = createForwardingData(configuration.getForwardingSecret(),
|
||||||
cleanRemoteAddress(serverConn.getPlayer().getRemoteAddress()),
|
cleanRemoteAddress(serverConn.getPlayer().getRemoteAddress()),
|
||||||
serverConn.getPlayer().getGameProfile());
|
serverConn.getPlayer().getGameProfile());
|
||||||
LoginPluginResponsePacket response = new LoginPluginResponsePacket(packet.getId(), true,
|
ServerboundLoginPluginResponsePacket response = new ServerboundLoginPluginResponsePacket(
|
||||||
forwardingData);
|
packet.getId(), true, forwardingData);
|
||||||
mc.write(response);
|
mc.write(response);
|
||||||
informationForwarded = true;
|
informationForwarded = true;
|
||||||
} else {
|
} else {
|
||||||
// Don't understand
|
// Don't understand
|
||||||
mc.write(new LoginPluginResponsePacket(packet.getId(), false, Unpooled.EMPTY_BUFFER));
|
mc.write(new ServerboundLoginPluginResponsePacket(packet.getId(), false,
|
||||||
|
Unpooled.EMPTY_BUFFER));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(DisconnectPacket packet) {
|
public boolean handle(ClientboundDisconnectPacket packet) {
|
||||||
resultFuture.complete(ConnectionRequestResults.forDisconnect(packet, serverConn.getServer()));
|
resultFuture.complete(ConnectionRequestResults.forDisconnect(packet, serverConn.getServer()));
|
||||||
serverConn.disconnect();
|
serverConn.disconnect();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(SetCompressionPacket packet) {
|
public boolean handle(ClientboundSetCompressionPacket packet) {
|
||||||
serverConn.ensureConnected().setCompressionThreshold(packet.getThreshold());
|
serverConn.ensureConnected().setCompressionThreshold(packet.getThreshold());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(ServerLoginSuccessPacket packet) {
|
public boolean handle(ClientboundServerLoginSuccessPacket packet) {
|
||||||
if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN
|
if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN
|
||||||
&& !informationForwarded) {
|
&& !informationForwarded) {
|
||||||
resultFuture.complete(ConnectionRequestResults.forDisconnect(MODERN_IP_FORWARDING_FAILURE,
|
resultFuture.complete(ConnectionRequestResults.forDisconnect(MODERN_IP_FORWARDING_FAILURE,
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
|||||||
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
|
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
|
||||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
|
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
|
||||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
||||||
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundJoinGamePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundKeepAlivePacket;
|
||||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@@ -60,13 +60,13 @@ public class TransitionSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(KeepAlivePacket packet) {
|
public boolean handle(ClientboundKeepAlivePacket packet) {
|
||||||
serverConn.ensureConnected().write(packet);
|
serverConn.ensureConnected().write(packet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(JoinGamePacket packet) {
|
public boolean handle(ClientboundJoinGamePacket packet) {
|
||||||
MinecraftConnection smc = serverConn.ensureConnected();
|
MinecraftConnection smc = serverConn.ensureConnected();
|
||||||
VelocityServerConnection existingConnection = serverConn.getPlayer().getConnectedServer();
|
VelocityServerConnection existingConnection = serverConn.getPlayer().getConnectedServer();
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ public class TransitionSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(DisconnectPacket packet) {
|
public boolean handle(ClientboundDisconnectPacket packet) {
|
||||||
final MinecraftConnection connection = serverConn.ensureConnected();
|
final MinecraftConnection connection = serverConn.ensureConnected();
|
||||||
serverConn.disconnect();
|
serverConn.disconnect();
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ public class TransitionSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(PluginMessagePacket packet) {
|
public boolean handle(ClientboundPluginMessagePacket packet) {
|
||||||
if (!serverConn.getPlayer().canForwardPluginMessage(serverConn.ensureConnected()
|
if (!serverConn.getPlayer().canForwardPluginMessage(serverConn.ensureConnected()
|
||||||
.getProtocolVersion(), packet)) {
|
.getProtocolVersion(), packet)) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
|
|||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import com.velocitypowered.proxy.connection.registry.DimensionRegistry;
|
import com.velocitypowered.proxy.connection.registry.DimensionRegistry;
|
||||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.network.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundJoinGamePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundHandshakePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundServerLoginPacket;
|
||||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@@ -143,7 +143,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
|||||||
|
|
||||||
// Initiate the handshake.
|
// Initiate the handshake.
|
||||||
ProtocolVersion protocolVersion = proxyPlayer.getConnection().getProtocolVersion();
|
ProtocolVersion protocolVersion = proxyPlayer.getConnection().getProtocolVersion();
|
||||||
HandshakePacket handshake = new HandshakePacket();
|
ServerboundHandshakePacket handshake = new ServerboundHandshakePacket();
|
||||||
handshake.setNextStatus(StateRegistry.LOGIN_ID);
|
handshake.setNextStatus(StateRegistry.LOGIN_ID);
|
||||||
handshake.setProtocolVersion(protocolVersion);
|
handshake.setProtocolVersion(protocolVersion);
|
||||||
if (forwardingMode == PlayerInfoForwarding.LEGACY) {
|
if (forwardingMode == PlayerInfoForwarding.LEGACY) {
|
||||||
@@ -165,7 +165,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
|||||||
|
|
||||||
mc.setProtocolVersion(protocolVersion);
|
mc.setProtocolVersion(protocolVersion);
|
||||||
mc.setState(StateRegistry.LOGIN);
|
mc.setState(StateRegistry.LOGIN);
|
||||||
mc.delayedWrite(new ServerLoginPacket(proxyPlayer.getUsername()));
|
mc.delayedWrite(new ServerboundServerLoginPacket(proxyPlayer.getUsername()));
|
||||||
mc.flush();
|
mc.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
|||||||
|
|
||||||
MinecraftConnection mc = ensureConnected();
|
MinecraftConnection mc = ensureConnected();
|
||||||
|
|
||||||
PluginMessagePacket message = new PluginMessagePacket(identifier.getId(), data);
|
ServerboundPluginMessagePacket message = new ServerboundPluginMessagePacket(identifier.getId(), data);
|
||||||
mc.write(message);
|
mc.write(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether the {@link JoinGamePacket}
|
* Gets whether the {@link ClientboundJoinGamePacket}
|
||||||
* packet has been sent by this server.
|
* packet has been sent by this server.
|
||||||
*
|
*
|
||||||
* @return Whether the join has been completed.
|
* @return Whether the join has been completed.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.velocitypowered.proxy.connection.client;
|
|||||||
|
|
||||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||||
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeHandshakeClientPhase;
|
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeHandshakeClientPhase;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides connection phase specific actions.
|
* Provides connection phase specific actions.
|
||||||
@@ -22,7 +22,7 @@ public interface ClientConnectionPhase {
|
|||||||
* @return true if handled, false otherwise.
|
* @return true if handled, false otherwise.
|
||||||
*/
|
*/
|
||||||
default boolean handle(ConnectedPlayer player,
|
default boolean handle(ConnectedPlayer player,
|
||||||
PluginMessagePacket message,
|
AbstractPluginMessagePacket<?> message,
|
||||||
VelocityServerConnection server) {
|
VelocityServerConnection server) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.velocitypowered.proxy.connection.client;
|
|||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
|
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
|
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
|
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
|
||||||
import static com.velocitypowered.proxy.protocol.util.PluginMessageUtil.constructChannelsPacket;
|
import static com.velocitypowered.proxy.network.PluginMessageUtil.constructChannelsPacket;
|
||||||
|
|
||||||
import com.velocitypowered.api.event.command.CommandExecuteEvent.CommandResult;
|
import com.velocitypowered.api.event.command.CommandExecuteEvent.CommandResult;
|
||||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
@@ -19,21 +19,23 @@ import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
|||||||
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases;
|
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases;
|
||||||
import com.velocitypowered.proxy.connection.backend.BungeeCordMessageResponder;
|
import com.velocitypowered.proxy.connection.backend.BungeeCordMessageResponder;
|
||||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.network.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ChatPacket;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundBossBarPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundJoinGamePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundRespawnPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTabCompleteResponsePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTabCompleteResponsePacket.Offer;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTitlePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket.Offer;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundClientSettingsPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TitlePacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundKeepAlivePacket;
|
||||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundPluginMessagePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundResourcePackResponsePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundTabCompleteRequestPacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufUtil;
|
import io.netty.buffer.ByteBufUtil;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@@ -64,9 +66,9 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
private final ConnectedPlayer player;
|
private final ConnectedPlayer player;
|
||||||
private boolean spawned = false;
|
private boolean spawned = false;
|
||||||
private final List<UUID> serverBossBars = new ArrayList<>();
|
private final List<UUID> serverBossBars = new ArrayList<>();
|
||||||
private final Queue<PluginMessagePacket> loginPluginMessages = new ArrayDeque<>();
|
private final Queue<ServerboundPluginMessagePacket> loginPluginMessages = new ArrayDeque<>();
|
||||||
private final VelocityServer server;
|
private final VelocityServer server;
|
||||||
private @Nullable TabCompleteRequestPacket outstandingTabComplete;
|
private @Nullable ServerboundTabCompleteRequestPacket outstandingTabComplete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a client play session handler.
|
* Constructs a client play session handler.
|
||||||
@@ -83,7 +85,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
Collection<String> channels = server.getChannelRegistrar().getChannelsForProtocol(player
|
Collection<String> channels = server.getChannelRegistrar().getChannelsForProtocol(player
|
||||||
.getProtocolVersion());
|
.getProtocolVersion());
|
||||||
if (!channels.isEmpty()) {
|
if (!channels.isEmpty()) {
|
||||||
PluginMessagePacket register = constructChannelsPacket(player.getProtocolVersion(), channels);
|
AbstractPluginMessagePacket<?> register = constructChannelsPacket(player.getProtocolVersion(),
|
||||||
|
channels, ClientboundPluginMessagePacket.FACTORY);
|
||||||
player.getConnection().write(register);
|
player.getConnection().write(register);
|
||||||
player.getKnownChannels().addAll(channels);
|
player.getKnownChannels().addAll(channels);
|
||||||
}
|
}
|
||||||
@@ -91,13 +94,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deactivated() {
|
public void deactivated() {
|
||||||
for (PluginMessagePacket message : loginPluginMessages) {
|
for (ServerboundPluginMessagePacket message : loginPluginMessages) {
|
||||||
ReferenceCountUtil.release(message);
|
ReferenceCountUtil.release(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(KeepAlivePacket packet) {
|
public boolean handle(ServerboundKeepAlivePacket packet) {
|
||||||
VelocityServerConnection serverConnection = player.getConnectedServer();
|
VelocityServerConnection serverConnection = player.getConnectedServer();
|
||||||
if (serverConnection != null && packet.getRandomId() == serverConnection.getLastPingId()) {
|
if (serverConnection != null && packet.getRandomId() == serverConnection.getLastPingId()) {
|
||||||
MinecraftConnection smc = serverConnection.getConnection();
|
MinecraftConnection smc = serverConnection.getConnection();
|
||||||
@@ -111,13 +114,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(ClientSettingsPacket packet) {
|
public boolean handle(ServerboundClientSettingsPacket packet) {
|
||||||
player.setPlayerSettings(packet);
|
player.setPlayerSettings(packet);
|
||||||
return false; // will forward onto the server
|
return false; // will forward onto the server
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(ChatPacket packet) {
|
public boolean handle(ServerboundChatPacket packet) {
|
||||||
VelocityServerConnection serverConnection = player.getConnectedServer();
|
VelocityServerConnection serverConnection = player.getConnectedServer();
|
||||||
if (serverConnection == null) {
|
if (serverConnection == null) {
|
||||||
return true;
|
return true;
|
||||||
@@ -154,7 +157,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
if (chatResult.isAllowed()) {
|
if (chatResult.isAllowed()) {
|
||||||
Optional<String> eventMsg = pme.getResult().getMessage();
|
Optional<String> eventMsg = pme.getResult().getMessage();
|
||||||
if (eventMsg.isPresent()) {
|
if (eventMsg.isPresent()) {
|
||||||
smc.write(ChatPacket.createServerbound(eventMsg.get()));
|
smc.write(new ServerboundChatPacket(eventMsg.get()));
|
||||||
} else {
|
} else {
|
||||||
smc.write(packet);
|
smc.write(packet);
|
||||||
}
|
}
|
||||||
@@ -169,7 +172,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(TabCompleteRequestPacket packet) {
|
public boolean handle(ServerboundTabCompleteRequestPacket packet) {
|
||||||
boolean isCommand = !packet.isAssumeCommand() && packet.getCommand().startsWith("/");
|
boolean isCommand = !packet.isAssumeCommand() && packet.getCommand().startsWith("/");
|
||||||
|
|
||||||
if (isCommand) {
|
if (isCommand) {
|
||||||
@@ -180,7 +183,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(PluginMessagePacket packet) {
|
public boolean handle(ServerboundPluginMessagePacket packet) {
|
||||||
VelocityServerConnection serverConn = player.getConnectedServer();
|
VelocityServerConnection serverConn = player.getConnectedServer();
|
||||||
MinecraftConnection backendConn = serverConn != null ? serverConn.getConnection() : null;
|
MinecraftConnection backendConn = serverConn != null ? serverConn.getConnection() : null;
|
||||||
if (serverConn != null && backendConn != null) {
|
if (serverConn != null && backendConn != null) {
|
||||||
@@ -195,7 +198,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
backendConn.write(packet.retain());
|
backendConn.write(packet.retain());
|
||||||
} else if (PluginMessageUtil.isMcBrand(packet)) {
|
} else if (PluginMessageUtil.isMcBrand(packet)) {
|
||||||
backendConn.write(PluginMessageUtil
|
backendConn.write(PluginMessageUtil
|
||||||
.rewriteMinecraftBrand(packet, server.getVersion(), player.getProtocolVersion()));
|
.rewriteMinecraftBrand(packet, server.getVersion(), player.getProtocolVersion(), ServerboundPluginMessagePacket.FACTORY));
|
||||||
} else if (BungeeCordMessageResponder.isBungeeCordMessage(packet)) {
|
} else if (BungeeCordMessageResponder.isBungeeCordMessage(packet)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -228,7 +231,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
PluginMessageEvent event = new PluginMessageEvent(player, serverConn, id, copy);
|
PluginMessageEvent event = new PluginMessageEvent(player, serverConn, id, copy);
|
||||||
server.getEventManager().fire(event).thenAcceptAsync(pme -> {
|
server.getEventManager().fire(event).thenAcceptAsync(pme -> {
|
||||||
if (pme.getResult().isAllowed()) {
|
if (pme.getResult().isAllowed()) {
|
||||||
PluginMessagePacket message = new PluginMessagePacket(packet.getChannel(),
|
ServerboundPluginMessagePacket message = new ServerboundPluginMessagePacket(packet.getChannel(),
|
||||||
Unpooled.wrappedBuffer(copy));
|
Unpooled.wrappedBuffer(copy));
|
||||||
backendConn.write(message);
|
backendConn.write(message);
|
||||||
}
|
}
|
||||||
@@ -248,7 +251,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(ResourcePackResponsePacket packet) {
|
public boolean handle(ServerboundResourcePackResponsePacket packet) {
|
||||||
server.getEventManager().fireAndForget(new PlayerResourcePackStatusEvent(player,
|
server.getEventManager().fireAndForget(new PlayerResourcePackStatusEvent(player,
|
||||||
packet.getStatus()));
|
packet.getStatus()));
|
||||||
return false;
|
return false;
|
||||||
@@ -264,8 +267,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
MinecraftConnection smc = serverConnection.getConnection();
|
MinecraftConnection smc = serverConnection.getConnection();
|
||||||
if (smc != null && serverConnection.getPhase().consideredComplete()) {
|
if (smc != null && serverConnection.getPhase().consideredComplete()) {
|
||||||
if (packet instanceof PluginMessagePacket) {
|
if (packet instanceof AbstractPluginMessagePacket<?>) {
|
||||||
((PluginMessagePacket) packet).retain();
|
((AbstractPluginMessagePacket<?>) packet).retain();
|
||||||
}
|
}
|
||||||
smc.write(packet);
|
smc.write(packet);
|
||||||
}
|
}
|
||||||
@@ -319,7 +322,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
* @param joinGame the join game packet
|
* @param joinGame the join game packet
|
||||||
* @param destination the new server we are connecting to
|
* @param destination the new server we are connecting to
|
||||||
*/
|
*/
|
||||||
public void handleBackendJoinGame(JoinGamePacket joinGame, VelocityServerConnection destination) {
|
public void handleBackendJoinGame(ClientboundJoinGamePacket joinGame,
|
||||||
|
VelocityServerConnection destination) {
|
||||||
final MinecraftConnection serverMc = destination.ensureConnected();
|
final MinecraftConnection serverMc = destination.ensureConnected();
|
||||||
|
|
||||||
if (!spawned) {
|
if (!spawned) {
|
||||||
@@ -344,9 +348,9 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
// Remove previous boss bars. These don't get cleared when sending JoinGame, thus the need to
|
// Remove previous boss bars. These don't get cleared when sending JoinGame, thus the need to
|
||||||
// track them.
|
// track them.
|
||||||
for (UUID serverBossBar : serverBossBars) {
|
for (UUID serverBossBar : serverBossBars) {
|
||||||
BossBarPacket deletePacket = new BossBarPacket();
|
ClientboundBossBarPacket deletePacket = new ClientboundBossBarPacket();
|
||||||
deletePacket.setUuid(serverBossBar);
|
deletePacket.setUuid(serverBossBar);
|
||||||
deletePacket.setAction(BossBarPacket.REMOVE);
|
deletePacket.setAction(ClientboundBossBarPacket.REMOVE);
|
||||||
player.getConnection().delayedWrite(deletePacket);
|
player.getConnection().delayedWrite(deletePacket);
|
||||||
}
|
}
|
||||||
serverBossBars.clear();
|
serverBossBars.clear();
|
||||||
@@ -354,19 +358,19 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
// Tell the server about this client's plugin message channels.
|
// Tell the server about this client's plugin message channels.
|
||||||
ProtocolVersion serverVersion = serverMc.getProtocolVersion();
|
ProtocolVersion serverVersion = serverMc.getProtocolVersion();
|
||||||
if (!player.getKnownChannels().isEmpty()) {
|
if (!player.getKnownChannels().isEmpty()) {
|
||||||
serverMc.delayedWrite(constructChannelsPacket(serverVersion, player.getKnownChannels()));
|
serverMc.delayedWrite(constructChannelsPacket(serverVersion, player.getKnownChannels(), ServerboundPluginMessagePacket.FACTORY));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we had plugin messages queued during login/FML handshake, send them now.
|
// If we had plugin messages queued during login/FML handshake, send them now.
|
||||||
PluginMessagePacket pm;
|
ServerboundPluginMessagePacket pm;
|
||||||
while ((pm = loginPluginMessages.poll()) != null) {
|
while ((pm = loginPluginMessages.poll()) != null) {
|
||||||
serverMc.delayedWrite(pm);
|
serverMc.delayedWrite(pm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear any title from the previous server.
|
// Clear any title from the previous server.
|
||||||
if (player.getProtocolVersion().compareTo(MINECRAFT_1_8) >= 0) {
|
if (player.getProtocolVersion().gte(MINECRAFT_1_8)) {
|
||||||
player.getConnection()
|
player.getConnection()
|
||||||
.delayedWrite(TitlePacket.resetForProtocolVersion(player.getProtocolVersion()));
|
.delayedWrite(ClientboundTitlePacket.reset(player.getProtocolVersion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush everything
|
// Flush everything
|
||||||
@@ -375,7 +379,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
destination.completeJoin();
|
destination.completeJoin();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doFastClientServerSwitch(JoinGamePacket joinGame) {
|
private void doFastClientServerSwitch(ClientboundJoinGamePacket joinGame) {
|
||||||
// In order to handle switching to another server, you will need to send two packets:
|
// In order to handle switching to another server, you will need to send two packets:
|
||||||
//
|
//
|
||||||
// - The join game packet from the backend server, with a different dimension
|
// - The join game packet from the backend server, with a different dimension
|
||||||
@@ -385,7 +389,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
// to perform entity ID rewrites, eliminating potential issues from rewriting packets and
|
// to perform entity ID rewrites, eliminating potential issues from rewriting packets and
|
||||||
// improving compatibility with mods.
|
// improving compatibility with mods.
|
||||||
int sentOldDim = joinGame.getDimension();
|
int sentOldDim = joinGame.getDimension();
|
||||||
if (player.getProtocolVersion().compareTo(MINECRAFT_1_16) < 0) {
|
if (player.getProtocolVersion().lt(MINECRAFT_1_16)) {
|
||||||
// Before Minecraft 1.16, we could not switch to the same dimension without sending an
|
// Before Minecraft 1.16, we could not switch to the same dimension without sending an
|
||||||
// additional respawn. On older versions of Minecraft this forces the client to perform
|
// additional respawn. On older versions of Minecraft this forces the client to perform
|
||||||
// garbage collection which adds additional latency.
|
// garbage collection which adds additional latency.
|
||||||
@@ -394,13 +398,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
player.getConnection().delayedWrite(joinGame);
|
player.getConnection().delayedWrite(joinGame);
|
||||||
|
|
||||||
player.getConnection().delayedWrite(
|
player.getConnection().delayedWrite(
|
||||||
new RespawnPacket(sentOldDim, joinGame.getPartialHashedSeed(),
|
new ClientboundRespawnPacket(sentOldDim, joinGame.getPartialHashedSeed(),
|
||||||
joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType(),
|
joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType(),
|
||||||
false, joinGame.getDimensionInfo(), joinGame.getPreviousGamemode(),
|
false, joinGame.getDimensionInfo(), joinGame.getPreviousGamemode(),
|
||||||
joinGame.getCurrentDimensionData()));
|
joinGame.getCurrentDimensionData()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doSafeClientServerSwitch(JoinGamePacket joinGame) {
|
private void doSafeClientServerSwitch(ClientboundJoinGamePacket joinGame) {
|
||||||
// Some clients do not behave well with the "fast" respawn sequence. In this case we will use
|
// Some clients do not behave well with the "fast" respawn sequence. In this case we will use
|
||||||
// a "safe" respawn sequence that involves sending three packets to the client. They have the
|
// a "safe" respawn sequence that involves sending three packets to the client. They have the
|
||||||
// same effect but tend to work better with buggier clients (Forge 1.8 in particular).
|
// same effect but tend to work better with buggier clients (Forge 1.8 in particular).
|
||||||
@@ -411,14 +415,14 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
// Send a respawn packet in a different dimension.
|
// Send a respawn packet in a different dimension.
|
||||||
int tempDim = joinGame.getDimension() == 0 ? -1 : 0;
|
int tempDim = joinGame.getDimension() == 0 ? -1 : 0;
|
||||||
player.getConnection().delayedWrite(
|
player.getConnection().delayedWrite(
|
||||||
new RespawnPacket(tempDim, joinGame.getPartialHashedSeed(), joinGame.getDifficulty(),
|
new ClientboundRespawnPacket(tempDim, joinGame.getPartialHashedSeed(),
|
||||||
joinGame.getGamemode(), joinGame.getLevelType(),
|
joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType(),
|
||||||
false, joinGame.getDimensionInfo(), joinGame.getPreviousGamemode(),
|
false, joinGame.getDimensionInfo(), joinGame.getPreviousGamemode(),
|
||||||
joinGame.getCurrentDimensionData()));
|
joinGame.getCurrentDimensionData()));
|
||||||
|
|
||||||
// Now send a respawn packet in the correct dimension.
|
// Now send a respawn packet in the correct dimension.
|
||||||
player.getConnection().delayedWrite(
|
player.getConnection().delayedWrite(
|
||||||
new RespawnPacket(joinGame.getDimension(), joinGame.getPartialHashedSeed(),
|
new ClientboundRespawnPacket(joinGame.getDimension(), joinGame.getPartialHashedSeed(),
|
||||||
joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType(),
|
joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType(),
|
||||||
false, joinGame.getDimensionInfo(), joinGame.getPreviousGamemode(),
|
false, joinGame.getDimensionInfo(), joinGame.getPreviousGamemode(),
|
||||||
joinGame.getCurrentDimensionData()));
|
joinGame.getCurrentDimensionData()));
|
||||||
@@ -428,7 +432,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
return serverBossBars;
|
return serverBossBars;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleCommandTabComplete(TabCompleteRequestPacket packet) {
|
private boolean handleCommandTabComplete(ServerboundTabCompleteRequestPacket packet) {
|
||||||
// In 1.13+, we need to do additional work for the richer suggestions available.
|
// In 1.13+, we need to do additional work for the richer suggestions available.
|
||||||
String command = packet.getCommand().substring(1);
|
String command = packet.getCommand().substring(1);
|
||||||
int commandEndPosition = command.indexOf(' ');
|
int commandEndPosition = command.indexOf(' ');
|
||||||
@@ -438,7 +442,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
String commandLabel = command.substring(0, commandEndPosition);
|
String commandLabel = command.substring(0, commandEndPosition);
|
||||||
if (!server.getCommandManager().hasCommand(commandLabel)) {
|
if (!server.getCommandManager().hasCommand(commandLabel)) {
|
||||||
if (player.getProtocolVersion().compareTo(MINECRAFT_1_13) < 0) {
|
if (player.getProtocolVersion().lt(MINECRAFT_1_13)) {
|
||||||
// Outstanding tab completes are recorded for use with 1.12 clients and below to provide
|
// Outstanding tab completes are recorded for use with 1.12 clients and below to provide
|
||||||
// additional tab completion support.
|
// additional tab completion support.
|
||||||
outstandingTabComplete = packet;
|
outstandingTabComplete = packet;
|
||||||
@@ -458,7 +462,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
int startPos = packet.getCommand().lastIndexOf(' ') + 1;
|
int startPos = packet.getCommand().lastIndexOf(' ') + 1;
|
||||||
if (startPos > 0) {
|
if (startPos > 0) {
|
||||||
TabCompleteResponsePacket resp = new TabCompleteResponsePacket();
|
ClientboundTabCompleteResponsePacket resp = new ClientboundTabCompleteResponsePacket();
|
||||||
resp.setTransactionId(packet.getTransactionId());
|
resp.setTransactionId(packet.getTransactionId());
|
||||||
resp.setStart(startPos);
|
resp.setStart(startPos);
|
||||||
resp.setLength(packet.getCommand().length() - startPos);
|
resp.setLength(packet.getCommand().length() - startPos);
|
||||||
@@ -474,8 +478,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
return true; // Sorry, handler; we're just gonna have to lie to you here.
|
return true; // Sorry, handler; we're just gonna have to lie to you here.
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleRegularTabComplete(TabCompleteRequestPacket packet) {
|
private boolean handleRegularTabComplete(ServerboundTabCompleteRequestPacket packet) {
|
||||||
if (player.getProtocolVersion().compareTo(MINECRAFT_1_13) < 0) {
|
if (player.getProtocolVersion().lt(MINECRAFT_1_13)) {
|
||||||
// Outstanding tab completes are recorded for use with 1.12 clients and below to provide
|
// Outstanding tab completes are recorded for use with 1.12 clients and below to provide
|
||||||
// additional tab completion support.
|
// additional tab completion support.
|
||||||
outstandingTabComplete = packet;
|
outstandingTabComplete = packet;
|
||||||
@@ -488,7 +492,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
*
|
*
|
||||||
* @param response the tab complete response from the backend
|
* @param response the tab complete response from the backend
|
||||||
*/
|
*/
|
||||||
public void handleTabCompleteResponse(TabCompleteResponsePacket response) {
|
public void handleTabCompleteResponse(ClientboundTabCompleteResponsePacket response) {
|
||||||
if (outstandingTabComplete != null && !outstandingTabComplete.isAssumeCommand()) {
|
if (outstandingTabComplete != null && !outstandingTabComplete.isAssumeCommand()) {
|
||||||
if (outstandingTabComplete.getCommand().startsWith("/")) {
|
if (outstandingTabComplete.getCommand().startsWith("/")) {
|
||||||
this.finishCommandTabComplete(outstandingTabComplete, response);
|
this.finishCommandTabComplete(outstandingTabComplete, response);
|
||||||
@@ -502,12 +506,12 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finishCommandTabComplete(TabCompleteRequestPacket request,
|
private void finishCommandTabComplete(ServerboundTabCompleteRequestPacket request,
|
||||||
TabCompleteResponsePacket response) {
|
ClientboundTabCompleteResponsePacket response) {
|
||||||
String command = request.getCommand().substring(1);
|
String command = request.getCommand().substring(1);
|
||||||
server.getCommandManager().offerSuggestions(player, command)
|
server.getCommandManager().offerSuggestions(player, command)
|
||||||
.thenAcceptAsync(offers -> {
|
.thenAcceptAsync(offers -> {
|
||||||
boolean legacy = player.getProtocolVersion().compareTo(MINECRAFT_1_13) < 0;
|
boolean legacy = player.getProtocolVersion().lt(MINECRAFT_1_13);
|
||||||
try {
|
try {
|
||||||
for (String offer : offers) {
|
for (String offer : offers) {
|
||||||
offer = legacy && !offer.startsWith("/") ? "/" + offer : offer;
|
offer = legacy && !offer.startsWith("/") ? "/" + offer : offer;
|
||||||
@@ -532,8 +536,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finishRegularTabComplete(TabCompleteRequestPacket request,
|
private void finishRegularTabComplete(ServerboundTabCompleteRequestPacket request,
|
||||||
TabCompleteResponsePacket response) {
|
ClientboundTabCompleteResponsePacket response) {
|
||||||
List<String> offers = new ArrayList<>();
|
List<String> offers = new ArrayList<>();
|
||||||
for (Offer offer : response.getOffers()) {
|
for (Offer offer : response.getOffers()) {
|
||||||
offers.add(offer.getText());
|
offers.add(offer.getText());
|
||||||
@@ -563,13 +567,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
MinecraftConnection smc = player.ensureAndGetCurrentServer().ensureConnected();
|
MinecraftConnection smc = player.ensureAndGetCurrentServer().ensureConnected();
|
||||||
String commandToRun = result.getCommand().orElse(originalCommand);
|
String commandToRun = result.getCommand().orElse(originalCommand);
|
||||||
if (result.isForwardToServer()) {
|
if (result.isForwardToServer()) {
|
||||||
return CompletableFuture.runAsync(() -> smc.write(ChatPacket.createServerbound("/"
|
return CompletableFuture.runAsync(() -> smc.write(new ServerboundChatPacket("/"
|
||||||
+ commandToRun)), smc.eventLoop());
|
+ commandToRun)), smc.eventLoop());
|
||||||
} else {
|
} else {
|
||||||
return server.getCommandManager().executeImmediately(player, commandToRun)
|
return server.getCommandManager().executeImmediately(player, commandToRun)
|
||||||
.thenAcceptAsync(hasRun -> {
|
.thenAcceptAsync(hasRun -> {
|
||||||
if (!hasRun) {
|
if (!hasRun) {
|
||||||
smc.write(ChatPacket.createServerbound("/" + commandToRun));
|
smc.write(new ServerboundChatPacket("/" + commandToRun));
|
||||||
}
|
}
|
||||||
}, smc.eventLoop());
|
}, smc.eventLoop());
|
||||||
}
|
}
|
||||||
@@ -583,7 +587,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
if (serverConnection != null) {
|
if (serverConnection != null) {
|
||||||
MinecraftConnection connection = serverConnection.getConnection();
|
MinecraftConnection connection = serverConnection.getConnection();
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
PluginMessagePacket pm;
|
ServerboundPluginMessagePacket pm;
|
||||||
while ((pm = loginPluginMessages.poll()) != null) {
|
while ((pm = loginPluginMessages.poll()) != null) {
|
||||||
connection.write(pm);
|
connection.write(pm);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,20 +2,20 @@ package com.velocitypowered.proxy.connection.client;
|
|||||||
|
|
||||||
import com.velocitypowered.api.proxy.player.PlayerSettings;
|
import com.velocitypowered.api.proxy.player.PlayerSettings;
|
||||||
import com.velocitypowered.api.proxy.player.SkinParts;
|
import com.velocitypowered.api.proxy.player.SkinParts;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundClientSettingsPacket;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class ClientSettingsWrapper implements PlayerSettings {
|
public class ClientSettingsWrapper implements PlayerSettings {
|
||||||
|
|
||||||
static final PlayerSettings DEFAULT = new ClientSettingsWrapper(
|
static final PlayerSettings DEFAULT = new ClientSettingsWrapper(
|
||||||
new ClientSettingsPacket("en_US", (byte) 10, 0, true, (short) 127, 1));
|
new ServerboundClientSettingsPacket("en_US", (byte) 10, 0, true, (short) 127, 1));
|
||||||
|
|
||||||
private final ClientSettingsPacket settings;
|
private final ServerboundClientSettingsPacket settings;
|
||||||
private final SkinParts parts;
|
private final SkinParts parts;
|
||||||
private @Nullable Locale locale;
|
private @Nullable Locale locale;
|
||||||
|
|
||||||
ClientSettingsWrapper(ClientSettingsPacket settings) {
|
ClientSettingsWrapper(ServerboundClientSettingsPacket settings) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.parts = new SkinParts((byte) settings.getSkinParts());
|
this.parts = new SkinParts((byte) settings.getSkinParts());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,20 +36,21 @@ import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
|||||||
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants;
|
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants;
|
||||||
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
|
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
|
||||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ChatPacket;
|
import com.velocitypowered.proxy.network.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundKeepAlivePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequestPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TitlePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundResourcePackRequestPacket;
|
||||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTitlePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundChatPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundClientSettingsPacket;
|
||||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||||
import com.velocitypowered.proxy.tablist.VelocityTabList;
|
import com.velocitypowered.proxy.tablist.VelocityTabList;
|
||||||
import com.velocitypowered.proxy.tablist.VelocityTabListLegacy;
|
import com.velocitypowered.proxy.tablist.VelocityTabListLegacy;
|
||||||
import com.velocitypowered.proxy.util.DurationUtils;
|
|
||||||
import com.velocitypowered.proxy.util.collect.CappedSet;
|
import com.velocitypowered.proxy.util.collect.CappedSet;
|
||||||
import io.netty.buffer.ByteBufUtil;
|
import io.netty.buffer.ByteBufUtil;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@@ -112,7 +113,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
ConnectedPlayer(VelocityServer server, GameProfile profile, MinecraftConnection connection,
|
ConnectedPlayer(VelocityServer server, GameProfile profile, MinecraftConnection connection,
|
||||||
@Nullable InetSocketAddress virtualHost, boolean onlineMode) {
|
@Nullable InetSocketAddress virtualHost, boolean onlineMode) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
if (connection.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (connection.getProtocolVersion().gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
this.tabList = new VelocityTabList(connection);
|
this.tabList = new VelocityTabList(connection);
|
||||||
} else {
|
} else {
|
||||||
this.tabList = new VelocityTabListLegacy(connection);
|
this.tabList = new VelocityTabListLegacy(connection);
|
||||||
@@ -186,7 +187,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
return settings == null ? ClientSettingsWrapper.DEFAULT : this.settings;
|
return settings == null ? ClientSettingsWrapper.DEFAULT : this.settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPlayerSettings(ClientSettingsPacket settings) {
|
void setPlayerSettings(ServerboundClientSettingsPacket settings) {
|
||||||
ClientSettingsWrapper cs = new ClientSettingsWrapper(settings);
|
ClientSettingsWrapper cs = new ClientSettingsWrapper(settings);
|
||||||
this.settings = cs;
|
this.settings = cs;
|
||||||
server.getEventManager().fireAndForget(new PlayerSettingsChangedEvent(this, cs));
|
server.getEventManager().fireAndForget(new PlayerSettingsChangedEvent(this, cs));
|
||||||
@@ -226,41 +227,40 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
return connection.getProtocolVersion();
|
return connection.getProtocolVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendMessage(@NonNull Identity identity, @NonNull Component message) {
|
|
||||||
connection.write(ChatPacket.createClientbound(identity, message, this.getProtocolVersion()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(@NonNull Identity identity, @NonNull Component message,
|
public void sendMessage(@NonNull Identity identity, @NonNull Component message,
|
||||||
@NonNull MessageType type) {
|
@NonNull MessageType type) {
|
||||||
Preconditions.checkNotNull(message, "message");
|
Preconditions.checkNotNull(message, "message");
|
||||||
Preconditions.checkNotNull(type, "type");
|
Preconditions.checkNotNull(type, "type");
|
||||||
|
|
||||||
ChatPacket packet = ChatPacket.createClientbound(identity, message, this.getProtocolVersion());
|
connection.write(new ClientboundChatPacket(
|
||||||
packet.setType(type == MessageType.CHAT ? ChatPacket.CHAT_TYPE : ChatPacket.SYSTEM_TYPE);
|
ProtocolUtils.getJsonChatSerializer(this.getProtocolVersion()).serialize(message),
|
||||||
connection.write(packet);
|
type == MessageType.CHAT
|
||||||
|
? ClientboundChatPacket.CHAT_TYPE
|
||||||
|
: ClientboundChatPacket.SYSTEM_TYPE,
|
||||||
|
identity.uuid()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendActionBar(net.kyori.adventure.text.@NonNull Component message) {
|
public void sendActionBar(net.kyori.adventure.text.@NonNull Component message) {
|
||||||
ProtocolVersion playerVersion = getProtocolVersion();
|
ProtocolVersion playerVersion = getProtocolVersion();
|
||||||
if (playerVersion.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0) {
|
if (playerVersion.gte(ProtocolVersion.MINECRAFT_1_11)) {
|
||||||
// Use the title packet instead.
|
// Use the title packet instead.
|
||||||
TitlePacket pkt = new TitlePacket();
|
connection.write(new ClientboundTitlePacket(
|
||||||
pkt.setAction(TitlePacket.SET_ACTION_BAR);
|
ClientboundTitlePacket.SET_ACTION_BAR,
|
||||||
pkt.setComponent(ProtocolUtils.getJsonChatSerializer(playerVersion)
|
ProtocolUtils.getJsonChatSerializer(playerVersion).serialize(message)
|
||||||
.serialize(message));
|
));
|
||||||
connection.write(pkt);
|
|
||||||
} else {
|
} else {
|
||||||
// Due to issues with action bar packets, we'll need to convert the text message into a
|
// Due to issues with action bar packets, we'll need to convert the text message into a
|
||||||
// legacy message and then inject the legacy text into a component... yuck!
|
// legacy message and then inject the legacy text into a component... yuck!
|
||||||
JsonObject object = new JsonObject();
|
JsonObject object = new JsonObject();
|
||||||
object.addProperty("text", LegacyComponentSerializer.legacySection().serialize(message));
|
object.addProperty("text", LegacyComponentSerializer.legacySection().serialize(message));
|
||||||
ChatPacket chat = new ChatPacket();
|
connection.write(new ClientboundChatPacket(
|
||||||
chat.setMessage(object.toString());
|
object.toString(),
|
||||||
chat.setType(ChatPacket.GAME_INFO_TYPE);
|
ClientboundChatPacket.GAME_INFO_TYPE,
|
||||||
connection.write(chat);
|
Identity.nil().uuid()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,36 +269,32 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
GsonComponentSerializer serializer = ProtocolUtils.getJsonChatSerializer(this
|
GsonComponentSerializer serializer = ProtocolUtils.getJsonChatSerializer(this
|
||||||
.getProtocolVersion());
|
.getProtocolVersion());
|
||||||
|
|
||||||
TitlePacket titlePkt = new TitlePacket();
|
connection.delayedWrite(new ClientboundTitlePacket(
|
||||||
titlePkt.setAction(TitlePacket.SET_TITLE);
|
ClientboundTitlePacket.SET_TITLE,
|
||||||
titlePkt.setComponent(serializer.serialize(title.title()));
|
serializer.serialize(title.title())
|
||||||
connection.delayedWrite(titlePkt);
|
));
|
||||||
|
|
||||||
TitlePacket subtitlePkt = new TitlePacket();
|
connection.delayedWrite(new ClientboundTitlePacket(
|
||||||
subtitlePkt.setAction(TitlePacket.SET_SUBTITLE);
|
ClientboundTitlePacket.SET_SUBTITLE,
|
||||||
subtitlePkt.setComponent(serializer.serialize(title.subtitle()));
|
serializer.serialize(title.subtitle())
|
||||||
connection.delayedWrite(subtitlePkt);
|
));
|
||||||
|
|
||||||
TitlePacket timesPkt = TitlePacket.timesForProtocolVersion(this.getProtocolVersion());
|
|
||||||
net.kyori.adventure.title.Title.Times times = title.times();
|
net.kyori.adventure.title.Title.Times times = title.times();
|
||||||
if (times != null) {
|
if (times != null) {
|
||||||
timesPkt.setFadeIn((int) DurationUtils.toTicks(times.fadeIn()));
|
connection.delayedWrite(ClientboundTitlePacket.times(this.getProtocolVersion(), times));
|
||||||
timesPkt.setStay((int) DurationUtils.toTicks(times.stay()));
|
|
||||||
timesPkt.setFadeOut((int) DurationUtils.toTicks(times.fadeOut()));
|
|
||||||
}
|
}
|
||||||
connection.delayedWrite(timesPkt);
|
|
||||||
|
|
||||||
connection.flush();
|
connection.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearTitle() {
|
public void clearTitle() {
|
||||||
connection.write(TitlePacket.hideForProtocolVersion(this.getProtocolVersion()));
|
connection.write(ClientboundTitlePacket.hide(this.getProtocolVersion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetTitle() {
|
public void resetTitle() {
|
||||||
connection.write(TitlePacket.resetForProtocolVersion(this.getProtocolVersion()));
|
connection.write(ClientboundTitlePacket.reset(this.getProtocolVersion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -343,7 +339,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
public void disconnect0(Component reason, boolean duringLogin) {
|
public void disconnect0(Component reason, boolean duringLogin) {
|
||||||
logger.info("{} has disconnected: {}", this,
|
logger.info("{} has disconnected: {}", this,
|
||||||
LegacyComponentSerializer.legacySection().serialize(reason));
|
LegacyComponentSerializer.legacySection().serialize(reason));
|
||||||
connection.closeWith(DisconnectPacket.create(reason, this.getProtocolVersion()));
|
connection.closeWith(ClientboundDisconnectPacket.create(reason, this.getProtocolVersion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable VelocityServerConnection getConnectedServer() {
|
public @Nullable VelocityServerConnection getConnectedServer() {
|
||||||
@@ -402,7 +398,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
* @param disconnect the disconnect packet
|
* @param disconnect the disconnect packet
|
||||||
* @param safe whether or not we can safely reconnect to a new server
|
* @param safe whether or not we can safely reconnect to a new server
|
||||||
*/
|
*/
|
||||||
public void handleConnectionException(RegisteredServer server, DisconnectPacket disconnect,
|
public void handleConnectionException(RegisteredServer server, ClientboundDisconnectPacket disconnect,
|
||||||
boolean safe) {
|
boolean safe) {
|
||||||
if (!isActive()) {
|
if (!isActive()) {
|
||||||
// If the connection is no longer active, it makes no sense to try and recover it.
|
// If the connection is no longer active, it makes no sense to try and recover it.
|
||||||
@@ -507,7 +503,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
case SERVER_DISCONNECTED:
|
case SERVER_DISCONNECTED:
|
||||||
Component reason = status.getReason()
|
Component reason = status.getReason()
|
||||||
.orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
|
.orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
|
||||||
handleConnectionException(res.getServer(), DisconnectPacket.create(reason,
|
handleConnectionException(res.getServer(), ClientboundDisconnectPacket.create(reason,
|
||||||
getProtocolVersion()), ((Impl) status).isSafe());
|
getProtocolVersion()), ((Impl) status).isSafe());
|
||||||
break;
|
break;
|
||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
@@ -664,7 +660,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
public boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data) {
|
public boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data) {
|
||||||
Preconditions.checkNotNull(identifier, "identifier");
|
Preconditions.checkNotNull(identifier, "identifier");
|
||||||
Preconditions.checkNotNull(data, "data");
|
Preconditions.checkNotNull(data, "data");
|
||||||
PluginMessagePacket message = new PluginMessagePacket(identifier.getId(),
|
ClientboundPluginMessagePacket message = new ClientboundPluginMessagePacket(identifier.getId(),
|
||||||
Unpooled.wrappedBuffer(data));
|
Unpooled.wrappedBuffer(data));
|
||||||
connection.write(message);
|
connection.write(message);
|
||||||
return true;
|
return true;
|
||||||
@@ -672,20 +668,17 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spoofChatInput(String input) {
|
public void spoofChatInput(String input) {
|
||||||
Preconditions.checkArgument(input.length() <= ChatPacket.MAX_SERVERBOUND_MESSAGE_LENGTH,
|
Preconditions.checkArgument(input.length() <= ServerboundChatPacket.MAX_MESSAGE_LENGTH,
|
||||||
"input cannot be greater than " + ChatPacket.MAX_SERVERBOUND_MESSAGE_LENGTH
|
"input cannot be greater than " + ServerboundChatPacket.MAX_MESSAGE_LENGTH
|
||||||
+ " characters in length");
|
+ " characters in length");
|
||||||
ensureBackendConnection().write(ChatPacket.createServerbound(input));
|
ensureBackendConnection().write(new ServerboundChatPacket(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResourcePack(String url) {
|
public void sendResourcePack(String url) {
|
||||||
Preconditions.checkNotNull(url, "url");
|
Preconditions.checkNotNull(url, "url");
|
||||||
|
|
||||||
ResourcePackRequestPacket request = new ResourcePackRequestPacket();
|
connection.write(new ClientboundResourcePackRequestPacket(url, ""));
|
||||||
request.setUrl(url);
|
|
||||||
request.setHash("");
|
|
||||||
connection.write(request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -694,22 +687,17 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
Preconditions.checkNotNull(hash, "hash");
|
Preconditions.checkNotNull(hash, "hash");
|
||||||
Preconditions.checkArgument(hash.length == 20, "Hash length is not 20");
|
Preconditions.checkArgument(hash.length == 20, "Hash length is not 20");
|
||||||
|
|
||||||
ResourcePackRequestPacket request = new ResourcePackRequestPacket();
|
connection.write(new ClientboundResourcePackRequestPacket(url, ByteBufUtil.hexDump(hash)));
|
||||||
request.setUrl(url);
|
|
||||||
request.setHash(ByteBufUtil.hexDump(hash));
|
|
||||||
connection.write(request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a {@link KeepAlivePacket} packet to the player with a random ID.
|
* Sends a {@link ClientboundKeepAlivePacket} packet to the player with a random ID.
|
||||||
* The response will be ignored by Velocity as it will not match the
|
* The response will be ignored by Velocity as it will not match the
|
||||||
* ID last sent by the server.
|
* ID last sent by the server.
|
||||||
*/
|
*/
|
||||||
public void sendKeepAlive() {
|
public void sendKeepAlive() {
|
||||||
if (connection.getState() == StateRegistry.PLAY) {
|
if (connection.getState() == StateRegistry.PLAY) {
|
||||||
KeepAlivePacket keepAlive = new KeepAlivePacket();
|
connection.write(new ClientboundKeepAlivePacket(ThreadLocalRandom.current().nextLong()));
|
||||||
keepAlive.setRandomId(ThreadLocalRandom.current().nextLong());
|
|
||||||
connection.write(keepAlive);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,11 +735,11 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
* @param message the plugin message to forward to the client
|
* @param message the plugin message to forward to the client
|
||||||
* @return {@code true} if the message can be forwarded, {@code false} otherwise
|
* @return {@code true} if the message can be forwarded, {@code false} otherwise
|
||||||
*/
|
*/
|
||||||
public boolean canForwardPluginMessage(ProtocolVersion version, PluginMessagePacket message) {
|
public boolean canForwardPluginMessage(ProtocolVersion version, AbstractPluginMessagePacket<?> message) {
|
||||||
boolean minecraftOrFmlMessage;
|
boolean minecraftOrFmlMessage;
|
||||||
|
|
||||||
// By default, all internal Minecraft and Forge channels are forwarded from the server.
|
// By default, all internal Minecraft and Forge channels are forwarded from the server.
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_12_2) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_12_2)) {
|
||||||
String channel = message.getChannel();
|
String channel = message.getChannel();
|
||||||
minecraftOrFmlMessage = channel.startsWith("MC|")
|
minecraftOrFmlMessage = channel.startsWith("MC|")
|
||||||
|| channel.startsWith(LegacyForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)
|
|| channel.startsWith(LegacyForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)
|
||||||
@@ -880,7 +868,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
case SERVER_DISCONNECTED:
|
case SERVER_DISCONNECTED:
|
||||||
Component reason = status.getReason()
|
Component reason = status.getReason()
|
||||||
.orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
|
.orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
|
||||||
handleConnectionException(toConnect, DisconnectPacket.create(reason,
|
handleConnectionException(toConnect, ClientboundDisconnectPacket.create(reason,
|
||||||
getProtocolVersion()), status.isSafe());
|
getProtocolVersion()), status.isSafe());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ import com.velocitypowered.proxy.connection.ConnectionTypes;
|
|||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants;
|
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyDisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyDisconnectPacket;
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyHandshakePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyHandshakePacket;
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyPingPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyPingPacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundHandshakePacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
@@ -58,7 +58,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(HandshakePacket handshake) {
|
public boolean handle(ServerboundHandshakePacket handshake) {
|
||||||
InitialInboundConnection ic = new InitialInboundConnection(connection,
|
InitialInboundConnection ic = new InitialInboundConnection(connection,
|
||||||
cleanVhost(handshake.getServerAddress()), handshake);
|
cleanVhost(handshake.getServerAddress()), handshake);
|
||||||
StateRegistry nextState = getStateForProtocol(handshake.getNextStatus());
|
StateRegistry nextState = getStateForProtocol(handshake.getNextStatus());
|
||||||
@@ -97,7 +97,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleLogin(HandshakePacket handshake, InitialInboundConnection ic) {
|
private void handleLogin(ServerboundHandshakePacket handshake, InitialInboundConnection ic) {
|
||||||
if (!ProtocolVersion.isSupported(handshake.getProtocolVersion())) {
|
if (!ProtocolVersion.isSupported(handshake.getProtocolVersion())) {
|
||||||
ic.disconnectQuietly(Component.translatable("multiplayer.disconnect.outdated_client"));
|
ic.disconnectQuietly(Component.translatable("multiplayer.disconnect.outdated_client"));
|
||||||
return;
|
return;
|
||||||
@@ -114,7 +114,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
// If the proxy is configured for modern forwarding, we must deny connections from 1.12.2
|
// If the proxy is configured for modern forwarding, we must deny connections from 1.12.2
|
||||||
// and lower, otherwise IP information will never get forwarded.
|
// and lower, otherwise IP information will never get forwarded.
|
||||||
if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN
|
if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN
|
||||||
&& handshake.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_13) < 0) {
|
&& handshake.getProtocolVersion().lt(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
ic.disconnectQuietly(Component.text("This server is only compatible with 1.13 and above."));
|
ic.disconnectQuietly(Component.text("This server is only compatible with 1.13 and above."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -123,12 +123,12 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
connection.setSessionHandler(new LoginSessionHandler(server, connection, ic));
|
connection.setSessionHandler(new LoginSessionHandler(server, connection, ic));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConnectionType getHandshakeConnectionType(HandshakePacket handshake) {
|
private ConnectionType getHandshakeConnectionType(ServerboundHandshakePacket handshake) {
|
||||||
// Determine if we're using Forge (1.8 to 1.12, may not be the case in 1.13).
|
// Determine if we're using Forge (1.8 to 1.12, may not be the case in 1.13).
|
||||||
if (handshake.getServerAddress().endsWith(LegacyForgeConstants.HANDSHAKE_HOSTNAME_TOKEN)
|
if (handshake.getServerAddress().endsWith(LegacyForgeConstants.HANDSHAKE_HOSTNAME_TOKEN)
|
||||||
&& handshake.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_13) < 0) {
|
&& handshake.getProtocolVersion().lt(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
return ConnectionTypes.LEGACY_FORGE;
|
return ConnectionTypes.LEGACY_FORGE;
|
||||||
} else if (handshake.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_7_6) <= 0) {
|
} else if (handshake.getProtocolVersion().lte(ProtocolVersion.MINECRAFT_1_7_6)) {
|
||||||
// 1.7 Forge will not notify us during handshake. UNDETERMINED will listen for incoming
|
// 1.7 Forge will not notify us during handshake. UNDETERMINED will listen for incoming
|
||||||
// forge handshake attempts. Also sends a reset handshake packet on every transition.
|
// forge handshake attempts. Also sends a reset handshake packet on every transition.
|
||||||
return ConnectionTypes.UNDETERMINED_17;
|
return ConnectionTypes.UNDETERMINED_17;
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package com.velocitypowered.proxy.connection.client;
|
|||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.connection.backend.BungeeCordMessageResponder;
|
import com.velocitypowered.proxy.connection.backend.BungeeCordMessageResponder;
|
||||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
||||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundPluginMessagePacket;
|
||||||
|
|
||||||
public class InitialConnectSessionHandler implements MinecraftSessionHandler {
|
public class InitialConnectSessionHandler implements MinecraftSessionHandler {
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ public class InitialConnectSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(PluginMessagePacket packet) {
|
public boolean handle(ServerboundPluginMessagePacket packet) {
|
||||||
VelocityServerConnection serverConn = player.getConnectionInFlight();
|
VelocityServerConnection serverConn = player.getConnectionInFlight();
|
||||||
if (serverConn != null) {
|
if (serverConn != null) {
|
||||||
if (player.getPhase().handle(player, packet, serverConn)) {
|
if (player.getPhase().handle(player, packet, serverConn)) {
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import com.velocitypowered.api.network.ProtocolVersion;
|
|||||||
import com.velocitypowered.api.proxy.connection.InboundConnection;
|
import com.velocitypowered.api.proxy.connection.InboundConnection;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
|
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundHandshakePacket;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
@@ -20,10 +20,10 @@ public final class InitialInboundConnection implements InboundConnection,
|
|||||||
|
|
||||||
private final MinecraftConnection connection;
|
private final MinecraftConnection connection;
|
||||||
private final String cleanedAddress;
|
private final String cleanedAddress;
|
||||||
private final HandshakePacket handshake;
|
private final ServerboundHandshakePacket handshake;
|
||||||
|
|
||||||
InitialInboundConnection(MinecraftConnection connection, String cleanedAddress,
|
InitialInboundConnection(MinecraftConnection connection, String cleanedAddress,
|
||||||
HandshakePacket handshake) {
|
ServerboundHandshakePacket handshake) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.cleanedAddress = cleanedAddress;
|
this.cleanedAddress = cleanedAddress;
|
||||||
this.handshake = handshake;
|
this.handshake = handshake;
|
||||||
@@ -61,7 +61,7 @@ public final class InitialInboundConnection implements InboundConnection,
|
|||||||
public void disconnect(Component reason) {
|
public void disconnect(Component reason) {
|
||||||
logger.info("{} has disconnected: {}", this,
|
logger.info("{} has disconnected: {}", this,
|
||||||
LegacyComponentSerializer.legacySection().serialize(reason));
|
LegacyComponentSerializer.legacySection().serialize(reason));
|
||||||
connection.closeWith(DisconnectPacket.create(reason, getProtocolVersion()));
|
connection.closeWith(ClientboundDisconnectPacket.create(reason, getProtocolVersion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,6 +69,6 @@ public final class InitialInboundConnection implements InboundConnection,
|
|||||||
* @param reason the reason for disconnecting
|
* @param reason the reason for disconnecting
|
||||||
*/
|
*/
|
||||||
public void disconnectQuietly(Component reason) {
|
public void disconnectQuietly(Component reason) {
|
||||||
connection.closeWith(DisconnectPacket.create(reason, getProtocolVersion()));
|
connection.closeWith(ClientboundDisconnectPacket.create(reason, getProtocolVersion()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ import com.velocitypowered.proxy.config.PlayerInfoForwarding;
|
|||||||
import com.velocitypowered.proxy.config.VelocityConfiguration;
|
import com.velocitypowered.proxy.config.VelocityConfiguration;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.network.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundEncryptionRequestPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionResponsePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundServerLoginSuccessPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundSetCompressionPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundEncryptionResponsePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundServerLoginPacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
@@ -58,7 +58,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
private final VelocityServer server;
|
private final VelocityServer server;
|
||||||
private final MinecraftConnection mcConnection;
|
private final MinecraftConnection mcConnection;
|
||||||
private final InitialInboundConnection inbound;
|
private final InitialInboundConnection inbound;
|
||||||
private @MonotonicNonNull ServerLoginPacket login;
|
private @MonotonicNonNull ServerboundServerLoginPacket login;
|
||||||
private byte[] verify = EMPTY_BYTE_ARRAY;
|
private byte[] verify = EMPTY_BYTE_ARRAY;
|
||||||
private @MonotonicNonNull ConnectedPlayer connectedPlayer;
|
private @MonotonicNonNull ConnectedPlayer connectedPlayer;
|
||||||
|
|
||||||
@@ -70,15 +70,15 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(ServerLoginPacket packet) {
|
public boolean handle(ServerboundServerLoginPacket packet) {
|
||||||
this.login = packet;
|
this.login = packet;
|
||||||
beginPreLogin();
|
beginPreLogin();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(EncryptionResponsePacket packet) {
|
public boolean handle(ServerboundEncryptionResponsePacket packet) {
|
||||||
ServerLoginPacket login = this.login;
|
ServerboundServerLoginPacket login = this.login;
|
||||||
if (login == null) {
|
if (login == null) {
|
||||||
throw new IllegalStateException("No ServerLogin packet received yet.");
|
throw new IllegalStateException("No ServerLogin packet received yet.");
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void beginPreLogin() {
|
private void beginPreLogin() {
|
||||||
ServerLoginPacket login = this.login;
|
ServerboundServerLoginPacket login = this.login;
|
||||||
if (login == null) {
|
if (login == null) {
|
||||||
throw new IllegalStateException("No ServerLogin packet received yet.");
|
throw new IllegalStateException("No ServerLogin packet received yet.");
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
Optional<Component> disconnectReason = result.getReason();
|
Optional<Component> disconnectReason = result.getReason();
|
||||||
if (disconnectReason.isPresent()) {
|
if (disconnectReason.isPresent()) {
|
||||||
// The component is guaranteed to be provided if the connection was denied.
|
// The component is guaranteed to be provided if the connection was denied.
|
||||||
mcConnection.closeWith(DisconnectPacket.create(disconnectReason.get(),
|
mcConnection.closeWith(ClientboundDisconnectPacket.create(disconnectReason.get(),
|
||||||
inbound.getProtocolVersion()));
|
inbound.getProtocolVersion()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
if (!result.isForceOfflineMode() && (server.getConfiguration().isOnlineMode() || result
|
if (!result.isForceOfflineMode() && (server.getConfiguration().isOnlineMode() || result
|
||||||
.isOnlineModeAllowed())) {
|
.isOnlineModeAllowed())) {
|
||||||
// Request encryption.
|
// Request encryption.
|
||||||
EncryptionRequestPacket request = generateEncryptionRequest();
|
ClientboundEncryptionRequestPacket request = generateEncryptionRequest();
|
||||||
this.verify = Arrays.copyOf(request.getVerifyToken(), 4);
|
this.verify = Arrays.copyOf(request.getVerifyToken(), 4);
|
||||||
mcConnection.write(request);
|
mcConnection.write(request);
|
||||||
} else {
|
} else {
|
||||||
@@ -190,11 +190,11 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private EncryptionRequestPacket generateEncryptionRequest() {
|
private ClientboundEncryptionRequestPacket generateEncryptionRequest() {
|
||||||
byte[] verify = new byte[4];
|
byte[] verify = new byte[4];
|
||||||
ThreadLocalRandom.current().nextBytes(verify);
|
ThreadLocalRandom.current().nextBytes(verify);
|
||||||
|
|
||||||
EncryptionRequestPacket request = new EncryptionRequestPacket();
|
ClientboundEncryptionRequestPacket request = new ClientboundEncryptionRequestPacket();
|
||||||
request.setPublicKey(server.getServerKeyPair().getPublic().getEncoded());
|
request.setPublicKey(server.getServerKeyPair().getPublic().getEncoded());
|
||||||
request.setVerifyToken(verify);
|
request.setVerifyToken(verify);
|
||||||
return request;
|
return request;
|
||||||
@@ -242,8 +242,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
private void completeLoginProtocolPhaseAndInitialize(ConnectedPlayer player) {
|
private void completeLoginProtocolPhaseAndInitialize(ConnectedPlayer player) {
|
||||||
int threshold = server.getConfiguration().getCompressionThreshold();
|
int threshold = server.getConfiguration().getCompressionThreshold();
|
||||||
if (threshold >= 0 && mcConnection.getProtocolVersion().compareTo(MINECRAFT_1_8) >= 0) {
|
if (threshold >= 0 && mcConnection.getProtocolVersion().gte(MINECRAFT_1_8)) {
|
||||||
mcConnection.write(new SetCompressionPacket(threshold));
|
mcConnection.write(new ClientboundSetCompressionPacket(threshold));
|
||||||
mcConnection.setCompressionThreshold(threshold);
|
mcConnection.setCompressionThreshold(threshold);
|
||||||
}
|
}
|
||||||
VelocityConfiguration configuration = server.getConfiguration();
|
VelocityConfiguration configuration = server.getConfiguration();
|
||||||
@@ -251,10 +251,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.NONE) {
|
if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.NONE) {
|
||||||
playerUniqueId = UuidUtils.generateOfflinePlayerUuid(player.getUsername());
|
playerUniqueId = UuidUtils.generateOfflinePlayerUuid(player.getUsername());
|
||||||
}
|
}
|
||||||
ServerLoginSuccessPacket success = new ServerLoginSuccessPacket();
|
mcConnection.write(new ClientboundServerLoginSuccessPacket(playerUniqueId, player.getUsername()));
|
||||||
success.setUsername(player.getUsername());
|
|
||||||
success.setUuid(playerUniqueId);
|
|
||||||
mcConnection.write(success);
|
|
||||||
|
|
||||||
mcConnection.setAssociation(player);
|
mcConnection.setAssociation(player);
|
||||||
mcConnection.setState(StateRegistry.PLAY);
|
mcConnection.setState(StateRegistry.PLAY);
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ import com.velocitypowered.proxy.config.PingPassthroughMode;
|
|||||||
import com.velocitypowered.proxy.config.VelocityConfiguration;
|
import com.velocitypowered.proxy.config.VelocityConfiguration;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundStatusResponsePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusRequestPacket;
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyDisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusResponsePacket;
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyPingPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyDisconnectPacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundStatusPingPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyPingPacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundStatusRequestPacket;
|
||||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||||
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
@@ -176,13 +176,13 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(StatusPingPacket packet) {
|
public boolean handle(ServerboundStatusPingPacket packet) {
|
||||||
connection.closeWith(packet);
|
connection.closeWith(packet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(StatusRequestPacket packet) {
|
public boolean handle(ServerboundStatusRequestPacket packet) {
|
||||||
if (this.pingReceived) {
|
if (this.pingReceived) {
|
||||||
throw EXPECTED_AWAITING_REQUEST;
|
throw EXPECTED_AWAITING_REQUEST;
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
|
|||||||
StringBuilder json = new StringBuilder();
|
StringBuilder json = new StringBuilder();
|
||||||
VelocityServer.getPingGsonInstance(connection.getProtocolVersion())
|
VelocityServer.getPingGsonInstance(connection.getProtocolVersion())
|
||||||
.toJson(event.getPing(), json);
|
.toJson(event.getPing(), json);
|
||||||
connection.write(new StatusResponsePacket(json));
|
connection.write(new ClientboundStatusResponsePacket(json));
|
||||||
},
|
},
|
||||||
connection.eventLoop())
|
connection.eventLoop())
|
||||||
.exceptionally((ex) -> {
|
.exceptionally((ex) -> {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase;
|
|||||||
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases;
|
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases;
|
||||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,7 +107,7 @@ public enum LegacyForgeHandshakeBackendPhase implements BackendConnectionPhase {
|
|||||||
@Override
|
@Override
|
||||||
public final boolean handle(VelocityServerConnection serverConnection,
|
public final boolean handle(VelocityServerConnection serverConnection,
|
||||||
ConnectedPlayer player,
|
ConnectedPlayer player,
|
||||||
PluginMessagePacket message) {
|
AbstractPluginMessagePacket<?> message) {
|
||||||
if (message.getChannel().equals(LegacyForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)) {
|
if (message.getChannel().equals(LegacyForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)) {
|
||||||
// Get the phase and check if we need to start the next phase.
|
// Get the phase and check if we need to start the next phase.
|
||||||
LegacyForgeHandshakeBackendPhase newPhase = getNewPhase(serverConnection, message);
|
LegacyForgeHandshakeBackendPhase newPhase = getNewPhase(serverConnection, message);
|
||||||
@@ -162,7 +162,7 @@ public enum LegacyForgeHandshakeBackendPhase implements BackendConnectionPhase {
|
|||||||
* @return The phase to transition to, which may be the same as before.
|
* @return The phase to transition to, which may be the same as before.
|
||||||
*/
|
*/
|
||||||
private LegacyForgeHandshakeBackendPhase getNewPhase(VelocityServerConnection serverConnection,
|
private LegacyForgeHandshakeBackendPhase getNewPhase(VelocityServerConnection serverConnection,
|
||||||
PluginMessagePacket packet) {
|
AbstractPluginMessagePacket<?> packet) {
|
||||||
if (packetToAdvanceOn != null
|
if (packetToAdvanceOn != null
|
||||||
&& LegacyForgeUtil.getHandshakePacketDiscriminator(packet) == packetToAdvanceOn) {
|
&& LegacyForgeUtil.getHandshakePacketDiscriminator(packet) == packetToAdvanceOn) {
|
||||||
LegacyForgeHandshakeBackendPhase phaseToTransitionTo = nextPhase();
|
LegacyForgeHandshakeBackendPhase phaseToTransitionTo = nextPhase();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
|||||||
import com.velocitypowered.proxy.connection.client.ClientConnectionPhase;
|
import com.velocitypowered.proxy.connection.client.ClientConnectionPhase;
|
||||||
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean onHandle(ConnectedPlayer player,
|
boolean onHandle(ConnectedPlayer player,
|
||||||
PluginMessagePacket message,
|
AbstractPluginMessagePacket<?> message,
|
||||||
MinecraftConnection backendConn) {
|
MinecraftConnection backendConn) {
|
||||||
// If we stay in this phase, we do nothing because it means the packet wasn't handled.
|
// If we stay in this phase, we do nothing because it means the packet wasn't handled.
|
||||||
// Returning false indicates this
|
// Returning false indicates this
|
||||||
@@ -73,7 +73,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean onHandle(ConnectedPlayer player,
|
boolean onHandle(ConnectedPlayer player,
|
||||||
PluginMessagePacket message,
|
AbstractPluginMessagePacket<?> message,
|
||||||
MinecraftConnection backendConn) {
|
MinecraftConnection backendConn) {
|
||||||
// Read the mod list if we haven't already.
|
// Read the mod list if we haven't already.
|
||||||
if (!player.getModInfo().isPresent()) {
|
if (!player.getModInfo().isPresent()) {
|
||||||
@@ -147,7 +147,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean onHandle(ConnectedPlayer player,
|
boolean onHandle(ConnectedPlayer player,
|
||||||
PluginMessagePacket message,
|
AbstractPluginMessagePacket<?> message,
|
||||||
MinecraftConnection backendConn) {
|
MinecraftConnection backendConn) {
|
||||||
super.onHandle(player, message, backendConn);
|
super.onHandle(player, message, backendConn);
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean handle(ConnectedPlayer player,
|
public final boolean handle(ConnectedPlayer player,
|
||||||
PluginMessagePacket message,
|
AbstractPluginMessagePacket<?> message,
|
||||||
VelocityServerConnection server) {
|
VelocityServerConnection server) {
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
MinecraftConnection backendConn = server.getConnection();
|
MinecraftConnection backendConn = server.getConnection();
|
||||||
@@ -211,7 +211,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
|||||||
* @return true if handled, false otherwise.
|
* @return true if handled, false otherwise.
|
||||||
*/
|
*/
|
||||||
boolean onHandle(ConnectedPlayer player,
|
boolean onHandle(ConnectedPlayer player,
|
||||||
PluginMessagePacket message,
|
AbstractPluginMessagePacket<?> message,
|
||||||
MinecraftConnection backendConn) {
|
MinecraftConnection backendConn) {
|
||||||
// Send the packet on to the server.
|
// Send the packet on to the server.
|
||||||
backendConn.write(message.retain());
|
backendConn.write(message.retain());
|
||||||
@@ -241,7 +241,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
|||||||
* @param packet The packet
|
* @param packet The packet
|
||||||
* @return The phase to transition to, which may be the same as before.
|
* @return The phase to transition to, which may be the same as before.
|
||||||
*/
|
*/
|
||||||
private LegacyForgeHandshakeClientPhase getNewPhase(PluginMessagePacket packet) {
|
private LegacyForgeHandshakeClientPhase getNewPhase(AbstractPluginMessagePacket<?> packet) {
|
||||||
if (packetToAdvanceOn != null
|
if (packetToAdvanceOn != null
|
||||||
&& LegacyForgeUtil.getHandshakePacketDiscriminator(packet) == packetToAdvanceOn) {
|
&& LegacyForgeUtil.getHandshakePacketDiscriminator(packet) == packetToAdvanceOn) {
|
||||||
return nextPhase();
|
return nextPhase();
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ import static com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConst
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.velocitypowered.api.util.ModInfo;
|
import com.velocitypowered.api.util.ModInfo;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -25,7 +26,7 @@ class LegacyForgeUtil {
|
|||||||
* @param message The message to analyse
|
* @param message The message to analyse
|
||||||
* @return The discriminator
|
* @return The discriminator
|
||||||
*/
|
*/
|
||||||
static byte getHandshakePacketDiscriminator(PluginMessagePacket message) {
|
static byte getHandshakePacketDiscriminator(AbstractPluginMessagePacket<?> message) {
|
||||||
Preconditions.checkArgument(message.getChannel().equals(FORGE_LEGACY_HANDSHAKE_CHANNEL));
|
Preconditions.checkArgument(message.getChannel().equals(FORGE_LEGACY_HANDSHAKE_CHANNEL));
|
||||||
Preconditions.checkArgument(message.content().isReadable());
|
Preconditions.checkArgument(message.content().isReadable());
|
||||||
return message.content().getByte(0);
|
return message.content().getByte(0);
|
||||||
@@ -37,7 +38,7 @@ class LegacyForgeUtil {
|
|||||||
* @param message The message
|
* @param message The message
|
||||||
* @return The list of mods. May be empty.
|
* @return The list of mods. May be empty.
|
||||||
*/
|
*/
|
||||||
static List<ModInfo.Mod> readModList(PluginMessagePacket message) {
|
static List<ModInfo.Mod> readModList(AbstractPluginMessagePacket<?> message) {
|
||||||
Preconditions.checkNotNull(message, "message");
|
Preconditions.checkNotNull(message, "message");
|
||||||
Preconditions.checkArgument(message.getChannel().equals(FORGE_LEGACY_HANDSHAKE_CHANNEL),
|
Preconditions.checkArgument(message.getChannel().equals(FORGE_LEGACY_HANDSHAKE_CHANNEL),
|
||||||
"message is not a FML HS plugin message");
|
"message is not a FML HS plugin message");
|
||||||
@@ -65,10 +66,10 @@ class LegacyForgeUtil {
|
|||||||
*
|
*
|
||||||
* @return A copy of the reset packet
|
* @return A copy of the reset packet
|
||||||
*/
|
*/
|
||||||
static PluginMessagePacket resetPacket() {
|
static AbstractPluginMessagePacket<?> resetPacket() {
|
||||||
PluginMessagePacket msg = new PluginMessagePacket();
|
return new ClientboundPluginMessagePacket(
|
||||||
msg.setChannel(FORGE_LEGACY_HANDSHAKE_CHANNEL);
|
FORGE_LEGACY_HANDSHAKE_CHANNEL,
|
||||||
msg.replace(Unpooled.wrappedBuffer(FORGE_LEGACY_HANDSHAKE_RESET_DATA.clone()));
|
Unpooled.wrappedBuffer(FORGE_LEGACY_HANDSHAKE_RESET_DATA.clone())
|
||||||
return msg;
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ public final class DimensionData {
|
|||||||
String registryIdentifier = dimTag.getString("name");
|
String registryIdentifier = dimTag.getString("name");
|
||||||
CompoundBinaryTag details;
|
CompoundBinaryTag details;
|
||||||
Integer dimensionId = null;
|
Integer dimensionId = null;
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
dimensionId = dimTag.getInt("id");
|
dimensionId = dimTag.getInt("id");
|
||||||
details = dimTag.getCompound("element");
|
details = dimTag.getCompound("element");
|
||||||
} else {
|
} else {
|
||||||
@@ -243,7 +243,7 @@ public final class DimensionData {
|
|||||||
*/
|
*/
|
||||||
public CompoundBinaryTag encodeAsCompoundTag(ProtocolVersion version) {
|
public CompoundBinaryTag encodeAsCompoundTag(ProtocolVersion version) {
|
||||||
CompoundBinaryTag details = serializeDimensionDetails();
|
CompoundBinaryTag details = serializeDimensionDetails();
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
if (dimensionId == null) {
|
if (dimensionId == null) {
|
||||||
throw new IllegalStateException("Tried to serialize a 1.16.2+ dimension registry entry "
|
throw new IllegalStateException("Tried to serialize a 1.16.2+ dimension registry entry "
|
||||||
+ "without an ID");
|
+ "without an ID");
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.velocitypowered.proxy.connection.util;
|
|||||||
import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder;
|
import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder;
|
||||||
import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder.Status;
|
import com.velocitypowered.api.proxy.player.ConnectionRequestBuilder.Status;
|
||||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
@@ -41,12 +41,12 @@ public class ConnectionRequestResults {
|
|||||||
return new Impl(Status.SERVER_DISCONNECTED, component, server, true);
|
return new Impl(Status.SERVER_DISCONNECTED, component, server, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Impl forDisconnect(DisconnectPacket disconnect, RegisteredServer server) {
|
public static Impl forDisconnect(ClientboundDisconnectPacket disconnect, RegisteredServer server) {
|
||||||
Component deserialized = GsonComponentSerializer.gson().deserialize(disconnect.getReason());
|
Component deserialized = GsonComponentSerializer.gson().deserialize(disconnect.getReason());
|
||||||
return forDisconnect(deserialized, server);
|
return forDisconnect(deserialized, server);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Impl forUnsafeDisconnect(DisconnectPacket disconnect, RegisteredServer server) {
|
public static Impl forUnsafeDisconnect(ClientboundDisconnectPacket disconnect, RegisteredServer server) {
|
||||||
Component deserialized = GsonComponentSerializer.gson().deserialize(disconnect.getReason());
|
Component deserialized = GsonComponentSerializer.gson().deserialize(disconnect.getReason());
|
||||||
return new Impl(Status.SERVER_DISCONNECTED, deserialized, server, false);
|
return new Impl(Status.SERVER_DISCONNECTED, deserialized, server, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import static com.velocitypowered.proxy.network.Connections.MINECRAFT_ENCODER;
|
|||||||
import static com.velocitypowered.proxy.network.Connections.READ_TIMEOUT;
|
import static com.velocitypowered.proxy.network.Connections.READ_TIMEOUT;
|
||||||
|
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.netty.AutoReadHolderHandler;
|
import com.velocitypowered.proxy.network.pipeline.AutoReadHolderHandler;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftEncoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintFrameDecoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftVarintFrameDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintLengthEncoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftVarintLengthEncoder;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||||
@@ -37,9 +37,9 @@ public class BackendChannelInitializer extends ChannelInitializer<Channel> {
|
|||||||
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
|
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
|
||||||
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
|
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
|
||||||
.addLast(MINECRAFT_DECODER,
|
.addLast(MINECRAFT_DECODER,
|
||||||
new MinecraftDecoder(ProtocolDirection.CLIENTBOUND))
|
new MinecraftDecoder(PacketDirection.CLIENTBOUND))
|
||||||
.addLast(FLOW_HANDLER, new AutoReadHolderHandler())
|
.addLast(FLOW_HANDLER, new AutoReadHolderHandler())
|
||||||
.addLast(MINECRAFT_ENCODER,
|
.addLast(MINECRAFT_ENCODER,
|
||||||
new MinecraftEncoder(ProtocolDirection.SERVERBOUND));
|
new MinecraftEncoder(PacketDirection.SERVERBOUND));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,18 @@ import java.util.function.Supplier;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
public class BackendChannelInitializerHolder implements Supplier<ChannelInitializer<Channel>> {
|
public class ChannelInitializerHolder<C extends Channel> implements Supplier<ChannelInitializer<C>> {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(ChannelInitializerHolder.class);
|
||||||
|
private final String name;
|
||||||
|
private ChannelInitializer<C> initializer;
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(ConnectionManager.class);
|
ChannelInitializerHolder(final String name, final ChannelInitializer<C> initializer) {
|
||||||
private ChannelInitializer<Channel> initializer;
|
this.name = name;
|
||||||
|
|
||||||
BackendChannelInitializerHolder(final ChannelInitializer<Channel> initializer) {
|
|
||||||
this.initializer = initializer;
|
this.initializer = initializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelInitializer<Channel> get() {
|
public ChannelInitializer<C> get() {
|
||||||
return this.initializer;
|
return this.initializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,8 +28,8 @@ public class BackendChannelInitializerHolder implements Supplier<ChannelInitiali
|
|||||||
* @deprecated Internal implementation detail
|
* @deprecated Internal implementation detail
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void set(final ChannelInitializer<Channel> initializer) {
|
public void set(final ChannelInitializer<C> initializer) {
|
||||||
LOGGER.warn("The backend channel initializer has been replaced by {}",
|
LOGGER.warn("The {} initializer has been replaced by {}", this.name,
|
||||||
Thread.currentThread().getStackTrace()[2]);
|
Thread.currentThread().getStackTrace()[2]);
|
||||||
this.initializer = initializer;
|
this.initializer = initializer;
|
||||||
}
|
}
|
||||||
@@ -6,8 +6,8 @@ import static org.asynchttpclient.Dsl.config;
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.velocitypowered.natives.util.Natives;
|
import com.velocitypowered.natives.util.Natives;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.network.netty.SeparatePoolInetNameResolver;
|
import com.velocitypowered.proxy.network.pipeline.GS4QueryHandler;
|
||||||
import com.velocitypowered.proxy.protocol.netty.GS4QueryHandler;
|
import com.velocitypowered.proxy.network.resolver.SeparatePoolInetNameResolver;
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
@@ -43,9 +43,9 @@ public final class ConnectionManager {
|
|||||||
// These are intentionally made public for plugins like ViaVersion, which inject their own
|
// These are intentionally made public for plugins like ViaVersion, which inject their own
|
||||||
// protocol logic into the proxy.
|
// protocol logic into the proxy.
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public final ServerChannelInitializerHolder serverChannelInitializer;
|
public final ChannelInitializerHolder<Channel> serverChannelInitializer;
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public final BackendChannelInitializerHolder backendChannelInitializer;
|
public final ChannelInitializerHolder<Channel> backendChannelInitializer;
|
||||||
|
|
||||||
private final SeparatePoolInetNameResolver resolver;
|
private final SeparatePoolInetNameResolver resolver;
|
||||||
private final AsyncHttpClient httpClient;
|
private final AsyncHttpClient httpClient;
|
||||||
@@ -60,9 +60,9 @@ public final class ConnectionManager {
|
|||||||
this.transportType = TransportType.bestType();
|
this.transportType = TransportType.bestType();
|
||||||
this.bossGroup = this.transportType.createEventLoopGroup(TransportType.Type.BOSS);
|
this.bossGroup = this.transportType.createEventLoopGroup(TransportType.Type.BOSS);
|
||||||
this.workerGroup = this.transportType.createEventLoopGroup(TransportType.Type.WORKER);
|
this.workerGroup = this.transportType.createEventLoopGroup(TransportType.Type.WORKER);
|
||||||
this.serverChannelInitializer = new ServerChannelInitializerHolder(
|
this.serverChannelInitializer = new ChannelInitializerHolder<>("server channel",
|
||||||
new ServerChannelInitializer(this.server));
|
new ServerChannelInitializer(this.server));
|
||||||
this.backendChannelInitializer = new BackendChannelInitializerHolder(
|
this.backendChannelInitializer = new ChannelInitializerHolder<>("backend channel",
|
||||||
new BackendChannelInitializer(this.server));
|
new BackendChannelInitializer(this.server));
|
||||||
this.resolver = new SeparatePoolInetNameResolver(GlobalEventExecutor.INSTANCE);
|
this.resolver = new SeparatePoolInetNameResolver(GlobalEventExecutor.INSTANCE);
|
||||||
this.httpClient = asyncHttpClient(config()
|
this.httpClient = asyncHttpClient(config()
|
||||||
@@ -198,7 +198,7 @@ public final class ConnectionManager {
|
|||||||
return bossGroup;
|
return bossGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerChannelInitializerHolder getServerChannelInitializer() {
|
public ChannelInitializerHolder<Channel> getServerChannelInitializer() {
|
||||||
return this.serverChannelInitializer;
|
return this.serverChannelInitializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ public final class ConnectionManager {
|
|||||||
return httpClient;
|
return httpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BackendChannelInitializerHolder getBackendChannelInitializer() {
|
public ChannelInitializerHolder<Channel> getBackendChannelInitializer() {
|
||||||
return this.backendChannelInitializer;
|
return this.backendChannelInitializer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.velocitypowered.proxy.protocol.util;
|
package com.velocitypowered.proxy.network;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
|
||||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||||
import io.netty.handler.codec.CorruptedFrameException;
|
import io.netty.handler.codec.CorruptedFrameException;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.util;
|
package com.velocitypowered.proxy.network;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@@ -6,8 +6,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.util.ProxyVersion;
|
import com.velocitypowered.api.util.ProxyVersion;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@@ -34,7 +33,7 @@ public final class PluginMessageUtil {
|
|||||||
* @param message the plugin message
|
* @param message the plugin message
|
||||||
* @return whether or not this is a brand plugin message
|
* @return whether or not this is a brand plugin message
|
||||||
*/
|
*/
|
||||||
public static boolean isMcBrand(PluginMessagePacket message) {
|
public static boolean isMcBrand(AbstractPluginMessagePacket<?> message) {
|
||||||
checkNotNull(message, "message");
|
checkNotNull(message, "message");
|
||||||
return message.getChannel().equals(BRAND_CHANNEL_LEGACY) || message.getChannel()
|
return message.getChannel().equals(BRAND_CHANNEL_LEGACY) || message.getChannel()
|
||||||
.equals(BRAND_CHANNEL);
|
.equals(BRAND_CHANNEL);
|
||||||
@@ -45,7 +44,7 @@ public final class PluginMessageUtil {
|
|||||||
* @param message the plugin message
|
* @param message the plugin message
|
||||||
* @return whether we are registering plugin channels or not
|
* @return whether we are registering plugin channels or not
|
||||||
*/
|
*/
|
||||||
public static boolean isRegister(PluginMessagePacket message) {
|
public static boolean isRegister(AbstractPluginMessagePacket<?> message) {
|
||||||
checkNotNull(message, "message");
|
checkNotNull(message, "message");
|
||||||
return message.getChannel().equals(REGISTER_CHANNEL_LEGACY) || message.getChannel()
|
return message.getChannel().equals(REGISTER_CHANNEL_LEGACY) || message.getChannel()
|
||||||
.equals(REGISTER_CHANNEL);
|
.equals(REGISTER_CHANNEL);
|
||||||
@@ -56,7 +55,7 @@ public final class PluginMessageUtil {
|
|||||||
* @param message the plugin message
|
* @param message the plugin message
|
||||||
* @return whether we are unregistering plugin channels or not
|
* @return whether we are unregistering plugin channels or not
|
||||||
*/
|
*/
|
||||||
public static boolean isUnregister(PluginMessagePacket message) {
|
public static boolean isUnregister(AbstractPluginMessagePacket<?> message) {
|
||||||
checkNotNull(message, "message");
|
checkNotNull(message, "message");
|
||||||
return message.getChannel().equals(UNREGISTER_CHANNEL_LEGACY) || message.getChannel()
|
return message.getChannel().equals(UNREGISTER_CHANNEL_LEGACY) || message.getChannel()
|
||||||
.equals(UNREGISTER_CHANNEL);
|
.equals(UNREGISTER_CHANNEL);
|
||||||
@@ -67,7 +66,7 @@ public final class PluginMessageUtil {
|
|||||||
* @param message the plugin message
|
* @param message the plugin message
|
||||||
* @return whether this is a legacy register message
|
* @return whether this is a legacy register message
|
||||||
*/
|
*/
|
||||||
public static boolean isLegacyRegister(PluginMessagePacket message) {
|
public static boolean isLegacyRegister(AbstractPluginMessagePacket<?> message) {
|
||||||
checkNotNull(message, "message");
|
checkNotNull(message, "message");
|
||||||
return message.getChannel().equals(REGISTER_CHANNEL_LEGACY);
|
return message.getChannel().equals(REGISTER_CHANNEL_LEGACY);
|
||||||
}
|
}
|
||||||
@@ -78,7 +77,7 @@ public final class PluginMessageUtil {
|
|||||||
* @param message the plugin message
|
* @param message the plugin message
|
||||||
* @return whether this is a legacy unregister message
|
* @return whether this is a legacy unregister message
|
||||||
*/
|
*/
|
||||||
public static boolean isLegacyUnregister(PluginMessagePacket message) {
|
public static boolean isLegacyUnregister(AbstractPluginMessagePacket<?> message) {
|
||||||
checkNotNull(message, "message");
|
checkNotNull(message, "message");
|
||||||
return message.getChannel().equals(UNREGISTER_CHANNEL_LEGACY);
|
return message.getChannel().equals(UNREGISTER_CHANNEL_LEGACY);
|
||||||
}
|
}
|
||||||
@@ -88,7 +87,7 @@ public final class PluginMessageUtil {
|
|||||||
* @param message the message to get the channels from
|
* @param message the message to get the channels from
|
||||||
* @return the channels, as an immutable list
|
* @return the channels, as an immutable list
|
||||||
*/
|
*/
|
||||||
public static List<String> getChannels(PluginMessagePacket message) {
|
public static List<String> getChannels(AbstractPluginMessagePacket<?> message) {
|
||||||
checkNotNull(message, "message");
|
checkNotNull(message, "message");
|
||||||
checkArgument(isRegister(message) || isUnregister(message), "Unknown channel type %s",
|
checkArgument(isRegister(message) || isUnregister(message), "Unknown channel type %s",
|
||||||
message.getChannel());
|
message.getChannel());
|
||||||
@@ -107,15 +106,16 @@ public final class PluginMessageUtil {
|
|||||||
* @param channels the channels to register
|
* @param channels the channels to register
|
||||||
* @return the plugin message to send
|
* @return the plugin message to send
|
||||||
*/
|
*/
|
||||||
public static PluginMessagePacket constructChannelsPacket(ProtocolVersion protocolVersion,
|
public static AbstractPluginMessagePacket<?> constructChannelsPacket(ProtocolVersion protocolVersion,
|
||||||
Collection<String> channels) {
|
Collection<String> channels,
|
||||||
|
AbstractPluginMessagePacket.Factory<?> factory) {
|
||||||
checkNotNull(channels, "channels");
|
checkNotNull(channels, "channels");
|
||||||
checkArgument(!channels.isEmpty(), "no channels specified");
|
checkArgument(!channels.isEmpty(), "no channels specified");
|
||||||
String channelName = protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_13) >= 0
|
String channelName = protocolVersion.gte(ProtocolVersion.MINECRAFT_1_13)
|
||||||
? REGISTER_CHANNEL : REGISTER_CHANNEL_LEGACY;
|
? REGISTER_CHANNEL : REGISTER_CHANNEL_LEGACY;
|
||||||
ByteBuf contents = Unpooled.buffer();
|
ByteBuf contents = Unpooled.buffer();
|
||||||
contents.writeCharSequence(String.join("\0", channels), StandardCharsets.UTF_8);
|
contents.writeCharSequence(String.join("\0", channels), StandardCharsets.UTF_8);
|
||||||
return new PluginMessagePacket(channelName, contents);
|
return factory.create(channelName, contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,9 +124,10 @@ public final class PluginMessageUtil {
|
|||||||
* @param version the proxy version
|
* @param version the proxy version
|
||||||
* @return the rewritten plugin message
|
* @return the rewritten plugin message
|
||||||
*/
|
*/
|
||||||
public static PluginMessagePacket rewriteMinecraftBrand(PluginMessagePacket message,
|
public static AbstractPluginMessagePacket<?> rewriteMinecraftBrand(AbstractPluginMessagePacket<?> message,
|
||||||
ProxyVersion version,
|
ProxyVersion version,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion,
|
||||||
|
AbstractPluginMessagePacket.Factory<?> factory) {
|
||||||
checkNotNull(message, "message");
|
checkNotNull(message, "message");
|
||||||
checkNotNull(version, "version");
|
checkNotNull(version, "version");
|
||||||
checkArgument(isMcBrand(message), "message is not a brand plugin message");
|
checkArgument(isMcBrand(message), "message is not a brand plugin message");
|
||||||
@@ -135,13 +136,13 @@ public final class PluginMessageUtil {
|
|||||||
String rewrittenBrand = String.format("%s (%s)", currentBrand, version.getName());
|
String rewrittenBrand = String.format("%s (%s)", currentBrand, version.getName());
|
||||||
|
|
||||||
ByteBuf rewrittenBuf = Unpooled.buffer();
|
ByteBuf rewrittenBuf = Unpooled.buffer();
|
||||||
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (protocolVersion.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
ProtocolUtils.writeString(rewrittenBuf, rewrittenBrand);
|
ProtocolUtils.writeString(rewrittenBuf, rewrittenBrand);
|
||||||
} else {
|
} else {
|
||||||
rewrittenBuf.writeCharSequence(rewrittenBrand, StandardCharsets.UTF_8);
|
rewrittenBuf.writeCharSequence(rewrittenBrand, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PluginMessagePacket(message.getChannel(), rewrittenBuf);
|
return factory.create(message.getChannel(), rewrittenBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String readBrandMessage(ByteBuf content) {
|
private static String readBrandMessage(ByteBuf content) {
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.velocitypowered.proxy.protocol;
|
package com.velocitypowered.proxy.network;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.velocitypowered.proxy.protocol.util.NettyPreconditions.checkFrame;
|
import static com.velocitypowered.proxy.network.NettyPreconditions.checkFrame;
|
||||||
|
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.util.GameProfile;
|
import com.velocitypowered.api.util.GameProfile;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.util.VelocityLegacyHoverEventSerializer;
|
import com.velocitypowered.proxy.network.serialization.VelocityLegacyHoverEventSerializer;
|
||||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufInputStream;
|
import io.netty.buffer.ByteBufInputStream;
|
||||||
@@ -459,7 +459,7 @@ public enum ProtocolUtils {
|
|||||||
* @return the appropriate {@link GsonComponentSerializer}
|
* @return the appropriate {@link GsonComponentSerializer}
|
||||||
*/
|
*/
|
||||||
public static GsonComponentSerializer getJsonChatSerializer(ProtocolVersion version) {
|
public static GsonComponentSerializer getJsonChatSerializer(ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
return MODERN_SERIALIZER;
|
return MODERN_SERIALIZER;
|
||||||
}
|
}
|
||||||
return PRE_1_16_SERIALIZER;
|
return PRE_1_16_SERIALIZER;
|
||||||
@@ -11,13 +11,13 @@ import static com.velocitypowered.proxy.network.Connections.READ_TIMEOUT;
|
|||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
|
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.netty.LegacyPingDecoder;
|
import com.velocitypowered.proxy.network.pipeline.LegacyPingDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.LegacyPingEncoder;
|
import com.velocitypowered.proxy.network.pipeline.LegacyPingEncoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftEncoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintFrameDecoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftVarintFrameDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintLengthEncoder;
|
import com.velocitypowered.proxy.network.pipeline.MinecraftVarintLengthEncoder;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
|
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
|
||||||
@@ -43,8 +43,8 @@ public class ServerChannelInitializer extends ChannelInitializer<Channel> {
|
|||||||
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
|
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
|
||||||
.addLast(LEGACY_PING_ENCODER, LegacyPingEncoder.INSTANCE)
|
.addLast(LEGACY_PING_ENCODER, LegacyPingEncoder.INSTANCE)
|
||||||
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
|
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
|
||||||
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(ProtocolDirection.SERVERBOUND))
|
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(PacketDirection.SERVERBOUND))
|
||||||
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(ProtocolDirection.CLIENTBOUND));
|
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(PacketDirection.CLIENTBOUND));
|
||||||
|
|
||||||
final MinecraftConnection connection = new MinecraftConnection(ch, this.server);
|
final MinecraftConnection connection = new MinecraftConnection(ch, this.server);
|
||||||
connection.setSessionHandler(new HandshakeSessionHandler(connection, this.server));
|
connection.setSessionHandler(new HandshakeSessionHandler(connection, this.server));
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.velocitypowered.proxy.network;
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import io.netty.channel.ChannelInitializer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
public class ServerChannelInitializerHolder implements Supplier<ChannelInitializer<Channel>> {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(ConnectionManager.class);
|
|
||||||
private ChannelInitializer<Channel> initializer;
|
|
||||||
|
|
||||||
ServerChannelInitializerHolder(final ChannelInitializer<Channel> initializer) {
|
|
||||||
this.initializer = initializer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChannelInitializer<Channel> get() {
|
|
||||||
return this.initializer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the channel initializer.
|
|
||||||
* @param initializer the new initializer to use
|
|
||||||
* @deprecated Internal implementation detail
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void set(final ChannelInitializer<Channel> initializer) {
|
|
||||||
LOGGER.warn("The server channel initializer has been replaced by {}",
|
|
||||||
Thread.currentThread().getStackTrace()[2]);
|
|
||||||
this.initializer = initializer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol;
|
package com.velocitypowered.proxy.network;
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.getLast;
|
import static com.google.common.collect.Iterables.getLast;
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12;
|
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12;
|
||||||
@@ -16,33 +16,41 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINIMUM_VERSION;
|
|||||||
import static com.velocitypowered.api.network.ProtocolVersion.SUPPORTED_VERSIONS;
|
import static com.velocitypowered.api.network.ProtocolVersion.SUPPORTED_VERSIONS;
|
||||||
|
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ChatPacket;
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundAvailableCommandsPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundBossBarPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionResponsePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundEncryptionRequestPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.HeaderAndFooterPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundHeaderAndFooterPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundJoinGamePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundKeepAlivePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundLoginPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponsePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPlayerListItemPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PlayerListItemPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundResourcePackRequestPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequestPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundRespawnPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundServerLoginSuccessPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundSetCompressionPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundStatusPingPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundStatusResponsePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTabCompleteResponsePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTitlePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusRequestPacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusResponsePacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundClientSettingsPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundEncryptionResponsePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundHandshakePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TitlePacket;
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundKeepAlivePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundLoginPluginResponsePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundPluginMessagePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundResourcePackResponsePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundServerLoginPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundStatusPingPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundStatusRequestPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundTabCompleteRequestPacket;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.util.collection.IntObjectHashMap;
|
import io.netty.util.collection.IntObjectHashMap;
|
||||||
import io.netty.util.collection.IntObjectMap;
|
import io.netty.util.collection.IntObjectMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
@@ -52,133 +60,188 @@ import java.util.EnumMap;
|
|||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public enum StateRegistry {
|
public enum StateRegistry {
|
||||||
|
|
||||||
HANDSHAKE {
|
HANDSHAKE(true) {
|
||||||
{
|
{
|
||||||
serverbound.register(HandshakePacket.class, HandshakePacket::new,
|
serverbound.register(
|
||||||
map(0x00, MINECRAFT_1_7_2, false));
|
ServerboundHandshakePacket.class,
|
||||||
|
ServerboundHandshakePacket.DECODER,
|
||||||
|
map(0x00, MINECRAFT_1_7_2, false)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
STATUS {
|
STATUS(true) {
|
||||||
{
|
{
|
||||||
serverbound.register(StatusRequestPacket.class, () -> StatusRequestPacket.INSTANCE,
|
serverbound.register(
|
||||||
map(0x00, MINECRAFT_1_7_2, false));
|
ServerboundStatusRequestPacket.class,
|
||||||
serverbound.register(StatusPingPacket.class, StatusPingPacket::new,
|
ServerboundStatusRequestPacket.DECODER,
|
||||||
map(0x01, MINECRAFT_1_7_2, false));
|
map(0x00, MINECRAFT_1_7_2, false)
|
||||||
|
);
|
||||||
|
serverbound.register(
|
||||||
|
ServerboundStatusPingPacket.class,
|
||||||
|
ServerboundStatusPingPacket.DECODER,
|
||||||
|
map(0x01, MINECRAFT_1_7_2, false)
|
||||||
|
);
|
||||||
|
|
||||||
clientbound.register(StatusResponsePacket.class, StatusResponsePacket::new,
|
clientbound.register(
|
||||||
map(0x00, MINECRAFT_1_7_2, false));
|
ClientboundStatusResponsePacket.class,
|
||||||
clientbound.register(StatusPingPacket.class, StatusPingPacket::new,
|
ClientboundStatusResponsePacket.DECODER,
|
||||||
map(0x01, MINECRAFT_1_7_2, false));
|
map(0x00, MINECRAFT_1_7_2, false)
|
||||||
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundStatusPingPacket.class,
|
||||||
|
ClientboundStatusPingPacket.DECODER,
|
||||||
|
map(0x01, MINECRAFT_1_7_2, false)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
PLAY {
|
PLAY(false) {
|
||||||
{
|
{
|
||||||
serverbound.fallback = false;
|
serverbound.register(
|
||||||
clientbound.fallback = false;
|
ServerboundTabCompleteRequestPacket.class,
|
||||||
|
ServerboundTabCompleteRequestPacket.DECODER,
|
||||||
serverbound.register(TabCompleteRequestPacket.class, TabCompleteRequestPacket::new,
|
|
||||||
map(0x14, MINECRAFT_1_7_2, false),
|
map(0x14, MINECRAFT_1_7_2, false),
|
||||||
map(0x01, MINECRAFT_1_9, false),
|
map(0x01, MINECRAFT_1_9, false),
|
||||||
map(0x02, MINECRAFT_1_12, false),
|
map(0x02, MINECRAFT_1_12, false),
|
||||||
map(0x01, MINECRAFT_1_12_1, false),
|
map(0x01, MINECRAFT_1_12_1, false),
|
||||||
map(0x05, MINECRAFT_1_13, false),
|
map(0x05, MINECRAFT_1_13, false),
|
||||||
map(0x06, MINECRAFT_1_14, false));
|
map(0x06, MINECRAFT_1_14, false)
|
||||||
serverbound.register(ChatPacket.class, ChatPacket::new,
|
);
|
||||||
|
serverbound.register(
|
||||||
|
ServerboundChatPacket.class,
|
||||||
|
ServerboundChatPacket.DECODER,
|
||||||
map(0x01, MINECRAFT_1_7_2, false),
|
map(0x01, MINECRAFT_1_7_2, false),
|
||||||
map(0x02, MINECRAFT_1_9, false),
|
map(0x02, MINECRAFT_1_9, false),
|
||||||
map(0x03, MINECRAFT_1_12, false),
|
map(0x03, MINECRAFT_1_12, false),
|
||||||
map(0x02, MINECRAFT_1_12_1, false),
|
map(0x02, MINECRAFT_1_12_1, false),
|
||||||
map(0x03, MINECRAFT_1_14, false));
|
map(0x03, MINECRAFT_1_14, false)
|
||||||
serverbound.register(ClientSettingsPacket.class, ClientSettingsPacket::new,
|
);
|
||||||
|
serverbound.register(
|
||||||
|
ServerboundClientSettingsPacket.class,
|
||||||
|
ServerboundClientSettingsPacket.DECODER,
|
||||||
map(0x15, MINECRAFT_1_7_2, false),
|
map(0x15, MINECRAFT_1_7_2, false),
|
||||||
map(0x04, MINECRAFT_1_9, false),
|
map(0x04, MINECRAFT_1_9, false),
|
||||||
map(0x05, MINECRAFT_1_12, false),
|
map(0x05, MINECRAFT_1_12, false),
|
||||||
map(0x04, MINECRAFT_1_12_1, false),
|
map(0x04, MINECRAFT_1_12_1, false),
|
||||||
map(0x05, MINECRAFT_1_14, false));
|
map(0x05, MINECRAFT_1_14, false)
|
||||||
serverbound.register(PluginMessagePacket.class, PluginMessagePacket::new,
|
);
|
||||||
|
serverbound.register(
|
||||||
|
ServerboundPluginMessagePacket.class,
|
||||||
|
ServerboundPluginMessagePacket.DECODER,
|
||||||
map(0x17, MINECRAFT_1_7_2, false),
|
map(0x17, MINECRAFT_1_7_2, false),
|
||||||
map(0x09, MINECRAFT_1_9, false),
|
map(0x09, MINECRAFT_1_9, false),
|
||||||
map(0x0A, MINECRAFT_1_12, false),
|
map(0x0A, MINECRAFT_1_12, false),
|
||||||
map(0x09, MINECRAFT_1_12_1, false),
|
map(0x09, MINECRAFT_1_12_1, false),
|
||||||
map(0x0A, MINECRAFT_1_13, false),
|
map(0x0A, MINECRAFT_1_13, false),
|
||||||
map(0x0B, MINECRAFT_1_14, false));
|
map(0x0B, MINECRAFT_1_14, false)
|
||||||
serverbound.register(KeepAlivePacket.class, KeepAlivePacket::new,
|
);
|
||||||
|
serverbound.register(
|
||||||
|
ServerboundKeepAlivePacket.class,
|
||||||
|
ServerboundKeepAlivePacket.DECODER,
|
||||||
map(0x00, MINECRAFT_1_7_2, false),
|
map(0x00, MINECRAFT_1_7_2, false),
|
||||||
map(0x0B, MINECRAFT_1_9, false),
|
map(0x0B, MINECRAFT_1_9, false),
|
||||||
map(0x0C, MINECRAFT_1_12, false),
|
map(0x0C, MINECRAFT_1_12, false),
|
||||||
map(0x0B, MINECRAFT_1_12_1, false),
|
map(0x0B, MINECRAFT_1_12_1, false),
|
||||||
map(0x0E, MINECRAFT_1_13, false),
|
map(0x0E, MINECRAFT_1_13, false),
|
||||||
map(0x0F, MINECRAFT_1_14, false),
|
map(0x0F, MINECRAFT_1_14, false),
|
||||||
map(0x10, MINECRAFT_1_16, false));
|
map(0x10, MINECRAFT_1_16, false)
|
||||||
serverbound.register(ResourcePackResponsePacket.class, ResourcePackResponsePacket::new,
|
);
|
||||||
|
serverbound.register(
|
||||||
|
ServerboundResourcePackResponsePacket.class,
|
||||||
|
ServerboundResourcePackResponsePacket.DECODER,
|
||||||
map(0x19, MINECRAFT_1_8, false),
|
map(0x19, MINECRAFT_1_8, false),
|
||||||
map(0x16, MINECRAFT_1_9, false),
|
map(0x16, MINECRAFT_1_9, false),
|
||||||
map(0x18, MINECRAFT_1_12, false),
|
map(0x18, MINECRAFT_1_12, false),
|
||||||
map(0x1D, MINECRAFT_1_13, false),
|
map(0x1D, MINECRAFT_1_13, false),
|
||||||
map(0x1F, MINECRAFT_1_14, false),
|
map(0x1F, MINECRAFT_1_14, false),
|
||||||
map(0x20, MINECRAFT_1_16, false),
|
map(0x20, MINECRAFT_1_16, false),
|
||||||
map(0x21, MINECRAFT_1_16_2, false));
|
map(0x21, MINECRAFT_1_16_2, false)
|
||||||
|
);
|
||||||
|
|
||||||
clientbound.register(BossBarPacket.class, BossBarPacket::new,
|
clientbound.register(
|
||||||
|
ClientboundBossBarPacket.class,
|
||||||
|
ClientboundBossBarPacket.DECODER,
|
||||||
map(0x0C, MINECRAFT_1_9, false),
|
map(0x0C, MINECRAFT_1_9, false),
|
||||||
map(0x0D, MINECRAFT_1_15, false),
|
map(0x0D, MINECRAFT_1_15, false),
|
||||||
map(0x0C, MINECRAFT_1_16, false));
|
map(0x0C, MINECRAFT_1_16, false)
|
||||||
clientbound.register(ChatPacket.class, ChatPacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundChatPacket.class,
|
||||||
|
ClientboundChatPacket.DECODER,
|
||||||
map(0x02, MINECRAFT_1_7_2, true),
|
map(0x02, MINECRAFT_1_7_2, true),
|
||||||
map(0x0F, MINECRAFT_1_9, true),
|
map(0x0F, MINECRAFT_1_9, true),
|
||||||
map(0x0E, MINECRAFT_1_13, true),
|
map(0x0E, MINECRAFT_1_13, true),
|
||||||
map(0x0F, MINECRAFT_1_15, true),
|
map(0x0F, MINECRAFT_1_15, true),
|
||||||
map(0x0E, MINECRAFT_1_16, true));
|
map(0x0E, MINECRAFT_1_16, true)
|
||||||
clientbound.register(TabCompleteResponsePacket.class, TabCompleteResponsePacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundTabCompleteResponsePacket.class,
|
||||||
|
ClientboundTabCompleteResponsePacket.DECODER,
|
||||||
map(0x3A, MINECRAFT_1_7_2, false),
|
map(0x3A, MINECRAFT_1_7_2, false),
|
||||||
map(0x0E, MINECRAFT_1_9, false),
|
map(0x0E, MINECRAFT_1_9, false),
|
||||||
map(0x10, MINECRAFT_1_13, false),
|
map(0x10, MINECRAFT_1_13, false),
|
||||||
map(0x11, MINECRAFT_1_15, false),
|
map(0x11, MINECRAFT_1_15, false),
|
||||||
map(0x10, MINECRAFT_1_16, false),
|
map(0x10, MINECRAFT_1_16, false),
|
||||||
map(0x0F, MINECRAFT_1_16_2, false));
|
map(0x0F, MINECRAFT_1_16_2, false)
|
||||||
clientbound.register(AvailableCommandsPacket.class, AvailableCommandsPacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundAvailableCommandsPacket.class,
|
||||||
|
ClientboundAvailableCommandsPacket.DECODER,
|
||||||
map(0x11, MINECRAFT_1_13, false),
|
map(0x11, MINECRAFT_1_13, false),
|
||||||
map(0x12, MINECRAFT_1_15, false),
|
map(0x12, MINECRAFT_1_15, false),
|
||||||
map(0x11, MINECRAFT_1_16, false),
|
map(0x11, MINECRAFT_1_16, false),
|
||||||
map(0x10, MINECRAFT_1_16_2, false));
|
map(0x10, MINECRAFT_1_16_2, false)
|
||||||
clientbound.register(PluginMessagePacket.class, PluginMessagePacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundPluginMessagePacket.class,
|
||||||
|
ClientboundPluginMessagePacket.DECODER,
|
||||||
map(0x3F, MINECRAFT_1_7_2, false),
|
map(0x3F, MINECRAFT_1_7_2, false),
|
||||||
map(0x18, MINECRAFT_1_9, false),
|
map(0x18, MINECRAFT_1_9, false),
|
||||||
map(0x19, MINECRAFT_1_13, false),
|
map(0x19, MINECRAFT_1_13, false),
|
||||||
map(0x18, MINECRAFT_1_14, false),
|
map(0x18, MINECRAFT_1_14, false),
|
||||||
map(0x19, MINECRAFT_1_15, false),
|
map(0x19, MINECRAFT_1_15, false),
|
||||||
map(0x18, MINECRAFT_1_16, false),
|
map(0x18, MINECRAFT_1_16, false),
|
||||||
map(0x17, MINECRAFT_1_16_2, false));
|
map(0x17, MINECRAFT_1_16_2, false)
|
||||||
clientbound.register(DisconnectPacket.class, DisconnectPacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundDisconnectPacket.class,
|
||||||
|
ClientboundDisconnectPacket.DECODER,
|
||||||
map(0x40, MINECRAFT_1_7_2, false),
|
map(0x40, MINECRAFT_1_7_2, false),
|
||||||
map(0x1A, MINECRAFT_1_9, false),
|
map(0x1A, MINECRAFT_1_9, false),
|
||||||
map(0x1B, MINECRAFT_1_13, false),
|
map(0x1B, MINECRAFT_1_13, false),
|
||||||
map(0x1A, MINECRAFT_1_14, false),
|
map(0x1A, MINECRAFT_1_14, false),
|
||||||
map(0x1B, MINECRAFT_1_15, false),
|
map(0x1B, MINECRAFT_1_15, false),
|
||||||
map(0x1A, MINECRAFT_1_16, false),
|
map(0x1A, MINECRAFT_1_16, false),
|
||||||
map(0x19, MINECRAFT_1_16_2, false));
|
map(0x19, MINECRAFT_1_16_2, false)
|
||||||
clientbound.register(KeepAlivePacket.class, KeepAlivePacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundKeepAlivePacket.class,
|
||||||
|
ClientboundKeepAlivePacket.DECODER,
|
||||||
map(0x00, MINECRAFT_1_7_2, false),
|
map(0x00, MINECRAFT_1_7_2, false),
|
||||||
map(0x1F, MINECRAFT_1_9, false),
|
map(0x1F, MINECRAFT_1_9, false),
|
||||||
map(0x21, MINECRAFT_1_13, false),
|
map(0x21, MINECRAFT_1_13, false),
|
||||||
map(0x20, MINECRAFT_1_14, false),
|
map(0x20, MINECRAFT_1_14, false),
|
||||||
map(0x21, MINECRAFT_1_15, false),
|
map(0x21, MINECRAFT_1_15, false),
|
||||||
map(0x20, MINECRAFT_1_16, false),
|
map(0x20, MINECRAFT_1_16, false),
|
||||||
map(0x1F, MINECRAFT_1_16_2, false));
|
map(0x1F, MINECRAFT_1_16_2, false)
|
||||||
clientbound.register(JoinGamePacket.class, JoinGamePacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundJoinGamePacket.class,
|
||||||
|
ClientboundJoinGamePacket.DECODER,
|
||||||
map(0x01, MINECRAFT_1_7_2, false),
|
map(0x01, MINECRAFT_1_7_2, false),
|
||||||
map(0x23, MINECRAFT_1_9, false),
|
map(0x23, MINECRAFT_1_9, false),
|
||||||
map(0x25, MINECRAFT_1_13, false),
|
map(0x25, MINECRAFT_1_13, false),
|
||||||
map(0x25, MINECRAFT_1_14, false),
|
map(0x25, MINECRAFT_1_14, false),
|
||||||
map(0x26, MINECRAFT_1_15, false),
|
map(0x26, MINECRAFT_1_15, false),
|
||||||
map(0x25, MINECRAFT_1_16, false),
|
map(0x25, MINECRAFT_1_16, false),
|
||||||
map(0x24, MINECRAFT_1_16_2, false));
|
map(0x24, MINECRAFT_1_16_2, false)
|
||||||
clientbound.register(RespawnPacket.class, RespawnPacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundRespawnPacket.class,
|
||||||
|
ClientboundRespawnPacket.DECODER,
|
||||||
map(0x07, MINECRAFT_1_7_2, true),
|
map(0x07, MINECRAFT_1_7_2, true),
|
||||||
map(0x33, MINECRAFT_1_9, true),
|
map(0x33, MINECRAFT_1_9, true),
|
||||||
map(0x34, MINECRAFT_1_12, true),
|
map(0x34, MINECRAFT_1_12, true),
|
||||||
@@ -187,8 +250,11 @@ public enum StateRegistry {
|
|||||||
map(0x3A, MINECRAFT_1_14, true),
|
map(0x3A, MINECRAFT_1_14, true),
|
||||||
map(0x3B, MINECRAFT_1_15, true),
|
map(0x3B, MINECRAFT_1_15, true),
|
||||||
map(0x3A, MINECRAFT_1_16, true),
|
map(0x3A, MINECRAFT_1_16, true),
|
||||||
map(0x39, MINECRAFT_1_16_2, true));
|
map(0x39, MINECRAFT_1_16_2, true)
|
||||||
clientbound.register(ResourcePackRequestPacket.class, ResourcePackRequestPacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundResourcePackRequestPacket.class,
|
||||||
|
ClientboundResourcePackRequestPacket.DECODER,
|
||||||
map(0x48, MINECRAFT_1_8, true),
|
map(0x48, MINECRAFT_1_8, true),
|
||||||
map(0x32, MINECRAFT_1_9, true),
|
map(0x32, MINECRAFT_1_9, true),
|
||||||
map(0x33, MINECRAFT_1_12, true),
|
map(0x33, MINECRAFT_1_12, true),
|
||||||
@@ -197,8 +263,11 @@ public enum StateRegistry {
|
|||||||
map(0x39, MINECRAFT_1_14, true),
|
map(0x39, MINECRAFT_1_14, true),
|
||||||
map(0x3A, MINECRAFT_1_15, true),
|
map(0x3A, MINECRAFT_1_15, true),
|
||||||
map(0x39, MINECRAFT_1_16, true),
|
map(0x39, MINECRAFT_1_16, true),
|
||||||
map(0x38, MINECRAFT_1_16_2, true));
|
map(0x38, MINECRAFT_1_16_2, true)
|
||||||
clientbound.register(HeaderAndFooterPacket.class, HeaderAndFooterPacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundHeaderAndFooterPacket.class,
|
||||||
|
ClientboundHeaderAndFooterPacket.DECODER,
|
||||||
map(0x47, MINECRAFT_1_8, true),
|
map(0x47, MINECRAFT_1_8, true),
|
||||||
map(0x48, MINECRAFT_1_9, true),
|
map(0x48, MINECRAFT_1_9, true),
|
||||||
map(0x47, MINECRAFT_1_9_4, true),
|
map(0x47, MINECRAFT_1_9_4, true),
|
||||||
@@ -207,8 +276,11 @@ public enum StateRegistry {
|
|||||||
map(0x4E, MINECRAFT_1_13, true),
|
map(0x4E, MINECRAFT_1_13, true),
|
||||||
map(0x53, MINECRAFT_1_14, true),
|
map(0x53, MINECRAFT_1_14, true),
|
||||||
map(0x54, MINECRAFT_1_15, true),
|
map(0x54, MINECRAFT_1_15, true),
|
||||||
map(0x53, MINECRAFT_1_16, true));
|
map(0x53, MINECRAFT_1_16, true)
|
||||||
clientbound.register(TitlePacket.class, TitlePacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundTitlePacket.class,
|
||||||
|
ClientboundTitlePacket.DECODER,
|
||||||
map(0x45, MINECRAFT_1_8, true),
|
map(0x45, MINECRAFT_1_8, true),
|
||||||
map(0x45, MINECRAFT_1_9, true),
|
map(0x45, MINECRAFT_1_9, true),
|
||||||
map(0x47, MINECRAFT_1_12, true),
|
map(0x47, MINECRAFT_1_12, true),
|
||||||
@@ -216,8 +288,11 @@ public enum StateRegistry {
|
|||||||
map(0x4B, MINECRAFT_1_13, true),
|
map(0x4B, MINECRAFT_1_13, true),
|
||||||
map(0x4F, MINECRAFT_1_14, true),
|
map(0x4F, MINECRAFT_1_14, true),
|
||||||
map(0x50, MINECRAFT_1_15, true),
|
map(0x50, MINECRAFT_1_15, true),
|
||||||
map(0x4F, MINECRAFT_1_16, true));
|
map(0x4F, MINECRAFT_1_16, true)
|
||||||
clientbound.register(PlayerListItemPacket.class, PlayerListItemPacket::new,
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundPlayerListItemPacket.class,
|
||||||
|
ClientboundPlayerListItemPacket.DECODER,
|
||||||
map(0x38, MINECRAFT_1_7_2, false),
|
map(0x38, MINECRAFT_1_7_2, false),
|
||||||
map(0x2D, MINECRAFT_1_9, false),
|
map(0x2D, MINECRAFT_1_9, false),
|
||||||
map(0x2E, MINECRAFT_1_12_1, false),
|
map(0x2E, MINECRAFT_1_12_1, false),
|
||||||
@@ -225,49 +300,85 @@ public enum StateRegistry {
|
|||||||
map(0x33, MINECRAFT_1_14, false),
|
map(0x33, MINECRAFT_1_14, false),
|
||||||
map(0x34, MINECRAFT_1_15, false),
|
map(0x34, MINECRAFT_1_15, false),
|
||||||
map(0x33, MINECRAFT_1_16, false),
|
map(0x33, MINECRAFT_1_16, false),
|
||||||
map(0x32, MINECRAFT_1_16_2, false));
|
map(0x32, MINECRAFT_1_16_2, false)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
LOGIN {
|
LOGIN(true) {
|
||||||
{
|
{
|
||||||
serverbound.register(ServerLoginPacket.class, ServerLoginPacket::new,
|
serverbound.register(
|
||||||
map(0x00, MINECRAFT_1_7_2, false));
|
ServerboundServerLoginPacket.class,
|
||||||
serverbound.register(EncryptionResponsePacket.class, EncryptionResponsePacket::new,
|
ServerboundServerLoginPacket.DECODER,
|
||||||
map(0x01, MINECRAFT_1_7_2, false));
|
map(0x00, MINECRAFT_1_7_2, false)
|
||||||
serverbound.register(LoginPluginResponsePacket.class, LoginPluginResponsePacket::new,
|
);
|
||||||
map(0x02, MINECRAFT_1_13, false));
|
serverbound.register(
|
||||||
clientbound.register(DisconnectPacket.class, DisconnectPacket::new,
|
ServerboundEncryptionResponsePacket.class,
|
||||||
map(0x00, MINECRAFT_1_7_2, false));
|
ServerboundEncryptionResponsePacket.DECODER,
|
||||||
clientbound.register(EncryptionRequestPacket.class, EncryptionRequestPacket::new,
|
map(0x01, MINECRAFT_1_7_2, false)
|
||||||
map(0x01, MINECRAFT_1_7_2, false));
|
);
|
||||||
clientbound.register(ServerLoginSuccessPacket.class, ServerLoginSuccessPacket::new,
|
serverbound.register(
|
||||||
map(0x02, MINECRAFT_1_7_2, false));
|
ServerboundLoginPluginResponsePacket.class,
|
||||||
clientbound.register(SetCompressionPacket.class, SetCompressionPacket::new,
|
ServerboundLoginPluginResponsePacket.DECODER,
|
||||||
map(0x03, MINECRAFT_1_8, false));
|
map(0x02, MINECRAFT_1_13, false)
|
||||||
clientbound.register(LoginPluginMessagePacket.class, LoginPluginMessagePacket::new,
|
);
|
||||||
map(0x04, MINECRAFT_1_13, false));
|
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundDisconnectPacket.class,
|
||||||
|
ClientboundDisconnectPacket.DECODER,
|
||||||
|
map(0x00, MINECRAFT_1_7_2, false)
|
||||||
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundEncryptionRequestPacket.class,
|
||||||
|
ClientboundEncryptionRequestPacket.DECODER,
|
||||||
|
map(0x01, MINECRAFT_1_7_2, false)
|
||||||
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundServerLoginSuccessPacket.class,
|
||||||
|
ClientboundServerLoginSuccessPacket.DECODER,
|
||||||
|
map(0x02, MINECRAFT_1_7_2, false)
|
||||||
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundSetCompressionPacket.class,
|
||||||
|
ClientboundSetCompressionPacket.DECODER,
|
||||||
|
map(0x03, MINECRAFT_1_8, false)
|
||||||
|
);
|
||||||
|
clientbound.register(
|
||||||
|
ClientboundLoginPluginMessagePacket.class,
|
||||||
|
ClientboundLoginPluginMessagePacket.DECODER,
|
||||||
|
map(0x04, MINECRAFT_1_13, false)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final int STATUS_ID = 1;
|
public static final int STATUS_ID = 1;
|
||||||
public static final int LOGIN_ID = 2;
|
public static final int LOGIN_ID = 2;
|
||||||
public final PacketRegistry clientbound = new PacketRegistry(ProtocolDirection.CLIENTBOUND);
|
public final PacketRegistry clientbound;
|
||||||
public final PacketRegistry serverbound = new PacketRegistry(ProtocolDirection.SERVERBOUND);
|
public final PacketRegistry serverbound;
|
||||||
|
|
||||||
public PacketRegistry.ProtocolRegistry getProtocolRegistry(ProtocolDirection direction,
|
StateRegistry(boolean useMinimumIfVersionNotFound) {
|
||||||
ProtocolVersion version) {
|
this.clientbound = new PacketRegistry(PacketDirection.CLIENTBOUND, useMinimumIfVersionNotFound);
|
||||||
return (direction == ProtocolDirection.SERVERBOUND ? this.serverbound : this.clientbound)
|
this.serverbound = new PacketRegistry(PacketDirection.SERVERBOUND, useMinimumIfVersionNotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketRegistry.ProtocolRegistry getProtocolRegistry(PacketDirection direction,
|
||||||
|
ProtocolVersion version) {
|
||||||
|
return (direction == PacketDirection.SERVERBOUND ? this.serverbound : this.clientbound)
|
||||||
.getProtocolRegistry(version);
|
.getProtocolRegistry(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PacketRegistry {
|
public static class PacketRegistry {
|
||||||
|
|
||||||
private final ProtocolDirection direction;
|
private final PacketDirection direction;
|
||||||
private final Map<ProtocolVersion, ProtocolRegistry> versions;
|
private final Map<ProtocolVersion, ProtocolRegistry> versions;
|
||||||
private boolean fallback = true;
|
private final boolean useMinimumIfVersionNotFound;
|
||||||
|
|
||||||
PacketRegistry(ProtocolDirection direction) {
|
PacketRegistry(PacketDirection direction) {
|
||||||
|
this(direction, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketRegistry(PacketDirection direction, boolean useMinimumIfVersionNotFound) {
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
|
this.useMinimumIfVersionNotFound = useMinimumIfVersionNotFound;
|
||||||
|
|
||||||
Map<ProtocolVersion, ProtocolRegistry> mutableVersions = new EnumMap<>(ProtocolVersion.class);
|
Map<ProtocolVersion, ProtocolRegistry> mutableVersions = new EnumMap<>(ProtocolVersion.class);
|
||||||
for (ProtocolVersion version : ProtocolVersion.values()) {
|
for (ProtocolVersion version : ProtocolVersion.values()) {
|
||||||
@@ -282,7 +393,7 @@ public enum StateRegistry {
|
|||||||
ProtocolRegistry getProtocolRegistry(final ProtocolVersion version) {
|
ProtocolRegistry getProtocolRegistry(final ProtocolVersion version) {
|
||||||
ProtocolRegistry registry = versions.get(version);
|
ProtocolRegistry registry = versions.get(version);
|
||||||
if (registry == null) {
|
if (registry == null) {
|
||||||
if (fallback) {
|
if (useMinimumIfVersionNotFound) {
|
||||||
return getProtocolRegistry(MINIMUM_VERSION);
|
return getProtocolRegistry(MINIMUM_VERSION);
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("Could not find data for protocol version " + version);
|
throw new IllegalArgumentException("Could not find data for protocol version " + version);
|
||||||
@@ -290,7 +401,7 @@ public enum StateRegistry {
|
|||||||
return registry;
|
return registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
<P extends Packet> void register(Class<P> clazz, Supplier<P> packetSupplier,
|
<P extends Packet> void register(Class<P> clazz, PacketReader<P> decoder,
|
||||||
PacketMapping... mappings) {
|
PacketMapping... mappings) {
|
||||||
if (mappings.length == 0) {
|
if (mappings.length == 0) {
|
||||||
throw new IllegalArgumentException("At least one mapping must be provided.");
|
throw new IllegalArgumentException("At least one mapping must be provided.");
|
||||||
@@ -317,7 +428,7 @@ public enum StateRegistry {
|
|||||||
+ current.protocolVersion);
|
+ current.protocolVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registry.packetIdToSupplier.containsKey(current.id)) {
|
if (registry.packetIdToReader.containsKey(current.id)) {
|
||||||
throw new IllegalArgumentException("Can not register class " + clazz.getSimpleName()
|
throw new IllegalArgumentException("Can not register class " + clazz.getSimpleName()
|
||||||
+ " with id " + current.id + " for " + registry.version
|
+ " with id " + current.id + " for " + registry.version
|
||||||
+ " because another packet is already registered");
|
+ " because another packet is already registered");
|
||||||
@@ -329,7 +440,7 @@ public enum StateRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!current.encodeOnly) {
|
if (!current.encodeOnly) {
|
||||||
registry.packetIdToSupplier.put(current.id, packetSupplier);
|
registry.packetIdToReader.put(current.id, decoder);
|
||||||
}
|
}
|
||||||
registry.packetClassToId.put(clazz, current.id);
|
registry.packetClassToId.put(clazz, current.id);
|
||||||
}
|
}
|
||||||
@@ -339,7 +450,7 @@ public enum StateRegistry {
|
|||||||
public class ProtocolRegistry {
|
public class ProtocolRegistry {
|
||||||
|
|
||||||
public final ProtocolVersion version;
|
public final ProtocolVersion version;
|
||||||
final IntObjectMap<Supplier<? extends Packet>> packetIdToSupplier =
|
final IntObjectMap<PacketReader<? extends Packet>> packetIdToReader =
|
||||||
new IntObjectHashMap<>(16, 0.5f);
|
new IntObjectHashMap<>(16, 0.5f);
|
||||||
final Object2IntMap<Class<? extends Packet>> packetClassToId =
|
final Object2IntMap<Class<? extends Packet>> packetClassToId =
|
||||||
new Object2IntOpenHashMap<>(16, 0.5f);
|
new Object2IntOpenHashMap<>(16, 0.5f);
|
||||||
@@ -353,14 +464,18 @@ public enum StateRegistry {
|
|||||||
* Attempts to create a packet from the specified {@code id}.
|
* Attempts to create a packet from the specified {@code id}.
|
||||||
*
|
*
|
||||||
* @param id the packet ID
|
* @param id the packet ID
|
||||||
|
* @param buf the bytebuf
|
||||||
|
* @param direction the packet direction
|
||||||
|
* @param version the protocol version
|
||||||
* @return the packet instance, or {@code null} if the ID is not registered
|
* @return the packet instance, or {@code null} if the ID is not registered
|
||||||
*/
|
*/
|
||||||
public @Nullable Packet createPacket(final int id) {
|
public @Nullable Packet readPacket(final int id, ByteBuf buf, PacketDirection direction,
|
||||||
final Supplier<? extends Packet> supplier = this.packetIdToSupplier.get(id);
|
ProtocolVersion version) {
|
||||||
if (supplier == null) {
|
final PacketReader<? extends Packet> decoder = this.packetIdToReader.get(id);
|
||||||
|
if (decoder == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return supplier.get();
|
return decoder.read(buf, direction, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -385,9 +500,9 @@ public enum StateRegistry {
|
|||||||
|
|
||||||
public static final class PacketMapping {
|
public static final class PacketMapping {
|
||||||
|
|
||||||
private final int id;
|
final int id;
|
||||||
private final ProtocolVersion protocolVersion;
|
final ProtocolVersion protocolVersion;
|
||||||
private final boolean encodeOnly;
|
final boolean encodeOnly;
|
||||||
|
|
||||||
PacketMapping(int id, ProtocolVersion protocolVersion, boolean packetDecoding) {
|
PacketMapping(int id, ProtocolVersion protocolVersion, boolean packetDecoding) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.util;
|
package com.velocitypowered.proxy.network.buffer;
|
||||||
|
|
||||||
import com.google.common.io.ByteArrayDataInput;
|
import com.google.common.io.ByteArrayDataInput;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
package com.velocitypowered.proxy.protocol.util;
|
package com.velocitypowered.proxy.network.buffer;
|
||||||
|
|
||||||
import com.google.common.io.ByteArrayDataOutput;
|
import com.google.common.io.ByteArrayDataOutput;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufUtil;
|
import io.netty.buffer.ByteBufUtil;
|
||||||
import java.io.DataOutput;
|
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.velocitypowered.proxy.network.buffer;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.DefaultByteBufHolder;
|
||||||
|
|
||||||
|
public abstract class TypedDefaultByteBufHolder<S extends TypedDefaultByteBufHolder<S>> extends DefaultByteBufHolder {
|
||||||
|
protected TypedDefaultByteBufHolder(final ByteBuf data) {
|
||||||
|
super(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract S replace(final ByteBuf content);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public S retain() {
|
||||||
|
return (S) super.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public S retain(final int increment) {
|
||||||
|
return (S) super.retain(increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public S touch() {
|
||||||
|
return (S) super.touch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public S touch(final Object hint) {
|
||||||
|
return (S) super.touch(hint);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.function.LongFunction;
|
||||||
|
|
||||||
|
public abstract class AbstractKeepAlivePacket implements Packet {
|
||||||
|
protected static <P extends AbstractKeepAlivePacket> PacketReader<P> decoder(final LongFunction<P> factory) {
|
||||||
|
return (buf, direction, version) -> {
|
||||||
|
final long randomId;
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_12_2)) {
|
||||||
|
randomId = buf.readLong();
|
||||||
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
|
randomId = ProtocolUtils.readVarInt(buf);
|
||||||
|
} else {
|
||||||
|
randomId = buf.readInt();
|
||||||
|
}
|
||||||
|
return factory.apply(randomId);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private final long randomId;
|
||||||
|
|
||||||
|
protected AbstractKeepAlivePacket(final long randomId) {
|
||||||
|
this.randomId = randomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_12_2)) {
|
||||||
|
buf.writeLong(randomId);
|
||||||
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
|
ProtocolUtils.writeVarInt(buf, (int) randomId);
|
||||||
|
} else {
|
||||||
|
buf.writeInt((int) randomId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRandomId() {
|
||||||
|
return randomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("randomId", this.randomId)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet;
|
||||||
|
|
||||||
|
import static com.velocitypowered.proxy.network.PluginMessageUtil.transformLegacyToModernChannel;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.buffer.TypedDefaultByteBufHolder;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public abstract class AbstractPluginMessagePacket<S extends AbstractPluginMessagePacket<S>> extends TypedDefaultByteBufHolder<S> implements Packet {
|
||||||
|
protected static <P extends AbstractPluginMessagePacket<P>> PacketReader<P> decoder(final Factory<P> factory) {
|
||||||
|
return (buf, direction, version) -> {
|
||||||
|
String channel = ProtocolUtils.readString(buf);
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
|
channel = transformLegacyToModernChannel(channel);
|
||||||
|
}
|
||||||
|
final ByteBuf data;
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
|
data = buf.readRetainedSlice(buf.readableBytes());
|
||||||
|
} else {
|
||||||
|
data = ProtocolUtils.readRetainedByteBufSlice17(buf);
|
||||||
|
}
|
||||||
|
return factory.create(channel, data);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final @Nullable String channel;
|
||||||
|
|
||||||
|
protected AbstractPluginMessagePacket(String channel,
|
||||||
|
@MonotonicNonNull ByteBuf backing) {
|
||||||
|
super(backing);
|
||||||
|
this.channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
if (channel == null) {
|
||||||
|
throw new IllegalStateException("Channel is not specified.");
|
||||||
|
}
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
|
ProtocolUtils.writeString(buf, transformLegacyToModernChannel(this.channel));
|
||||||
|
} else {
|
||||||
|
ProtocolUtils.writeString(buf, this.channel);
|
||||||
|
}
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
|
buf.writeBytes(content());
|
||||||
|
} else {
|
||||||
|
ProtocolUtils.writeByteBuf17(content(), buf, true); // True for Forge support
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChannel() {
|
||||||
|
if (channel == null) {
|
||||||
|
throw new IllegalStateException("Channel is not specified.");
|
||||||
|
}
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object other) {
|
||||||
|
if (this == other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other == null || this.getClass() != other.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final AbstractPluginMessagePacket<?> that = (AbstractPluginMessagePacket<?>) other;
|
||||||
|
return Objects.equals(this.channel, that.channel)
|
||||||
|
&& super.equals(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(this.channel, super.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("channel", this.channel)
|
||||||
|
.add("data", this.contentToString())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Factory<P extends AbstractPluginMessagePacket<P>> {
|
||||||
|
P create(final String channel, final ByteBuf data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.function.LongFunction;
|
||||||
|
|
||||||
|
public abstract class AbstractStatusPingPacket implements Packet {
|
||||||
|
protected static <P extends AbstractStatusPingPacket> PacketReader<P> decoder(final LongFunction<P> factory) {
|
||||||
|
return (buf, direction, version) -> {
|
||||||
|
final long randomId = buf.readLong();
|
||||||
|
return factory.apply(randomId);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private final long randomId;
|
||||||
|
|
||||||
|
protected AbstractStatusPingPacket(final long randomId) {
|
||||||
|
this.randomId = randomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
buf.writeLong(this.randomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("randomId", this.randomId)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public interface Packet {
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
default void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion protocolVersion) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion protocolVersion);
|
||||||
|
|
||||||
|
boolean handle(PacketHandler handler);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet;
|
||||||
|
|
||||||
|
public enum PacketDirection {
|
||||||
|
SERVERBOUND,
|
||||||
|
CLIENTBOUND;
|
||||||
|
}
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundAvailableCommandsPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundBossBarPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundChatPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundEncryptionRequestPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundHeaderAndFooterPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundJoinGamePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundKeepAlivePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundLoginPluginMessagePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPlayerListItemPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundResourcePackRequestPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundRespawnPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundServerLoginSuccessPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundSetCompressionPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundStatusPingPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundStatusResponsePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTabCompleteResponsePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTitlePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyHandshakePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyPingPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundChatPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundClientSettingsPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundEncryptionResponsePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundHandshakePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundKeepAlivePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundLoginPluginResponsePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundPluginMessagePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundResourcePackResponsePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundServerLoginPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundStatusPingPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundStatusRequestPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundTabCompleteRequestPacket;
|
||||||
|
|
||||||
|
public interface PacketHandler {
|
||||||
|
/*
|
||||||
|
* Clientbound
|
||||||
|
*/
|
||||||
|
|
||||||
|
default boolean handle(ClientboundAvailableCommandsPacket commands) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundBossBarPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundChatPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundDisconnectPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundEncryptionRequestPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundHeaderAndFooterPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundJoinGamePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundKeepAlivePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundLoginPluginMessagePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundPlayerListItemPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundPluginMessagePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundResourcePackRequestPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundRespawnPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundServerLoginSuccessPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundSetCompressionPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundStatusPingPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundStatusResponsePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundTabCompleteResponsePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ClientboundTitlePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serverbound
|
||||||
|
*/
|
||||||
|
|
||||||
|
default boolean handle(ServerboundChatPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundClientSettingsPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundEncryptionResponsePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundHandshakePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundKeepAlivePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundLoginPluginResponsePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundPluginMessagePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundResourcePackResponsePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundServerLoginPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundStatusPingPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundStatusRequestPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundTabCompleteRequestPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Legacy
|
||||||
|
*/
|
||||||
|
|
||||||
|
default boolean handle(LegacyHandshakePacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(LegacyPingPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public interface PacketReader<P extends Packet> {
|
||||||
|
P read(final ByteBuf buf, final PacketDirection direction, final ProtocolVersion version);
|
||||||
|
|
||||||
|
static <P extends Packet> PacketReader<P> unsupported() {
|
||||||
|
return (buf, direction, version) -> {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static <P extends Packet> PacketReader<P> instance(final P packet) {
|
||||||
|
return (buf, direction, version) -> packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
static <P extends Packet> PacketReader<P> method(final Supplier<P> factory) {
|
||||||
|
return (buf, direction, version) -> {
|
||||||
|
final P packet = factory.get();
|
||||||
|
packet.decode(buf, direction, version);
|
||||||
|
return packet;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet;
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
@@ -18,11 +18,12 @@ import com.mojang.brigadier.tree.LiteralCommandNode;
|
|||||||
import com.mojang.brigadier.tree.RootCommandNode;
|
import com.mojang.brigadier.tree.RootCommandNode;
|
||||||
import com.velocitypowered.api.command.CommandSource;
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
import com.velocitypowered.proxy.protocol.packet.brigadier.ArgumentPropertyRegistry;
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import com.velocitypowered.proxy.network.serialization.brigadier.ArgumentPropertyRegistry;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
@@ -35,7 +36,9 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class AvailableCommandsPacket implements Packet {
|
public class ClientboundAvailableCommandsPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundAvailableCommandsPacket> DECODER = PacketReader.method(ClientboundAvailableCommandsPacket::new);
|
||||||
|
|
||||||
private static final Command<CommandSource> PLACEHOLDER_COMMAND = source -> 0;
|
private static final Command<CommandSource> PLACEHOLDER_COMMAND = source -> 0;
|
||||||
|
|
||||||
private static final byte NODE_TYPE_ROOT = 0x00;
|
private static final byte NODE_TYPE_ROOT = 0x00;
|
||||||
@@ -61,7 +64,7 @@ public class AvailableCommandsPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion) {
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion protocolVersion) {
|
||||||
int commands = ProtocolUtils.readVarInt(buf);
|
int commands = ProtocolUtils.readVarInt(buf);
|
||||||
WireNode[] wireNodes = new WireNode[commands];
|
WireNode[] wireNodes = new WireNode[commands];
|
||||||
for (int i = 0; i < commands; i++) {
|
for (int i = 0; i < commands; i++) {
|
||||||
@@ -93,7 +96,7 @@ public class AvailableCommandsPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion) {
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion protocolVersion) {
|
||||||
// Assign all the children an index.
|
// Assign all the children an index.
|
||||||
Deque<CommandNode<CommandSource>> childrenQueue = new ArrayDeque<>(ImmutableList.of(rootNode));
|
Deque<CommandNode<CommandSource>> childrenQueue = new ArrayDeque<>(ImmutableList.of(rootNode));
|
||||||
Object2IntMap<CommandNode<CommandSource>> idMappings = new Object2IntLinkedOpenHashMap<>();
|
Object2IntMap<CommandNode<CommandSource>> idMappings = new Object2IntLinkedOpenHashMap<>();
|
||||||
@@ -163,7 +166,7 @@ public class AvailableCommandsPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(PacketHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,15 +1,19 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet;
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class BossBarPacket implements Packet {
|
public class ClientboundBossBarPacket implements Packet {
|
||||||
|
|
||||||
|
public static final PacketReader<ClientboundBossBarPacket> DECODER = PacketReader.method(ClientboundBossBarPacket::new);
|
||||||
|
|
||||||
public static final int ADD = 0;
|
public static final int ADD = 0;
|
||||||
public static final int REMOVE = 1;
|
public static final int REMOVE = 1;
|
||||||
@@ -86,20 +90,7 @@ public class BossBarPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
return "BossBar{"
|
|
||||||
+ "uuid=" + uuid
|
|
||||||
+ ", action=" + action
|
|
||||||
+ ", name='" + name + '\''
|
|
||||||
+ ", percent=" + percent
|
|
||||||
+ ", color=" + color
|
|
||||||
+ ", overlay=" + overlay
|
|
||||||
+ ", flags=" + flags
|
|
||||||
+ '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
this.uuid = ProtocolUtils.readUuid(buf);
|
this.uuid = ProtocolUtils.readUuid(buf);
|
||||||
this.action = ProtocolUtils.readVarInt(buf);
|
this.action = ProtocolUtils.readVarInt(buf);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
@@ -131,7 +122,7 @@ public class BossBarPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
throw new IllegalStateException("No boss bar UUID specified");
|
throw new IllegalStateException("No boss bar UUID specified");
|
||||||
}
|
}
|
||||||
@@ -172,14 +163,27 @@ public class BossBarPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(PacketHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BossBarPacket createRemovePacket(UUID id) {
|
public static ClientboundBossBarPacket createRemovePacket(UUID id) {
|
||||||
BossBarPacket packet = new BossBarPacket();
|
ClientboundBossBarPacket packet = new ClientboundBossBarPacket();
|
||||||
packet.setUuid(id);
|
packet.setUuid(id);
|
||||||
packet.setAction(REMOVE);
|
packet.setAction(REMOVE);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("uuid", this.uuid)
|
||||||
|
.add("action", this.action)
|
||||||
|
.add("name", this.name)
|
||||||
|
.add("percent", this.percent)
|
||||||
|
.add("color", this.color)
|
||||||
|
.add("overlay", this.overlay)
|
||||||
|
.add("flags", this.flags)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.UUID;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public class ClientboundChatPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundChatPacket> DECODER = PacketReader.method(ClientboundChatPacket::new);
|
||||||
|
|
||||||
|
public static final byte CHAT_TYPE = (byte) 0;
|
||||||
|
public static final byte SYSTEM_TYPE = (byte) 1;
|
||||||
|
public static final byte GAME_INFO_TYPE = (byte) 2;
|
||||||
|
|
||||||
|
private @Nullable String message;
|
||||||
|
private byte type;
|
||||||
|
private @Nullable UUID sender;
|
||||||
|
|
||||||
|
private ClientboundChatPacket() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientboundChatPacket(String message, byte type, UUID sender) {
|
||||||
|
this.message = message;
|
||||||
|
this.type = type;
|
||||||
|
this.sender = sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
message = ProtocolUtils.readString(buf);
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
|
type = buf.readByte();
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
|
sender = ProtocolUtils.readUuid(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
if (message == null) {
|
||||||
|
throw new IllegalStateException("Message is not specified");
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeString(buf, message);
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
|
buf.writeByte(type);
|
||||||
|
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
||||||
|
ProtocolUtils.writeUuid(buf, sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
if (message == null) {
|
||||||
|
throw new IllegalStateException("Message is not specified");
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getSenderUuid() {
|
||||||
|
return sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("message", this.message)
|
||||||
|
.add("type", this.type)
|
||||||
|
.add("sender", this.sender)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public class ClientboundDisconnectPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundDisconnectPacket> DECODER = PacketReader.method(ClientboundDisconnectPacket::new);
|
||||||
|
|
||||||
|
private @Nullable String reason;
|
||||||
|
|
||||||
|
public ClientboundDisconnectPacket() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientboundDisconnectPacket(String reason) {
|
||||||
|
this.reason = Preconditions.checkNotNull(reason, "reason");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
if (reason == null) {
|
||||||
|
throw new IllegalStateException("No reason specified");
|
||||||
|
}
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReason(@Nullable String reason) {
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
reason = ProtocolUtils.readString(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
if (reason == null) {
|
||||||
|
throw new IllegalStateException("No reason specified.");
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeString(buf, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClientboundDisconnectPacket create(Component component, ProtocolVersion version) {
|
||||||
|
Preconditions.checkNotNull(component, "component");
|
||||||
|
return new ClientboundDisconnectPacket(ProtocolUtils.getJsonChatSerializer(version).serialize(component));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("reason", this.reason)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,18 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet;
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
import static com.velocitypowered.proxy.connection.VelocityConstants.EMPTY_BYTE_ARRAY;
|
import static com.velocitypowered.proxy.connection.VelocityConstants.EMPTY_BYTE_ARRAY;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class EncryptionRequestPacket implements Packet {
|
public class ClientboundEncryptionRequestPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundEncryptionRequestPacket> DECODER = PacketReader.method(ClientboundEncryptionRequestPacket::new);
|
||||||
|
|
||||||
private String serverId = "";
|
private String serverId = "";
|
||||||
private byte[] publicKey = EMPTY_BYTE_ARRAY;
|
private byte[] publicKey = EMPTY_BYTE_ARRAY;
|
||||||
@@ -33,18 +35,10 @@ public class EncryptionRequestPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
return "EncryptionRequest{"
|
|
||||||
+ "publicKey=" + Arrays.toString(publicKey)
|
|
||||||
+ ", verifyToken=" + Arrays.toString(verifyToken)
|
|
||||||
+ '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
this.serverId = ProtocolUtils.readString(buf, 20);
|
this.serverId = ProtocolUtils.readString(buf, 20);
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
publicKey = ProtocolUtils.readByteArray(buf, 256);
|
publicKey = ProtocolUtils.readByteArray(buf, 256);
|
||||||
verifyToken = ProtocolUtils.readByteArray(buf, 16);
|
verifyToken = ProtocolUtils.readByteArray(buf, 16);
|
||||||
} else {
|
} else {
|
||||||
@@ -54,10 +48,10 @@ public class EncryptionRequestPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
ProtocolUtils.writeString(buf, this.serverId);
|
ProtocolUtils.writeString(buf, this.serverId);
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
ProtocolUtils.writeByteArray(buf, publicKey);
|
ProtocolUtils.writeByteArray(buf, publicKey);
|
||||||
ProtocolUtils.writeByteArray(buf, verifyToken);
|
ProtocolUtils.writeByteArray(buf, verifyToken);
|
||||||
} else {
|
} else {
|
||||||
@@ -67,7 +61,16 @@ public class EncryptionRequestPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(PacketHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("serverId", this.serverId)
|
||||||
|
.add("publicKey", this.publicKey)
|
||||||
|
.add("verifyToken", this.verifyToken)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import static com.velocitypowered.proxy.network.ProtocolUtils.writeString;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class ClientboundHeaderAndFooterPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundHeaderAndFooterPacket> DECODER = PacketReader.method(ClientboundHeaderAndFooterPacket::new);
|
||||||
|
|
||||||
|
private static final String EMPTY_COMPONENT = "{\"translate\":\"\"}";
|
||||||
|
private static final ClientboundHeaderAndFooterPacket RESET
|
||||||
|
= new ClientboundHeaderAndFooterPacket();
|
||||||
|
|
||||||
|
private final String header;
|
||||||
|
private final String footer;
|
||||||
|
|
||||||
|
public ClientboundHeaderAndFooterPacket() {
|
||||||
|
this(EMPTY_COMPONENT, EMPTY_COMPONENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientboundHeaderAndFooterPacket(String header, String footer) {
|
||||||
|
this.header = Preconditions.checkNotNull(header, "header");
|
||||||
|
this.footer = Preconditions.checkNotNull(footer, "footer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
writeString(buf, header);
|
||||||
|
writeString(buf, footer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFooter() {
|
||||||
|
return footer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClientboundHeaderAndFooterPacket reset() {
|
||||||
|
return RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("header", this.header)
|
||||||
|
.add("footer", this.footer)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,24 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet;
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
|
||||||
import com.velocitypowered.proxy.connection.registry.DimensionData;
|
import com.velocitypowered.proxy.connection.registry.DimensionData;
|
||||||
import com.velocitypowered.proxy.connection.registry.DimensionInfo;
|
import com.velocitypowered.proxy.connection.registry.DimensionInfo;
|
||||||
import com.velocitypowered.proxy.connection.registry.DimensionRegistry;
|
import com.velocitypowered.proxy.connection.registry.DimensionRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.kyori.adventure.nbt.BinaryTagTypes;
|
import net.kyori.adventure.nbt.BinaryTagTypes;
|
||||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||||
import net.kyori.adventure.nbt.ListBinaryTag;
|
import net.kyori.adventure.nbt.ListBinaryTag;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class JoinGamePacket implements Packet {
|
public class ClientboundJoinGamePacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundJoinGamePacket> DECODER = PacketReader.method(ClientboundJoinGamePacket::new);
|
||||||
|
|
||||||
private int entityId;
|
private int entityId;
|
||||||
private short gamemode;
|
private short gamemode;
|
||||||
@@ -34,140 +37,18 @@ public class JoinGamePacket implements Packet {
|
|||||||
private short previousGamemode; // 1.16+
|
private short previousGamemode; // 1.16+
|
||||||
private CompoundBinaryTag biomeRegistry; // 1.16.2+
|
private CompoundBinaryTag biomeRegistry; // 1.16.2+
|
||||||
|
|
||||||
public int getEntityId() {
|
public void withDimension(int dimension) {
|
||||||
return entityId;
|
this.dimension = dimension;
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntityId(int entityId) {
|
|
||||||
this.entityId = entityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getGamemode() {
|
|
||||||
return gamemode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGamemode(short gamemode) {
|
|
||||||
this.gamemode = gamemode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDimension() {
|
|
||||||
return dimension;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDimension(int dimension) {
|
public void setDimension(int dimension) {
|
||||||
this.dimension = dimension;
|
this.dimension = dimension;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getPartialHashedSeed() {
|
|
||||||
return partialHashedSeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getDifficulty() {
|
|
||||||
return difficulty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDifficulty(short difficulty) {
|
|
||||||
this.difficulty = difficulty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxPlayers() {
|
|
||||||
return maxPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxPlayers(int maxPlayers) {
|
|
||||||
this.maxPlayers = maxPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable String getLevelType() {
|
|
||||||
return levelType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLevelType(String levelType) {
|
|
||||||
this.levelType = levelType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getViewDistance() {
|
|
||||||
return viewDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setViewDistance(int viewDistance) {
|
|
||||||
this.viewDistance = viewDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReducedDebugInfo() {
|
|
||||||
return reducedDebugInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReducedDebugInfo(boolean reducedDebugInfo) {
|
|
||||||
this.reducedDebugInfo = reducedDebugInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DimensionInfo getDimensionInfo() {
|
|
||||||
return dimensionInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDimensionInfo(DimensionInfo dimensionInfo) {
|
|
||||||
this.dimensionInfo = dimensionInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DimensionRegistry getDimensionRegistry() {
|
|
||||||
return dimensionRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDimensionRegistry(DimensionRegistry dimensionRegistry) {
|
|
||||||
this.dimensionRegistry = dimensionRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getPreviousGamemode() {
|
|
||||||
return previousGamemode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPreviousGamemode(short previousGamemode) {
|
|
||||||
this.previousGamemode = previousGamemode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getIsHardcore() {
|
|
||||||
return isHardcore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsHardcore(boolean isHardcore) {
|
|
||||||
this.isHardcore = isHardcore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompoundBinaryTag getBiomeRegistry() {
|
|
||||||
return biomeRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBiomeRegistry(CompoundBinaryTag biomeRegistry) {
|
|
||||||
this.biomeRegistry = biomeRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DimensionData getCurrentDimensionData() {
|
|
||||||
return currentDimensionData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
return "JoinGame{"
|
|
||||||
+ "entityId=" + entityId
|
|
||||||
+ ", gamemode=" + gamemode
|
|
||||||
+ ", dimension=" + dimension
|
|
||||||
+ ", partialHashedSeed=" + partialHashedSeed
|
|
||||||
+ ", difficulty=" + difficulty
|
|
||||||
+ ", maxPlayers=" + maxPlayers
|
|
||||||
+ ", levelType='" + levelType + '\''
|
|
||||||
+ ", viewDistance=" + viewDistance
|
|
||||||
+ ", reducedDebugInfo=" + reducedDebugInfo
|
|
||||||
+ ", dimensionRegistry='" + dimensionRegistry + '\''
|
|
||||||
+ ", dimensionInfo='" + dimensionInfo + '\''
|
|
||||||
+ ", previousGamemode=" + previousGamemode
|
|
||||||
+ '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
this.entityId = buf.readInt();
|
this.entityId = buf.readInt();
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
this.isHardcore = buf.readBoolean();
|
this.isHardcore = buf.readBoolean();
|
||||||
this.gamemode = buf.readByte();
|
this.gamemode = buf.readByte();
|
||||||
} else {
|
} else {
|
||||||
@@ -177,12 +58,12 @@ public class JoinGamePacket implements Packet {
|
|||||||
}
|
}
|
||||||
String dimensionIdentifier = null;
|
String dimensionIdentifier = null;
|
||||||
String levelName = null;
|
String levelName = null;
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
this.previousGamemode = buf.readByte();
|
this.previousGamemode = buf.readByte();
|
||||||
ImmutableSet<String> levelNames = ImmutableSet.copyOf(ProtocolUtils.readStringArray(buf));
|
ImmutableSet<String> levelNames = ImmutableSet.copyOf(ProtocolUtils.readStringArray(buf));
|
||||||
CompoundBinaryTag registryContainer = ProtocolUtils.readCompoundTag(buf);
|
CompoundBinaryTag registryContainer = ProtocolUtils.readCompoundTag(buf);
|
||||||
ListBinaryTag dimensionRegistryContainer = null;
|
ListBinaryTag dimensionRegistryContainer = null;
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
dimensionRegistryContainer = registryContainer.getCompound("minecraft:dimension_type")
|
dimensionRegistryContainer = registryContainer.getCompound("minecraft:dimension_type")
|
||||||
.getList("value", BinaryTagTypes.COMPOUND);
|
.getList("value", BinaryTagTypes.COMPOUND);
|
||||||
this.biomeRegistry = registryContainer.getCompound("minecraft:worldgen/biome");
|
this.biomeRegistry = registryContainer.getCompound("minecraft:worldgen/biome");
|
||||||
@@ -193,7 +74,7 @@ public class JoinGamePacket implements Packet {
|
|||||||
ImmutableSet<DimensionData> readData =
|
ImmutableSet<DimensionData> readData =
|
||||||
DimensionRegistry.fromGameData(dimensionRegistryContainer, version);
|
DimensionRegistry.fromGameData(dimensionRegistryContainer, version);
|
||||||
this.dimensionRegistry = new DimensionRegistry(readData, levelNames);
|
this.dimensionRegistry = new DimensionRegistry(readData, levelNames);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
CompoundBinaryTag currentDimDataTag = ProtocolUtils.readCompoundTag(buf);
|
CompoundBinaryTag currentDimDataTag = ProtocolUtils.readCompoundTag(buf);
|
||||||
dimensionIdentifier = ProtocolUtils.readString(buf);
|
dimensionIdentifier = ProtocolUtils.readString(buf);
|
||||||
this.currentDimensionData = DimensionData.decodeBaseCompoundTag(currentDimDataTag, version)
|
this.currentDimensionData = DimensionData.decodeBaseCompoundTag(currentDimDataTag, version)
|
||||||
@@ -202,35 +83,35 @@ public class JoinGamePacket implements Packet {
|
|||||||
dimensionIdentifier = ProtocolUtils.readString(buf);
|
dimensionIdentifier = ProtocolUtils.readString(buf);
|
||||||
levelName = ProtocolUtils.readString(buf);
|
levelName = ProtocolUtils.readString(buf);
|
||||||
}
|
}
|
||||||
} else if (version.compareTo(ProtocolVersion.MINECRAFT_1_9_1) >= 0) {
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_9_1)) {
|
||||||
this.dimension = buf.readInt();
|
this.dimension = buf.readInt();
|
||||||
} else {
|
} else {
|
||||||
this.dimension = buf.readByte();
|
this.dimension = buf.readByte();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13_2) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_13_2)) {
|
||||||
this.difficulty = buf.readUnsignedByte();
|
this.difficulty = buf.readUnsignedByte();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
this.partialHashedSeed = buf.readLong();
|
this.partialHashedSeed = buf.readLong();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
this.maxPlayers = ProtocolUtils.readVarInt(buf);
|
this.maxPlayers = ProtocolUtils.readVarInt(buf);
|
||||||
} else {
|
} else {
|
||||||
this.maxPlayers = buf.readUnsignedByte();
|
this.maxPlayers = buf.readUnsignedByte();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) < 0) {
|
if (version.lt(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
this.levelType = ProtocolUtils.readString(buf, 16);
|
this.levelType = ProtocolUtils.readString(buf, 16);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_14) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_14)) {
|
||||||
this.viewDistance = ProtocolUtils.readVarInt(buf);
|
this.viewDistance = ProtocolUtils.readVarInt(buf);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
this.reducedDebugInfo = buf.readBoolean();
|
this.reducedDebugInfo = buf.readBoolean();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
this.showRespawnScreen = buf.readBoolean();
|
this.showRespawnScreen = buf.readBoolean();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
boolean isDebug = buf.readBoolean();
|
boolean isDebug = buf.readBoolean();
|
||||||
boolean isFlat = buf.readBoolean();
|
boolean isFlat = buf.readBoolean();
|
||||||
this.dimensionInfo = new DimensionInfo(dimensionIdentifier, levelName, isFlat, isDebug);
|
this.dimensionInfo = new DimensionInfo(dimensionIdentifier, levelName, isFlat, isDebug);
|
||||||
@@ -238,20 +119,20 @@ public class JoinGamePacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
buf.writeInt(entityId);
|
buf.writeInt(entityId);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
buf.writeBoolean(isHardcore);
|
buf.writeBoolean(isHardcore);
|
||||||
buf.writeByte(gamemode);
|
buf.writeByte(gamemode);
|
||||||
} else {
|
} else {
|
||||||
buf.writeByte(isHardcore ? gamemode | 0x8 : gamemode);
|
buf.writeByte(isHardcore ? gamemode | 0x8 : gamemode);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
buf.writeByte(previousGamemode);
|
buf.writeByte(previousGamemode);
|
||||||
ProtocolUtils.writeStringArray(buf, dimensionRegistry.getLevelNames().toArray(new String[0]));
|
ProtocolUtils.writeStringArray(buf, dimensionRegistry.getLevelNames().toArray(new String[0]));
|
||||||
CompoundBinaryTag.Builder registryContainer = CompoundBinaryTag.builder();
|
CompoundBinaryTag.Builder registryContainer = CompoundBinaryTag.builder();
|
||||||
ListBinaryTag encodedDimensionRegistry = dimensionRegistry.encodeRegistry(version);
|
ListBinaryTag encodedDimensionRegistry = dimensionRegistry.encodeRegistry(version);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
CompoundBinaryTag.Builder dimensionRegistryEntry = CompoundBinaryTag.builder();
|
CompoundBinaryTag.Builder dimensionRegistryEntry = CompoundBinaryTag.builder();
|
||||||
dimensionRegistryEntry.putString("type", "minecraft:dimension_type");
|
dimensionRegistryEntry.putString("type", "minecraft:dimension_type");
|
||||||
dimensionRegistryEntry.put("value", encodedDimensionRegistry);
|
dimensionRegistryEntry.put("value", encodedDimensionRegistry);
|
||||||
@@ -261,52 +142,134 @@ public class JoinGamePacket implements Packet {
|
|||||||
registryContainer.put("dimension", encodedDimensionRegistry);
|
registryContainer.put("dimension", encodedDimensionRegistry);
|
||||||
}
|
}
|
||||||
ProtocolUtils.writeCompoundTag(buf, registryContainer.build());
|
ProtocolUtils.writeCompoundTag(buf, registryContainer.build());
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
ProtocolUtils.writeCompoundTag(buf, currentDimensionData.serializeDimensionDetails());
|
ProtocolUtils.writeCompoundTag(buf, currentDimensionData.serializeDimensionDetails());
|
||||||
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
||||||
} else {
|
} else {
|
||||||
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
||||||
ProtocolUtils.writeString(buf, dimensionInfo.getLevelName());
|
ProtocolUtils.writeString(buf, dimensionInfo.getLevelName());
|
||||||
}
|
}
|
||||||
} else if (version.compareTo(ProtocolVersion.MINECRAFT_1_9_1) >= 0) {
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_9_1)) {
|
||||||
buf.writeInt(dimension);
|
buf.writeInt(dimension);
|
||||||
} else {
|
} else {
|
||||||
buf.writeByte(dimension);
|
buf.writeByte(dimension);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13_2) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_13_2)) {
|
||||||
buf.writeByte(difficulty);
|
buf.writeByte(difficulty);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
buf.writeLong(partialHashedSeed);
|
buf.writeLong(partialHashedSeed);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
ProtocolUtils.writeVarInt(buf, maxPlayers);
|
ProtocolUtils.writeVarInt(buf, maxPlayers);
|
||||||
} else {
|
} else {
|
||||||
buf.writeByte(maxPlayers);
|
buf.writeByte(maxPlayers);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) < 0) {
|
if (version.lt(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
if (levelType == null) {
|
if (levelType == null) {
|
||||||
throw new IllegalStateException("No level type specified.");
|
throw new IllegalStateException("No level type specified.");
|
||||||
}
|
}
|
||||||
ProtocolUtils.writeString(buf, levelType);
|
ProtocolUtils.writeString(buf, levelType);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_14) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_14)) {
|
||||||
ProtocolUtils.writeVarInt(buf, viewDistance);
|
ProtocolUtils.writeVarInt(buf, viewDistance);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
buf.writeBoolean(reducedDebugInfo);
|
buf.writeBoolean(reducedDebugInfo);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
buf.writeBoolean(showRespawnScreen);
|
buf.writeBoolean(showRespawnScreen);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
buf.writeBoolean(dimensionInfo.isDebugType());
|
buf.writeBoolean(dimensionInfo.isDebugType());
|
||||||
buf.writeBoolean(dimensionInfo.isFlat());
|
buf.writeBoolean(dimensionInfo.isFlat());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getEntityId() {
|
||||||
|
return entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getGamemode() {
|
||||||
|
return gamemode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDimension() {
|
||||||
|
return dimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPartialHashedSeed() {
|
||||||
|
return partialHashedSeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getDifficulty() {
|
||||||
|
return difficulty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxPlayers() {
|
||||||
|
return maxPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getLevelType() {
|
||||||
|
return levelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getViewDistance() {
|
||||||
|
return viewDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReducedDebugInfo() {
|
||||||
|
return reducedDebugInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DimensionInfo getDimensionInfo() {
|
||||||
|
return dimensionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DimensionRegistry getDimensionRegistry() {
|
||||||
|
return dimensionRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getPreviousGamemode() {
|
||||||
|
return previousGamemode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getIsHardcore() {
|
||||||
|
return isHardcore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundBinaryTag getBiomeRegistry() {
|
||||||
|
return biomeRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DimensionData getCurrentDimensionData() {
|
||||||
|
return currentDimensionData;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(PacketHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("entityId", this.entityId)
|
||||||
|
.add("gamemode", this.gamemode)
|
||||||
|
.add("dimension", this.dimension)
|
||||||
|
.add("partialHashedSeed", this.partialHashedSeed)
|
||||||
|
.add("difficulty", this.difficulty)
|
||||||
|
.add("isHardcore", this.isHardcore)
|
||||||
|
.add("maxPlayers", this.maxPlayers)
|
||||||
|
.add("levelType", this.levelType)
|
||||||
|
.add("viewDistance", this.viewDistance)
|
||||||
|
.add("reducedDebugInfo", this.reducedDebugInfo)
|
||||||
|
.add("showRespawnScreen", this.showRespawnScreen)
|
||||||
|
.add("dimensionRegistry", this.dimensionRegistry)
|
||||||
|
.add("dimensionInfo", this.dimensionInfo)
|
||||||
|
.add("currentDimensionData", this.currentDimensionData)
|
||||||
|
.add("previousGamemode", this.previousGamemode)
|
||||||
|
.add("biomeRegistry", this.biomeRegistry)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.network.packet.AbstractKeepAlivePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
|
||||||
|
public class ClientboundKeepAlivePacket extends AbstractKeepAlivePacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundKeepAlivePacket> DECODER = decoder(ClientboundKeepAlivePacket::new);
|
||||||
|
|
||||||
|
public ClientboundKeepAlivePacket(final long randomId) {
|
||||||
|
super(randomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.DefaultByteBufHolder;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public class ClientboundLoginPluginMessagePacket extends DefaultByteBufHolder implements Packet {
|
||||||
|
public static final PacketReader<ClientboundLoginPluginMessagePacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final int id = ProtocolUtils.readVarInt(buf);
|
||||||
|
final String channel = ProtocolUtils.readString(buf);
|
||||||
|
final ByteBuf data;
|
||||||
|
if (buf.isReadable()) {
|
||||||
|
data = buf.readSlice(buf.readableBytes());
|
||||||
|
} else {
|
||||||
|
data = Unpooled.EMPTY_BUFFER;
|
||||||
|
}
|
||||||
|
return new ClientboundLoginPluginMessagePacket(id, channel, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final @Nullable String channel;
|
||||||
|
|
||||||
|
public ClientboundLoginPluginMessagePacket(int id, @Nullable String channel, ByteBuf data) {
|
||||||
|
super(data);
|
||||||
|
this.id = id;
|
||||||
|
this.channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
ProtocolUtils.writeVarInt(buf, id);
|
||||||
|
if (channel == null) {
|
||||||
|
throw new IllegalStateException("Channel is not specified!");
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeString(buf, channel);
|
||||||
|
buf.writeBytes(content());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChannel() {
|
||||||
|
if (channel == null) {
|
||||||
|
throw new IllegalStateException("Channel is not specified!");
|
||||||
|
}
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object other) {
|
||||||
|
if (this == other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other == null || this.getClass() != other.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final ClientboundLoginPluginMessagePacket that = (ClientboundLoginPluginMessagePacket) other;
|
||||||
|
return this.id == that.id
|
||||||
|
&& Objects.equals(this.channel, that.channel)
|
||||||
|
&& super.equals(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(this.id, this.channel, super.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("id", this.id)
|
||||||
|
.add("channel", this.channel)
|
||||||
|
.add("data", this.contentToString())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet;
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.proxy.player.TabListEntry;
|
import com.velocitypowered.api.proxy.player.TabListEntry;
|
||||||
import com.velocitypowered.api.util.GameProfile;
|
import com.velocitypowered.api.util.GameProfile;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -16,7 +18,8 @@ import net.kyori.adventure.text.Component;
|
|||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class PlayerListItemPacket implements Packet {
|
public class ClientboundPlayerListItemPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundPlayerListItemPacket> DECODER = PacketReader.method(ClientboundPlayerListItemPacket::new);
|
||||||
|
|
||||||
public static final int ADD_PLAYER = 0;
|
public static final int ADD_PLAYER = 0;
|
||||||
public static final int UPDATE_GAMEMODE = 1;
|
public static final int UPDATE_GAMEMODE = 1;
|
||||||
@@ -26,12 +29,12 @@ public class PlayerListItemPacket implements Packet {
|
|||||||
private int action;
|
private int action;
|
||||||
private final List<Item> items = new ArrayList<>();
|
private final List<Item> items = new ArrayList<>();
|
||||||
|
|
||||||
public PlayerListItemPacket(int action, List<Item> items) {
|
public ClientboundPlayerListItemPacket(int action, List<Item> items) {
|
||||||
this.action = action;
|
this.action = action;
|
||||||
this.items.addAll(items);
|
this.items.addAll(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerListItemPacket() {
|
public ClientboundPlayerListItemPacket() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAction() {
|
public int getAction() {
|
||||||
@@ -43,8 +46,8 @@ public class PlayerListItemPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
action = ProtocolUtils.readVarInt(buf);
|
action = ProtocolUtils.readVarInt(buf);
|
||||||
int length = ProtocolUtils.readVarInt(buf);
|
int length = ProtocolUtils.readVarInt(buf);
|
||||||
|
|
||||||
@@ -93,8 +96,8 @@ public class PlayerListItemPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
ProtocolUtils.writeVarInt(buf, action);
|
ProtocolUtils.writeVarInt(buf, action);
|
||||||
ProtocolUtils.writeVarInt(buf, items.size());
|
ProtocolUtils.writeVarInt(buf, items.size());
|
||||||
for (Item item : items) {
|
for (Item item : items) {
|
||||||
@@ -144,7 +147,7 @@ public class PlayerListItemPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(PacketHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +160,14 @@ public class PlayerListItemPacket implements Packet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("action", this.action)
|
||||||
|
.add("items", this.items)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public static class Item {
|
public static class Item {
|
||||||
|
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class ClientboundPluginMessagePacket extends AbstractPluginMessagePacket<ClientboundPluginMessagePacket> implements Packet {
|
||||||
|
public static final Factory<ClientboundPluginMessagePacket> FACTORY = ClientboundPluginMessagePacket::new;
|
||||||
|
public static final PacketReader<ClientboundPluginMessagePacket> DECODER = decoder(FACTORY);
|
||||||
|
|
||||||
|
public ClientboundPluginMessagePacket(final String channel, final ByteBuf backing) {
|
||||||
|
super(channel, backing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientboundPluginMessagePacket replace(ByteBuf content) {
|
||||||
|
return new ClientboundPluginMessagePacket(this.channel, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class ClientboundResourcePackRequestPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundResourcePackRequestPacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final String url = ProtocolUtils.readString(buf);
|
||||||
|
final String hash = ProtocolUtils.readString(buf);
|
||||||
|
return new ClientboundResourcePackRequestPacket(url, hash);
|
||||||
|
};
|
||||||
|
|
||||||
|
private final String url;
|
||||||
|
private final String hash;
|
||||||
|
|
||||||
|
public ClientboundResourcePackRequestPacket(final String url, final String hash) {
|
||||||
|
this.url = Objects.requireNonNull(url, "url");
|
||||||
|
this.hash = Objects.requireNonNull(hash, "hash");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion protocolVersion) {
|
||||||
|
ProtocolUtils.writeString(buf, url);
|
||||||
|
ProtocolUtils.writeString(buf, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHash() {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("url", this.url)
|
||||||
|
.add("hash", this.hash)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,19 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet;
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
|
||||||
import com.velocitypowered.proxy.connection.registry.DimensionData;
|
import com.velocitypowered.proxy.connection.registry.DimensionData;
|
||||||
import com.velocitypowered.proxy.connection.registry.DimensionInfo;
|
import com.velocitypowered.proxy.connection.registry.DimensionInfo;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||||
|
|
||||||
public class RespawnPacket implements Packet {
|
public class ClientboundRespawnPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundRespawnPacket> DECODER = PacketReader.method(ClientboundRespawnPacket::new);
|
||||||
|
|
||||||
private int dimension;
|
private int dimension;
|
||||||
private long partialHashedSeed;
|
private long partialHashedSeed;
|
||||||
@@ -22,12 +25,12 @@ public class RespawnPacket implements Packet {
|
|||||||
private short previousGamemode; // 1.16+
|
private short previousGamemode; // 1.16+
|
||||||
private DimensionData currentDimensionData; // 1.16.2+
|
private DimensionData currentDimensionData; // 1.16.2+
|
||||||
|
|
||||||
public RespawnPacket() {
|
public ClientboundRespawnPacket() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public RespawnPacket(int dimension, long partialHashedSeed, short difficulty, short gamemode,
|
public ClientboundRespawnPacket(int dimension, long partialHashedSeed, short difficulty, short gamemode,
|
||||||
String levelType, boolean shouldKeepPlayerData, DimensionInfo dimensionInfo,
|
String levelType, boolean shouldKeepPlayerData, DimensionInfo dimensionInfo,
|
||||||
short previousGamemode, DimensionData currentDimensionData) {
|
short previousGamemode, DimensionData currentDimensionData) {
|
||||||
this.dimension = dimension;
|
this.dimension = dimension;
|
||||||
this.partialHashedSeed = partialHashedSeed;
|
this.partialHashedSeed = partialHashedSeed;
|
||||||
this.difficulty = difficulty;
|
this.difficulty = difficulty;
|
||||||
@@ -96,27 +99,11 @@ public class RespawnPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
return "Respawn{"
|
|
||||||
+ "dimension=" + dimension
|
|
||||||
+ ", partialHashedSeed=" + partialHashedSeed
|
|
||||||
+ ", difficulty=" + difficulty
|
|
||||||
+ ", gamemode=" + gamemode
|
|
||||||
+ ", levelType='" + levelType + '\''
|
|
||||||
+ ", shouldKeepPlayerData=" + shouldKeepPlayerData
|
|
||||||
+ ", dimensionRegistryName='" + dimensionInfo.toString() + '\''
|
|
||||||
+ ", dimensionInfo=" + dimensionInfo
|
|
||||||
+ ", previousGamemode=" + previousGamemode
|
|
||||||
+ ", dimensionData=" + currentDimensionData
|
|
||||||
+ '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
String dimensionIdentifier = null;
|
String dimensionIdentifier = null;
|
||||||
String levelName = null;
|
String levelName = null;
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
CompoundBinaryTag dimDataTag = ProtocolUtils.readCompoundTag(buf);
|
CompoundBinaryTag dimDataTag = ProtocolUtils.readCompoundTag(buf);
|
||||||
dimensionIdentifier = ProtocolUtils.readString(buf);
|
dimensionIdentifier = ProtocolUtils.readString(buf);
|
||||||
this.currentDimensionData = DimensionData.decodeBaseCompoundTag(dimDataTag, version)
|
this.currentDimensionData = DimensionData.decodeBaseCompoundTag(dimDataTag, version)
|
||||||
@@ -128,14 +115,14 @@ public class RespawnPacket implements Packet {
|
|||||||
} else {
|
} else {
|
||||||
this.dimension = buf.readInt();
|
this.dimension = buf.readInt();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13_2) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_13_2)) {
|
||||||
this.difficulty = buf.readUnsignedByte();
|
this.difficulty = buf.readUnsignedByte();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
this.partialHashedSeed = buf.readLong();
|
this.partialHashedSeed = buf.readLong();
|
||||||
}
|
}
|
||||||
this.gamemode = buf.readByte();
|
this.gamemode = buf.readByte();
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
this.previousGamemode = buf.readByte();
|
this.previousGamemode = buf.readByte();
|
||||||
boolean isDebug = buf.readBoolean();
|
boolean isDebug = buf.readBoolean();
|
||||||
boolean isFlat = buf.readBoolean();
|
boolean isFlat = buf.readBoolean();
|
||||||
@@ -147,9 +134,9 @@ public class RespawnPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
ProtocolUtils.writeCompoundTag(buf, currentDimensionData.serializeDimensionDetails());
|
ProtocolUtils.writeCompoundTag(buf, currentDimensionData.serializeDimensionDetails());
|
||||||
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
||||||
} else {
|
} else {
|
||||||
@@ -159,14 +146,14 @@ public class RespawnPacket implements Packet {
|
|||||||
} else {
|
} else {
|
||||||
buf.writeInt(dimension);
|
buf.writeInt(dimension);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13_2) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_13_2)) {
|
||||||
buf.writeByte(difficulty);
|
buf.writeByte(difficulty);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
buf.writeLong(partialHashedSeed);
|
buf.writeLong(partialHashedSeed);
|
||||||
}
|
}
|
||||||
buf.writeByte(gamemode);
|
buf.writeByte(gamemode);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
buf.writeByte(previousGamemode);
|
buf.writeByte(previousGamemode);
|
||||||
buf.writeBoolean(dimensionInfo.isDebugType());
|
buf.writeBoolean(dimensionInfo.isDebugType());
|
||||||
buf.writeBoolean(dimensionInfo.isFlat());
|
buf.writeBoolean(dimensionInfo.isFlat());
|
||||||
@@ -177,7 +164,22 @@ public class RespawnPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(PacketHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("dimension", this.dimension)
|
||||||
|
.add("partialHashedSeed", this.partialHashedSeed)
|
||||||
|
.add("difficulty", this.difficulty)
|
||||||
|
.add("gamemode", this.gamemode)
|
||||||
|
.add("levelType", this.levelType)
|
||||||
|
.add("shouldKeepPlayerData", this.shouldKeepPlayerData)
|
||||||
|
.add("dimensionInfo", this.dimensionInfo)
|
||||||
|
.add("previousGamemode", this.previousGamemode)
|
||||||
|
.add("currentDimensionData", this.currentDimensionData)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.api.util.UuidUtils;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ClientboundServerLoginSuccessPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundServerLoginSuccessPacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final UUID uuid;
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
|
uuid = ProtocolUtils.readUuidIntArray(buf);
|
||||||
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_7_6)) {
|
||||||
|
uuid = UUID.fromString(ProtocolUtils.readString(buf, 36));
|
||||||
|
} else {
|
||||||
|
uuid = UuidUtils.fromUndashed(ProtocolUtils.readString(buf, 32));
|
||||||
|
}
|
||||||
|
final String username = ProtocolUtils.readString(buf, 16);
|
||||||
|
return new ClientboundServerLoginSuccessPacket(uuid, username);
|
||||||
|
};
|
||||||
|
|
||||||
|
private final UUID uuid;
|
||||||
|
private final String username;
|
||||||
|
|
||||||
|
public ClientboundServerLoginSuccessPacket(final UUID uuid, final String username) {
|
||||||
|
this.uuid = Objects.requireNonNull(uuid, "uuid");
|
||||||
|
this.username = Objects.requireNonNull(username, "username");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
|
ProtocolUtils.writeUuidIntArray(buf, uuid);
|
||||||
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_7_6)) {
|
||||||
|
ProtocolUtils.writeString(buf, uuid.toString());
|
||||||
|
} else {
|
||||||
|
ProtocolUtils.writeString(buf, UuidUtils.toUndashed(uuid));
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeString(buf, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("uuid", this.uuid)
|
||||||
|
.add("username", this.username)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class ClientboundSetCompressionPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundSetCompressionPacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final int threshold = ProtocolUtils.readVarInt(buf);
|
||||||
|
return new ClientboundSetCompressionPacket(threshold);
|
||||||
|
};
|
||||||
|
|
||||||
|
private final int threshold;
|
||||||
|
|
||||||
|
public ClientboundSetCompressionPacket(int threshold) {
|
||||||
|
this.threshold = threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
ProtocolUtils.writeVarInt(buf, threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getThreshold() {
|
||||||
|
return threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("threshold", this.threshold)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.network.packet.AbstractStatusPingPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
|
||||||
|
public class ClientboundStatusPingPacket extends AbstractStatusPingPacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundStatusPingPacket> DECODER = decoder(ClientboundStatusPingPacket::new);
|
||||||
|
|
||||||
|
public ClientboundStatusPingPacket(final long randomId) {
|
||||||
|
super(randomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public class ClientboundStatusResponsePacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundStatusResponsePacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final String status = ProtocolUtils.readString(buf, Short.MAX_VALUE);
|
||||||
|
return new ClientboundStatusResponsePacket(status);
|
||||||
|
};
|
||||||
|
|
||||||
|
private final @Nullable CharSequence status;
|
||||||
|
|
||||||
|
public ClientboundStatusResponsePacket(CharSequence status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
if (status == null) {
|
||||||
|
throw new IllegalStateException("Status is not specified");
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeString(buf, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
if (status == null) {
|
||||||
|
throw new IllegalStateException("Status is not specified");
|
||||||
|
}
|
||||||
|
return status.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("status", this.status)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet;
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
|
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class TabCompleteResponsePacket implements Packet {
|
public class ClientboundTabCompleteResponsePacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundTabCompleteResponsePacket> DECODER = PacketReader.method(ClientboundTabCompleteResponsePacket::new);
|
||||||
|
|
||||||
private int transactionId;
|
private int transactionId;
|
||||||
private int start;
|
private int start;
|
||||||
@@ -50,18 +50,8 @@ public class TabCompleteResponsePacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
return "TabCompleteResponse{"
|
if (version.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
+ "transactionId=" + transactionId
|
|
||||||
+ ", start=" + start
|
|
||||||
+ ", length=" + length
|
|
||||||
+ ", offers=" + offers
|
|
||||||
+ '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
if (version.compareTo(MINECRAFT_1_13) >= 0) {
|
|
||||||
this.transactionId = ProtocolUtils.readVarInt(buf);
|
this.transactionId = ProtocolUtils.readVarInt(buf);
|
||||||
this.start = ProtocolUtils.readVarInt(buf);
|
this.start = ProtocolUtils.readVarInt(buf);
|
||||||
this.length = ProtocolUtils.readVarInt(buf);
|
this.length = ProtocolUtils.readVarInt(buf);
|
||||||
@@ -81,8 +71,8 @@ public class TabCompleteResponsePacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(MINECRAFT_1_13) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
ProtocolUtils.writeVarInt(buf, this.transactionId);
|
ProtocolUtils.writeVarInt(buf, this.transactionId);
|
||||||
ProtocolUtils.writeVarInt(buf, this.start);
|
ProtocolUtils.writeVarInt(buf, this.start);
|
||||||
ProtocolUtils.writeVarInt(buf, this.length);
|
ProtocolUtils.writeVarInt(buf, this.length);
|
||||||
@@ -104,10 +94,20 @@ public class TabCompleteResponsePacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(PacketHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("transactionId", this.transactionId)
|
||||||
|
.add("start", this.start)
|
||||||
|
.add("length", this.length)
|
||||||
|
.add("offers", this.offers)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public static class Offer implements Comparable<Offer> {
|
public static class Offer implements Comparable<Offer> {
|
||||||
private final String text;
|
private final String text;
|
||||||
private final @Nullable Component tooltip;
|
private final @Nullable Component tooltip;
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.google.common.primitives.Ints;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import com.velocitypowered.proxy.util.DurationUtils;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import net.kyori.adventure.title.Title;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public class ClientboundTitlePacket implements Packet {
|
||||||
|
public static final PacketReader<ClientboundTitlePacket> DECODER = PacketReader.unsupported();
|
||||||
|
|
||||||
|
public static ClientboundTitlePacket hide(final ProtocolVersion version) {
|
||||||
|
return version.gte(ProtocolVersion.MINECRAFT_1_11)
|
||||||
|
? Instances.HIDE
|
||||||
|
: Instances.HIDE_OLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClientboundTitlePacket reset(final ProtocolVersion version) {
|
||||||
|
return version.gte(ProtocolVersion.MINECRAFT_1_11)
|
||||||
|
? Instances.RESET
|
||||||
|
: Instances.RESET_OLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClientboundTitlePacket times(final ProtocolVersion version, final Title.Times times) {
|
||||||
|
final int action = version.gte(ProtocolVersion.MINECRAFT_1_11)
|
||||||
|
? SET_TIMES
|
||||||
|
: SET_TIMES_OLD;
|
||||||
|
return new ClientboundTitlePacket(
|
||||||
|
action,
|
||||||
|
(int) DurationUtils.toTicks(times.fadeIn()),
|
||||||
|
(int) DurationUtils.toTicks(times.stay()),
|
||||||
|
(int) DurationUtils.toTicks(times.fadeOut())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int SET_TITLE = 0;
|
||||||
|
public static final int SET_SUBTITLE = 1;
|
||||||
|
public static final int SET_ACTION_BAR = 2;
|
||||||
|
public static final int SET_TIMES = 3;
|
||||||
|
public static final int HIDE = 4;
|
||||||
|
public static final int RESET = 5;
|
||||||
|
|
||||||
|
public static final int SET_TIMES_OLD = 2;
|
||||||
|
public static final int HIDE_OLD = 3;
|
||||||
|
public static final int RESET_OLD = 4;
|
||||||
|
|
||||||
|
private final int action;
|
||||||
|
private final @Nullable String component;
|
||||||
|
private final int fadeIn;
|
||||||
|
private final int stay;
|
||||||
|
private final int fadeOut;
|
||||||
|
|
||||||
|
private ClientboundTitlePacket(final int action) {
|
||||||
|
checkAction(action, HIDE, RESET, HIDE_OLD, RESET_OLD);
|
||||||
|
this.action = action;
|
||||||
|
this.component = null;
|
||||||
|
this.fadeIn = -1;
|
||||||
|
this.stay = -1;
|
||||||
|
this.fadeOut = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientboundTitlePacket(final int action, final String component) {
|
||||||
|
checkAction(action, SET_TITLE, SET_SUBTITLE, SET_ACTION_BAR);
|
||||||
|
this.action = action;
|
||||||
|
this.component = component;
|
||||||
|
this.fadeIn = -1;
|
||||||
|
this.stay = -1;
|
||||||
|
this.fadeOut = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientboundTitlePacket(final int action, final int fadeIn, final int stay, final int fadeOut) {
|
||||||
|
checkAction(action, SET_TIMES, SET_TIMES_OLD);
|
||||||
|
this.action = action;
|
||||||
|
this.component = null;
|
||||||
|
this.fadeIn = fadeIn;
|
||||||
|
this.stay = stay;
|
||||||
|
this.fadeOut = fadeOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkAction(final int action, final int... validActions) {
|
||||||
|
if (!Ints.contains(validActions, action)) {
|
||||||
|
throw new IllegalArgumentException("Invalid action " + action + ", expected one of: " + Arrays.toString(validActions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
ProtocolUtils.writeVarInt(buf, action);
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_11)) {
|
||||||
|
// 1.11+ shifted the action enum by 1 to handle the action bar
|
||||||
|
switch (action) {
|
||||||
|
case SET_TITLE:
|
||||||
|
case SET_SUBTITLE:
|
||||||
|
case SET_ACTION_BAR:
|
||||||
|
if (component == null) {
|
||||||
|
throw new IllegalStateException("No component found for " + action);
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeString(buf, component);
|
||||||
|
break;
|
||||||
|
case SET_TIMES:
|
||||||
|
buf.writeInt(fadeIn);
|
||||||
|
buf.writeInt(stay);
|
||||||
|
buf.writeInt(fadeOut);
|
||||||
|
break;
|
||||||
|
case HIDE:
|
||||||
|
case RESET:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unknown action " + action);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (action) {
|
||||||
|
case SET_TITLE:
|
||||||
|
case SET_SUBTITLE:
|
||||||
|
if (component == null) {
|
||||||
|
throw new IllegalStateException("No component found for " + action);
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeString(buf, component);
|
||||||
|
break;
|
||||||
|
case SET_TIMES_OLD:
|
||||||
|
buf.writeInt(fadeIn);
|
||||||
|
buf.writeInt(stay);
|
||||||
|
buf.writeInt(fadeOut);
|
||||||
|
break;
|
||||||
|
case HIDE_OLD:
|
||||||
|
case RESET_OLD:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unknown action " + action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable String getComponent() {
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFadeIn() {
|
||||||
|
return fadeIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStay() {
|
||||||
|
return stay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFadeOut() {
|
||||||
|
return fadeOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("action", this.action)
|
||||||
|
.add("component", this.component)
|
||||||
|
.add("fadeIn", this.fadeIn)
|
||||||
|
.add("stay", this.stay)
|
||||||
|
.add("fadeOut", this.fadeOut)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Instances {
|
||||||
|
public static final ClientboundTitlePacket HIDE
|
||||||
|
= new ClientboundTitlePacket(ClientboundTitlePacket.HIDE);
|
||||||
|
public static final ClientboundTitlePacket RESET
|
||||||
|
= new ClientboundTitlePacket(ClientboundTitlePacket.RESET);
|
||||||
|
|
||||||
|
public static final ClientboundTitlePacket HIDE_OLD = new ClientboundTitlePacket(ClientboundTitlePacket.HIDE_OLD);
|
||||||
|
public static final ClientboundTitlePacket RESET_OLD = new ClientboundTitlePacket(ClientboundTitlePacket.RESET_OLD);
|
||||||
|
|
||||||
|
private Instances() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet.legacy;
|
package com.velocitypowered.proxy.network.packet.legacy;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||||
import com.velocitypowered.api.proxy.server.ServerPing.Players;
|
import com.velocitypowered.api.proxy.server.ServerPing.Players;
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacyping.LegacyMinecraftPingVersion;
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
|
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
|
||||||
|
|
||||||
public class LegacyDisconnectPacket {
|
public class LegacyDisconnectPacket implements LegacyPacket {
|
||||||
|
|
||||||
private static final ServerPing.Players FAKE_PLAYERS = new ServerPing.Players(0, 0,
|
private static final ServerPing.Players FAKE_PLAYERS = new ServerPing.Players(0, 0,
|
||||||
ImmutableList.of());
|
ImmutableList.of());
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.legacy;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class LegacyHandshakePacket implements LegacyPacket, Packet {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet.legacyping;
|
package com.velocitypowered.proxy.network.packet.legacy;
|
||||||
|
|
||||||
public enum LegacyMinecraftPingVersion {
|
public enum LegacyMinecraftPingVersion {
|
||||||
MINECRAFT_1_3,
|
MINECRAFT_1_3,
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.legacy;
|
||||||
|
|
||||||
|
public interface LegacyPacket {
|
||||||
|
}
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet.legacy;
|
package com.velocitypowered.proxy.network.packet.legacy;
|
||||||
|
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacyping.LegacyMinecraftPingVersion;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class LegacyPingPacket implements Packet {
|
public class LegacyPingPacket implements LegacyPacket, Packet {
|
||||||
|
|
||||||
private final LegacyMinecraftPingVersion version;
|
private final LegacyMinecraftPingVersion version;
|
||||||
private final @Nullable InetSocketAddress vhost;
|
private final @Nullable InetSocketAddress vhost;
|
||||||
@@ -24,6 +23,16 @@ public class LegacyPingPacket implements Packet {
|
|||||||
this.vhost = vhost;
|
this.vhost = vhost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
public LegacyMinecraftPingVersion getVersion() {
|
public LegacyMinecraftPingVersion getVersion() {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
@@ -31,19 +40,4 @@ public class LegacyPingPacket implements Packet {
|
|||||||
public @Nullable InetSocketAddress getVhost() {
|
public @Nullable InetSocketAddress getVhost() {
|
||||||
return vhost;
|
return vhost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
|
||||||
return handler.handle(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class ServerboundChatPacket implements Packet {
|
||||||
|
public static final PacketReader<ServerboundChatPacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final String message = ProtocolUtils.readString(buf);
|
||||||
|
return new ServerboundChatPacket(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final int MAX_MESSAGE_LENGTH = 256;
|
||||||
|
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
public ServerboundChatPacket(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
ProtocolUtils.writeString(buf, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("message", this.message)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,17 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet;
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class ClientSettingsPacket implements Packet {
|
public class ServerboundClientSettingsPacket implements Packet {
|
||||||
|
public static final PacketReader<ServerboundClientSettingsPacket> DECODER = PacketReader.method(ServerboundClientSettingsPacket::new);
|
||||||
|
|
||||||
private @Nullable String locale;
|
private @Nullable String locale;
|
||||||
private byte viewDistance;
|
private byte viewDistance;
|
||||||
@@ -18,11 +21,11 @@ public class ClientSettingsPacket implements Packet {
|
|||||||
private short skinParts;
|
private short skinParts;
|
||||||
private int mainHand;
|
private int mainHand;
|
||||||
|
|
||||||
public ClientSettingsPacket() {
|
public ServerboundClientSettingsPacket() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientSettingsPacket(String locale, byte viewDistance, int chatVisibility, boolean chatColors,
|
public ServerboundClientSettingsPacket(String locale, byte viewDistance, int chatVisibility, boolean chatColors,
|
||||||
short skinParts, int mainHand) {
|
short skinParts, int mainHand) {
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
this.viewDistance = viewDistance;
|
this.viewDistance = viewDistance;
|
||||||
this.chatVisibility = chatVisibility;
|
this.chatVisibility = chatVisibility;
|
||||||
@@ -31,6 +34,50 @@ public class ClientSettingsPacket implements Packet {
|
|||||||
this.mainHand = mainHand;
|
this.mainHand = mainHand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
this.locale = ProtocolUtils.readString(buf, 16);
|
||||||
|
this.viewDistance = buf.readByte();
|
||||||
|
this.chatVisibility = ProtocolUtils.readVarInt(buf);
|
||||||
|
this.chatColors = buf.readBoolean();
|
||||||
|
|
||||||
|
if (version.lte(ProtocolVersion.MINECRAFT_1_7_6)) {
|
||||||
|
this.difficulty = buf.readByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.skinParts = buf.readUnsignedByte();
|
||||||
|
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_9)) {
|
||||||
|
this.mainHand = ProtocolUtils.readVarInt(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
if (locale == null) {
|
||||||
|
throw new IllegalStateException("No locale specified");
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeString(buf, locale);
|
||||||
|
buf.writeByte(viewDistance);
|
||||||
|
ProtocolUtils.writeVarInt(buf, chatVisibility);
|
||||||
|
buf.writeBoolean(chatColors);
|
||||||
|
|
||||||
|
if (version.lte(ProtocolVersion.MINECRAFT_1_7_6)) {
|
||||||
|
buf.writeByte(difficulty);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.writeByte(skinParts);
|
||||||
|
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_9)) {
|
||||||
|
ProtocolUtils.writeVarInt(buf, mainHand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
public String getLocale() {
|
public String getLocale() {
|
||||||
if (locale == null) {
|
if (locale == null) {
|
||||||
throw new IllegalStateException("No locale specified");
|
throw new IllegalStateException("No locale specified");
|
||||||
@@ -38,103 +85,36 @@ public class ClientSettingsPacket implements Packet {
|
|||||||
return locale;
|
return locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocale(String locale) {
|
|
||||||
this.locale = locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte getViewDistance() {
|
public byte getViewDistance() {
|
||||||
return viewDistance;
|
return viewDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setViewDistance(byte viewDistance) {
|
|
||||||
this.viewDistance = viewDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChatVisibility() {
|
public int getChatVisibility() {
|
||||||
return chatVisibility;
|
return chatVisibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChatVisibility(int chatVisibility) {
|
|
||||||
this.chatVisibility = chatVisibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isChatColors() {
|
public boolean isChatColors() {
|
||||||
return chatColors;
|
return chatColors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChatColors(boolean chatColors) {
|
|
||||||
this.chatColors = chatColors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getSkinParts() {
|
public short getSkinParts() {
|
||||||
return skinParts;
|
return skinParts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSkinParts(short skinParts) {
|
|
||||||
this.skinParts = skinParts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMainHand() {
|
public int getMainHand() {
|
||||||
return mainHand;
|
return mainHand;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMainHand(int mainHand) {
|
|
||||||
this.mainHand = mainHand;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ClientSettings{"
|
return MoreObjects.toStringHelper(this)
|
||||||
+ "locale='" + locale + '\''
|
.add("locale", this.locale)
|
||||||
+ ", viewDistance=" + viewDistance
|
.add("viewDistance", this.viewDistance)
|
||||||
+ ", chatVisibility=" + chatVisibility
|
.add("chatVisibility", this.chatVisibility)
|
||||||
+ ", chatColors=" + chatColors
|
.add("chatColors", this.chatColors)
|
||||||
+ ", skinParts=" + skinParts
|
.add("difficulty", this.difficulty)
|
||||||
+ ", mainHand=" + mainHand
|
.add("skinParts", this.skinParts)
|
||||||
+ '}';
|
.add("mainHand", this.mainHand)
|
||||||
}
|
.toString();
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
this.locale = ProtocolUtils.readString(buf, 16);
|
|
||||||
this.viewDistance = buf.readByte();
|
|
||||||
this.chatVisibility = ProtocolUtils.readVarInt(buf);
|
|
||||||
this.chatColors = buf.readBoolean();
|
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_7_6) <= 0) {
|
|
||||||
this.difficulty = buf.readByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.skinParts = buf.readUnsignedByte();
|
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_9) >= 0) {
|
|
||||||
this.mainHand = ProtocolUtils.readVarInt(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
if (locale == null) {
|
|
||||||
throw new IllegalStateException("No locale specified");
|
|
||||||
}
|
|
||||||
ProtocolUtils.writeString(buf, locale);
|
|
||||||
buf.writeByte(viewDistance);
|
|
||||||
ProtocolUtils.writeVarInt(buf, chatVisibility);
|
|
||||||
buf.writeBoolean(chatColors);
|
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_7_6) <= 0) {
|
|
||||||
buf.writeByte(difficulty);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.writeByte(skinParts);
|
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_9) >= 0) {
|
|
||||||
ProtocolUtils.writeVarInt(buf, mainHand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
|
||||||
return handler.handle(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class ServerboundEncryptionResponsePacket implements Packet {
|
||||||
|
public static final PacketReader<ServerboundEncryptionResponsePacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final byte[] sharedSecret;
|
||||||
|
final byte[] verifyToken;
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
|
sharedSecret = ProtocolUtils.readByteArray(buf, 256);
|
||||||
|
verifyToken = ProtocolUtils.readByteArray(buf, 128);
|
||||||
|
} else {
|
||||||
|
sharedSecret = ProtocolUtils.readByteArray17(buf);
|
||||||
|
verifyToken = ProtocolUtils.readByteArray17(buf);
|
||||||
|
}
|
||||||
|
return new ServerboundEncryptionResponsePacket(sharedSecret, verifyToken);
|
||||||
|
};
|
||||||
|
|
||||||
|
private final byte[] sharedSecret;
|
||||||
|
private final byte[] verifyToken;
|
||||||
|
|
||||||
|
private ServerboundEncryptionResponsePacket(final byte[] sharedSecret, final byte[] verifyToken) {
|
||||||
|
this.sharedSecret = sharedSecret;
|
||||||
|
this.verifyToken = verifyToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
|
ProtocolUtils.writeByteArray(buf, sharedSecret);
|
||||||
|
ProtocolUtils.writeByteArray(buf, verifyToken);
|
||||||
|
} else {
|
||||||
|
ProtocolUtils.writeByteArray17(sharedSecret, buf, false);
|
||||||
|
ProtocolUtils.writeByteArray17(verifyToken, buf, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getSharedSecret() {
|
||||||
|
return sharedSecret.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getVerifyToken() {
|
||||||
|
return verifyToken.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("sharedSecret", this.sharedSecret)
|
||||||
|
.add("verifyToken", this.verifyToken)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class ServerboundHandshakePacket implements Packet {
|
||||||
|
public static final PacketReader<ServerboundHandshakePacket> DECODER = (buf, direction, version) -> {
|
||||||
|
int realProtocolVersion = ProtocolUtils.readVarInt(buf);
|
||||||
|
final ProtocolVersion protocolVersion = ProtocolVersion.getProtocolVersion(realProtocolVersion);
|
||||||
|
final String hostname = ProtocolUtils.readString(buf);
|
||||||
|
final int port = buf.readUnsignedShort();
|
||||||
|
final int nextStatus = ProtocolUtils.readVarInt(buf);
|
||||||
|
return new ServerboundHandshakePacket(protocolVersion, hostname, port, nextStatus);
|
||||||
|
};
|
||||||
|
|
||||||
|
private ProtocolVersion protocolVersion;
|
||||||
|
private String serverAddress = "";
|
||||||
|
private int port;
|
||||||
|
private int nextStatus;
|
||||||
|
|
||||||
|
public ServerboundHandshakePacket() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerboundHandshakePacket(final ProtocolVersion protocolVersion, final String hostname, final int port, final int nextStatus) {
|
||||||
|
this.protocolVersion = protocolVersion;
|
||||||
|
this.serverAddress = hostname;
|
||||||
|
this.port = port;
|
||||||
|
this.nextStatus = nextStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion ignored) {
|
||||||
|
ProtocolUtils.writeVarInt(buf, this.protocolVersion.getProtocol());
|
||||||
|
ProtocolUtils.writeString(buf, this.serverAddress);
|
||||||
|
buf.writeShort(this.port);
|
||||||
|
ProtocolUtils.writeVarInt(buf, this.nextStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProtocolVersion getProtocolVersion() {
|
||||||
|
return protocolVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void setProtocolVersion(ProtocolVersion protocolVersion) {
|
||||||
|
this.protocolVersion = protocolVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerAddress() {
|
||||||
|
return serverAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void setServerAddress(String serverAddress) {
|
||||||
|
this.serverAddress = serverAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNextStatus() {
|
||||||
|
return nextStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void setNextStatus(int nextStatus) {
|
||||||
|
this.nextStatus = nextStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("protocolVersion", this.protocolVersion)
|
||||||
|
.add("serverAddress", this.serverAddress)
|
||||||
|
.add("port", this.port)
|
||||||
|
.add("nextStatus", this.nextStatus)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.network.packet.AbstractKeepAlivePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
|
||||||
|
public class ServerboundKeepAlivePacket extends AbstractKeepAlivePacket implements Packet {
|
||||||
|
public static final PacketReader<ServerboundKeepAlivePacket> DECODER = decoder(ServerboundKeepAlivePacket::new);
|
||||||
|
|
||||||
|
public ServerboundKeepAlivePacket(final long randomId) {
|
||||||
|
super(randomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.DefaultByteBufHolder;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
|
public class ServerboundLoginPluginResponsePacket extends DefaultByteBufHolder implements Packet {
|
||||||
|
public static final PacketReader<ServerboundLoginPluginResponsePacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final int id = ProtocolUtils.readVarInt(buf);
|
||||||
|
final boolean success = buf.readBoolean();
|
||||||
|
final ByteBuf data;
|
||||||
|
if (buf.isReadable()) {
|
||||||
|
data = buf.readSlice(buf.readableBytes());
|
||||||
|
} else {
|
||||||
|
data = Unpooled.EMPTY_BUFFER;
|
||||||
|
}
|
||||||
|
return new ServerboundLoginPluginResponsePacket(id, success, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final boolean success;
|
||||||
|
|
||||||
|
public ServerboundLoginPluginResponsePacket(int id, boolean success, @MonotonicNonNull ByteBuf buf) {
|
||||||
|
super(buf);
|
||||||
|
this.id = id;
|
||||||
|
this.success = success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
ProtocolUtils.writeVarInt(buf, id);
|
||||||
|
buf.writeBoolean(success);
|
||||||
|
buf.writeBytes(content());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("id", this.id)
|
||||||
|
.add("success", this.success)
|
||||||
|
.add("data", this.contentToString())
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object other) {
|
||||||
|
if (this == other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other == null || this.getClass() != other.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final ServerboundLoginPluginResponsePacket that = (ServerboundLoginPluginResponsePacket) other;
|
||||||
|
return this.id == that.id
|
||||||
|
&& Objects.equals(this.success, that.success)
|
||||||
|
&& super.equals(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(this.id, this.success, super.hashCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class ServerboundPluginMessagePacket extends AbstractPluginMessagePacket<ServerboundPluginMessagePacket> implements Packet {
|
||||||
|
public static final Factory<ServerboundPluginMessagePacket> FACTORY = ServerboundPluginMessagePacket::new;
|
||||||
|
public static final PacketReader<ServerboundPluginMessagePacket> DECODER = decoder(FACTORY);
|
||||||
|
|
||||||
|
public ServerboundPluginMessagePacket(final String channel, final ByteBuf backing) {
|
||||||
|
super(channel, backing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerboundPluginMessagePacket replace(ByteBuf content) {
|
||||||
|
return new ServerboundPluginMessagePacket(this.channel, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.event.player.PlayerResourcePackStatusEvent.Status;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public class ServerboundResourcePackResponsePacket implements Packet {
|
||||||
|
public static final PacketReader<ServerboundResourcePackResponsePacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final String hash;
|
||||||
|
if (version.lte(ProtocolVersion.MINECRAFT_1_9_4)) {
|
||||||
|
hash = ProtocolUtils.readString(buf);
|
||||||
|
} else {
|
||||||
|
hash = null;
|
||||||
|
}
|
||||||
|
final Status status = Status.values()[ProtocolUtils.readVarInt(buf)];
|
||||||
|
return new ServerboundResourcePackResponsePacket(hash, status);
|
||||||
|
};
|
||||||
|
|
||||||
|
private final @Nullable String hash;
|
||||||
|
private final Status status;
|
||||||
|
|
||||||
|
public ServerboundResourcePackResponsePacket(final @Nullable String hash, final Status status) {
|
||||||
|
this.hash = hash;
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion protocolVersion) {
|
||||||
|
if (protocolVersion.lte(ProtocolVersion.MINECRAFT_1_9_4)) {
|
||||||
|
ProtocolUtils.writeString(buf, hash);
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeVarInt(buf, status.ordinal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("hash", this.hash)
|
||||||
|
.add("status", this.status)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.google.common.base.MoreObjects;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class ServerboundServerLoginPacket implements Packet {
|
||||||
|
private static final QuietDecoderException EMPTY_USERNAME = new QuietDecoderException("Empty username!");
|
||||||
|
|
||||||
|
public static final PacketReader<ServerboundServerLoginPacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final String username = ProtocolUtils.readString(buf, 16);
|
||||||
|
if (username.isEmpty()) {
|
||||||
|
throw EMPTY_USERNAME;
|
||||||
|
}
|
||||||
|
return new ServerboundServerLoginPacket(username);
|
||||||
|
};
|
||||||
|
|
||||||
|
private final String username;
|
||||||
|
|
||||||
|
public ServerboundServerLoginPacket(String username) {
|
||||||
|
this.username = Objects.requireNonNull(username, "username");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
ProtocolUtils.writeString(buf, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("username", this.username)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.network.packet.AbstractStatusPingPacket;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
|
||||||
|
public class ServerboundStatusPingPacket extends AbstractStatusPingPacket implements Packet {
|
||||||
|
public static final PacketReader<ServerboundStatusPingPacket> DECODER = decoder(ServerboundStatusPingPacket::new);
|
||||||
|
|
||||||
|
public ServerboundStatusPingPacket(final long randomId) {
|
||||||
|
super(randomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class ServerboundStatusRequestPacket implements Packet {
|
||||||
|
public static final ServerboundStatusRequestPacket INSTANCE = new ServerboundStatusRequestPacket();
|
||||||
|
public static final PacketReader<ServerboundStatusRequestPacket> DECODER = PacketReader.instance(INSTANCE);
|
||||||
|
|
||||||
|
private ServerboundStatusRequestPacket() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
|
// There is no data to decode.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(PacketHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "StatusRequestPacket";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet;
|
package com.velocitypowered.proxy.network.packet.serverbound;
|
||||||
|
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
|
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
|
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
|
||||||
@@ -6,14 +6,16 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_9;
|
|||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||||
|
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class TabCompleteRequestPacket implements Packet {
|
public class ServerboundTabCompleteRequestPacket implements Packet {
|
||||||
|
public static final PacketReader<ServerboundTabCompleteRequestPacket> DECODER = PacketReader.method(ServerboundTabCompleteRequestPacket::new);
|
||||||
|
|
||||||
private static final int VANILLA_MAX_TAB_COMPLETE_LEN = 2048;
|
private static final int VANILLA_MAX_TAB_COMPLETE_LEN = 2048;
|
||||||
|
|
||||||
@@ -67,27 +69,16 @@ public class TabCompleteRequestPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
return MoreObjects.toStringHelper(this)
|
if (version.gte(MINECRAFT_1_13)) {
|
||||||
.add("command", command)
|
|
||||||
.add("transactionId", transactionId)
|
|
||||||
.add("assumeCommand", assumeCommand)
|
|
||||||
.add("hasPosition", hasPosition)
|
|
||||||
.add("position", position)
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
if (version.compareTo(MINECRAFT_1_13) >= 0) {
|
|
||||||
this.transactionId = ProtocolUtils.readVarInt(buf);
|
this.transactionId = ProtocolUtils.readVarInt(buf);
|
||||||
this.command = ProtocolUtils.readString(buf, VANILLA_MAX_TAB_COMPLETE_LEN);
|
this.command = ProtocolUtils.readString(buf, VANILLA_MAX_TAB_COMPLETE_LEN);
|
||||||
} else {
|
} else {
|
||||||
this.command = ProtocolUtils.readString(buf, VANILLA_MAX_TAB_COMPLETE_LEN);
|
this.command = ProtocolUtils.readString(buf, VANILLA_MAX_TAB_COMPLETE_LEN);
|
||||||
if (version.compareTo(MINECRAFT_1_9) >= 0) {
|
if (version.gte(MINECRAFT_1_9)) {
|
||||||
this.assumeCommand = buf.readBoolean();
|
this.assumeCommand = buf.readBoolean();
|
||||||
}
|
}
|
||||||
if (version.compareTo(MINECRAFT_1_8) >= 0) {
|
if (version.gte(MINECRAFT_1_8)) {
|
||||||
this.hasPosition = buf.readBoolean();
|
this.hasPosition = buf.readBoolean();
|
||||||
if (hasPosition) {
|
if (hasPosition) {
|
||||||
this.position = buf.readLong();
|
this.position = buf.readLong();
|
||||||
@@ -97,20 +88,20 @@ public class TabCompleteRequestPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||||
if (command == null) {
|
if (command == null) {
|
||||||
throw new IllegalStateException("Command is not specified");
|
throw new IllegalStateException("Command is not specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version.compareTo(MINECRAFT_1_13) >= 0) {
|
if (version.gte(MINECRAFT_1_13)) {
|
||||||
ProtocolUtils.writeVarInt(buf, transactionId);
|
ProtocolUtils.writeVarInt(buf, transactionId);
|
||||||
ProtocolUtils.writeString(buf, command);
|
ProtocolUtils.writeString(buf, command);
|
||||||
} else {
|
} else {
|
||||||
ProtocolUtils.writeString(buf, command);
|
ProtocolUtils.writeString(buf, command);
|
||||||
if (version.compareTo(MINECRAFT_1_9) >= 0) {
|
if (version.gte(MINECRAFT_1_9)) {
|
||||||
buf.writeBoolean(assumeCommand);
|
buf.writeBoolean(assumeCommand);
|
||||||
}
|
}
|
||||||
if (version.compareTo(MINECRAFT_1_8) >= 0) {
|
if (version.gte(MINECRAFT_1_8)) {
|
||||||
buf.writeBoolean(hasPosition);
|
buf.writeBoolean(hasPosition);
|
||||||
if (hasPosition) {
|
if (hasPosition) {
|
||||||
buf.writeLong(position);
|
buf.writeLong(position);
|
||||||
@@ -120,7 +111,18 @@ public class TabCompleteRequestPacket implements Packet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(PacketHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this)
|
||||||
|
.add("command", command)
|
||||||
|
.add("transactionId", transactionId)
|
||||||
|
.add("assumeCommand", assumeCommand)
|
||||||
|
.add("hasPosition", hasPosition)
|
||||||
|
.add("position", position)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import io.netty.channel.ChannelDuplexHandler;
|
import io.netty.channel.ChannelDuplexHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import static com.velocitypowered.api.event.connection.ProxyQueryEvent.QueryType.BASIC;
|
import static com.velocitypowered.api.event.connection.ProxyQueryEvent.QueryType.BASIC;
|
||||||
import static com.velocitypowered.api.event.connection.ProxyQueryEvent.QueryType.FULL;
|
import static com.velocitypowered.api.event.connection.ProxyQueryEvent.QueryType.FULL;
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import static com.velocitypowered.proxy.protocol.util.NettyPreconditions.checkFrame;
|
import static com.velocitypowered.proxy.network.NettyPreconditions.checkFrame;
|
||||||
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyHandshakePacket;
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyHandshakePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyPingPacket;
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyMinecraftPingVersion;
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacyping.LegacyMinecraftPingVersion;
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyPingPacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyDisconnectPacket;
|
import com.velocitypowered.proxy.network.packet.legacy.LegacyDisconnectPacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.velocitypowered.natives.encryption.VelocityCipher;
|
import com.velocitypowered.natives.encryption.VelocityCipher;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.velocitypowered.natives.encryption.VelocityCipher;
|
import com.velocitypowered.natives.encryption.VelocityCipher;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import static com.velocitypowered.natives.util.MoreByteBufUtils.ensureCompatible;
|
import static com.velocitypowered.natives.util.MoreByteBufUtils.ensureCompatible;
|
||||||
import static com.velocitypowered.natives.util.MoreByteBufUtils.preferredBuffer;
|
import static com.velocitypowered.natives.util.MoreByteBufUtils.preferredBuffer;
|
||||||
import static com.velocitypowered.proxy.protocol.util.NettyPreconditions.checkFrame;
|
import static com.velocitypowered.proxy.network.NettyPreconditions.checkFrame;
|
||||||
|
|
||||||
import com.velocitypowered.natives.compression.VelocityCompressor;
|
import com.velocitypowered.natives.compression.VelocityCompressor;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import com.velocitypowered.natives.compression.VelocityCompressor;
|
import com.velocitypowered.natives.compression.VelocityCompressor;
|
||||||
import com.velocitypowered.natives.util.MoreByteBufUtils;
|
import com.velocitypowered.natives.util.MoreByteBufUtils;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.MessageToByteEncoder;
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
@@ -19,7 +19,7 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
|||||||
new QuietDecoderException("A packet did not decode successfully (invalid data). If you are a "
|
new QuietDecoderException("A packet did not decode successfully (invalid data). If you are a "
|
||||||
+ "developer, launch Velocity with -Dvelocity.packet-decode-logging=true to see more.");
|
+ "developer, launch Velocity with -Dvelocity.packet-decode-logging=true to see more.");
|
||||||
|
|
||||||
private final ProtocolDirection direction;
|
private final PacketDirection direction;
|
||||||
private StateRegistry state;
|
private StateRegistry state;
|
||||||
private StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
private StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
|||||||
*
|
*
|
||||||
* @param direction the direction from which we decode from
|
* @param direction the direction from which we decode from
|
||||||
*/
|
*/
|
||||||
public MinecraftDecoder(ProtocolDirection direction) {
|
public MinecraftDecoder(PacketDirection direction) {
|
||||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||||
this.registry = StateRegistry.HANDSHAKE.getProtocolRegistry(direction,
|
this.registry = StateRegistry.HANDSHAKE.getProtocolRegistry(direction,
|
||||||
ProtocolVersion.MINIMUM_VERSION);
|
ProtocolVersion.MINIMUM_VERSION);
|
||||||
@@ -53,18 +53,17 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
int originalReaderIndex = buf.readerIndex();
|
int originalReaderIndex = buf.readerIndex();
|
||||||
int packetId = ProtocolUtils.readVarInt(buf);
|
int packetId = ProtocolUtils.readVarInt(buf);
|
||||||
Packet packet = this.registry.createPacket(packetId);
|
Packet packet = null;
|
||||||
|
try {
|
||||||
|
packet = this.registry.readPacket(packetId, buf, direction, registry.version);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw handleDecodeFailure(e, packet, packetId); // TODO: packet is always null
|
||||||
|
}
|
||||||
if (packet == null) {
|
if (packet == null) {
|
||||||
buf.readerIndex(originalReaderIndex);
|
buf.readerIndex(originalReaderIndex);
|
||||||
ctx.fireChannelRead(buf);
|
ctx.fireChannelRead(buf);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
try {
|
|
||||||
packet.decode(buf, direction, registry.version);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw handleDecodeFailure(e, packet, packetId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf.isReadable()) {
|
if (buf.isReadable()) {
|
||||||
throw handleNotReadEnough(packet, packetId);
|
throw handleNotReadEnough(packet, packetId);
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.network.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.packet.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.MessageToByteEncoder;
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
|
||||||
public class MinecraftEncoder extends MessageToByteEncoder<Packet> {
|
public class MinecraftEncoder extends MessageToByteEncoder<Packet> {
|
||||||
|
|
||||||
private final ProtocolDirection direction;
|
private final PacketDirection direction;
|
||||||
private StateRegistry state;
|
private StateRegistry state;
|
||||||
private StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
private StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<Packet> {
|
|||||||
*
|
*
|
||||||
* @param direction the direction to encode to
|
* @param direction the direction to encode to
|
||||||
*/
|
*/
|
||||||
public MinecraftEncoder(ProtocolDirection direction) {
|
public MinecraftEncoder(PacketDirection direction) {
|
||||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||||
this.registry = StateRegistry.HANDSHAKE
|
this.registry = StateRegistry.HANDSHAKE
|
||||||
.getProtocolRegistry(direction, ProtocolVersion.MINIMUM_VERSION);
|
.getProtocolRegistry(direction, ProtocolVersion.MINIMUM_VERSION);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import com.velocitypowered.proxy.protocol.netty.VarintByteDecoder.DecodeResult;
|
import com.velocitypowered.proxy.network.pipeline.VarintByteDecoder.DecodeResult;
|
||||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import com.velocitypowered.natives.encryption.JavaVelocityCipher;
|
import com.velocitypowered.natives.encryption.JavaVelocityCipher;
|
||||||
import com.velocitypowered.natives.util.Natives;
|
import com.velocitypowered.natives.util.Natives;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.netty;
|
package com.velocitypowered.proxy.network.pipeline;
|
||||||
|
|
||||||
import io.netty.util.ByteProcessor;
|
import io.netty.util.ByteProcessor;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.network.netty;
|
package com.velocitypowered.proxy.network.resolver;
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.velocitypowered.proxy.protocol.util;
|
package com.velocitypowered.proxy.network.serialization;
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.google.gson.JsonDeserializationContext;
|
||||||
import com.google.gson.JsonDeserializer;
|
import com.google.gson.JsonDeserializer;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user