mirror of
https://github.com/PaperMC/Velocity.git
synced 2026-02-17 14:37:43 +01:00
@@ -32,6 +32,7 @@ dependencies {
|
||||
api "net.kyori:adventure-text-serializer-gson:${adventureVersion}"
|
||||
api "net.kyori:adventure-text-serializer-legacy:${adventureVersion}"
|
||||
api "net.kyori:adventure-text-serializer-plain:${adventureVersion}"
|
||||
api("net.kyori:coffee:1.0.0-SNAPSHOT")
|
||||
|
||||
api "org.slf4j:slf4j-api:${slf4jVersion}"
|
||||
api 'com.google.inject:guice:4.2.3'
|
||||
@@ -75,13 +76,13 @@ javadoc {
|
||||
options.encoding = 'UTF-8'
|
||||
options.charSet = 'UTF-8'
|
||||
options.source = '8'
|
||||
options.links(
|
||||
'https://www.slf4j.org/apidocs/',
|
||||
'https://guava.dev/releases/30.0-jre/api/docs/',
|
||||
'https://google.github.io/guice/api-docs/4.2/javadoc/',
|
||||
'https://docs.oracle.com/javase/8/docs/api/',
|
||||
'https://jd.adventure.kyori.net/api/4.0.0/'
|
||||
)
|
||||
// options.links(
|
||||
// 'https://www.slf4j.org/apidocs/',
|
||||
// 'https://guava.dev/releases/30.0-jre/api/docs/',
|
||||
// 'https://google.github.io/guice/api-docs/4.2/javadoc/',
|
||||
// 'https://docs.oracle.com/javase/8/docs/api/',
|
||||
// 'https://jd.adventure.kyori.net/api/4.0.0/'
|
||||
// )
|
||||
|
||||
// Disable the crazy super-strict doclint tool in Java 8
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
|
||||
@@ -6,11 +6,12 @@ import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.kyori.coffee.Ordered;
|
||||
|
||||
/**
|
||||
* Represents each Minecraft protocol version.
|
||||
*/
|
||||
public enum ProtocolVersion {
|
||||
public enum ProtocolVersion implements Ordered<ProtocolVersion> {
|
||||
UNKNOWN(-1, "Unknown"),
|
||||
LEGACY(-2, "Legacy"),
|
||||
MINECRAFT_1_7_2(4, "1.7.2"),
|
||||
|
||||
@@ -3,7 +3,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
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"/>
|
||||
</module>
|
||||
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${configDirectory}/suppressions.xml"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<module name="OuterTypeFilename"/>
|
||||
<!-- <module name="IllegalTokenText">
|
||||
@@ -42,7 +46,7 @@
|
||||
<property name="allowNonPrintableEscapes" value="true"/>
|
||||
</module>
|
||||
<module name="LineLength">
|
||||
<property name="max" value="100"/>
|
||||
<property name="max" value="150"/>
|
||||
<property name="ignorePattern"
|
||||
value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
||||
</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 {
|
||||
def configDirectory = new File(project.rootDir, ["config", "checkstyle"].join(File.separator))
|
||||
|
||||
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.
|
||||
maxErrors = 0
|
||||
maxWarnings = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ import com.velocitypowered.proxy.config.VelocityConfiguration;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.console.VelocityConsole;
|
||||
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.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.server.ServerMap;
|
||||
import com.velocitypowered.proxy.util.AddressUtil;
|
||||
@@ -645,7 +645,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,15 @@ import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
|
||||
import com.velocitypowered.proxy.connection.client.LoginSessionHandler;
|
||||
import com.velocitypowered.proxy.connection.client.StatusSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCipherDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCipherEncoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCompressDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCompressEncoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
||||
import com.velocitypowered.proxy.network.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.packet.Packet;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundSetCompressionPacket;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftCipherDecoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftCipherEncoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftCompressDecoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftCompressEncoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftEncoder;
|
||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
@@ -224,8 +224,8 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
*/
|
||||
public void closeWith(Object msg) {
|
||||
if (channel.isActive()) {
|
||||
boolean is17 = this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) < 0
|
||||
&& this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_7_2) >= 0;
|
||||
boolean is17 = this.getProtocolVersion().lt(ProtocolVersion.MINECRAFT_1_8)
|
||||
&& this.getProtocolVersion().gte(ProtocolVersion.MINECRAFT_1_7_2);
|
||||
if (is17 && this.getState() != StateRegistry.STATUS) {
|
||||
channel.eventLoop().execute(() -> {
|
||||
// 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
|
||||
* {@link SetCompressionPacket} beforehand.
|
||||
* {@link ClientboundSetCompressionPacket} beforehand.
|
||||
* @param threshold the compression threshold to use
|
||||
*/
|
||||
public void setCompressionThreshold(int threshold) {
|
||||
|
||||
@@ -1,192 +1,39 @@
|
||||
package com.velocitypowered.proxy.connection;
|
||||
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
||||
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 com.velocitypowered.proxy.network.packet.Packet;
|
||||
import com.velocitypowered.proxy.network.packet.PacketHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public interface MinecraftSessionHandler {
|
||||
public interface MinecraftSessionHandler extends PacketHandler {
|
||||
|
||||
default boolean beforeHandle() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default void handleGeneric(Packet packet) {
|
||||
|
||||
}
|
||||
|
||||
default void handleUnknown(ByteBuf buf) {
|
||||
|
||||
}
|
||||
|
||||
default void connected() {
|
||||
|
||||
}
|
||||
|
||||
default void disconnected() {
|
||||
|
||||
}
|
||||
|
||||
default void activated() {
|
||||
|
||||
}
|
||||
|
||||
default void deactivated() {
|
||||
|
||||
}
|
||||
|
||||
default void exception(Throwable throwable) {
|
||||
|
||||
}
|
||||
|
||||
default void writabilityChanged() {
|
||||
|
||||
}
|
||||
|
||||
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.forge.legacy.LegacyForgeHandshakeBackendPhase;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||
|
||||
/**
|
||||
* Provides connection phase specific actions.
|
||||
@@ -21,7 +21,7 @@ public interface BackendConnectionPhase {
|
||||
*/
|
||||
default boolean handle(VelocityServerConnection server,
|
||||
ConnectedPlayer player,
|
||||
PluginMessagePacket message) {
|
||||
AbstractPluginMessagePacket<?> message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.velocitypowered.proxy.connection.backend;
|
||||
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
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.
|
||||
@@ -29,7 +29,7 @@ public final class BackendConnectionPhases {
|
||||
@Override
|
||||
public boolean handle(VelocityServerConnection serverConn,
|
||||
ConnectedPlayer player,
|
||||
PluginMessagePacket message) {
|
||||
AbstractPluginMessagePacket<?> message) {
|
||||
// The connection may be legacy forge. If so, the Forge handler will deal with this
|
||||
// for us. Otherwise, we have nothing to do.
|
||||
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.client.ClientPlaySessionHandler;
|
||||
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PlayerListItemPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.Packet;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundAvailableCommandsPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundBossBarPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundKeepAlivePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPlayerListItemPacket;
|
||||
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.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@@ -64,7 +65,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
serverConn.getServer().addPlayer(serverConn.getPlayer());
|
||||
MinecraftConnection serverMc = serverConn.ensureConnected();
|
||||
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
|
||||
public boolean handle(KeepAlivePacket packet) {
|
||||
public boolean handle(ClientboundKeepAlivePacket packet) {
|
||||
serverConn.setLastPingId(packet.getRandomId());
|
||||
return false; // forwards on
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(DisconnectPacket packet) {
|
||||
public boolean handle(ClientboundDisconnectPacket packet) {
|
||||
serverConn.disconnect();
|
||||
serverConn.getPlayer().handleConnectionException(serverConn.getServer(), packet, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(BossBarPacket packet) {
|
||||
if (packet.getAction() == BossBarPacket.ADD) {
|
||||
public boolean handle(ClientboundBossBarPacket packet) {
|
||||
if (packet.getAction() == ClientboundBossBarPacket.ADD) {
|
||||
playerSessionHandler.getServerBossBars().add(packet.getUuid());
|
||||
} else if (packet.getAction() == BossBarPacket.REMOVE) {
|
||||
} else if (packet.getAction() == ClientboundBossBarPacket.REMOVE) {
|
||||
playerSessionHandler.getServerBossBars().remove(packet.getUuid());
|
||||
}
|
||||
return false; // forward
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(PluginMessagePacket packet) {
|
||||
public boolean handle(ClientboundPluginMessagePacket packet) {
|
||||
if (bungeecordMessageResponder.process(packet)) {
|
||||
return true;
|
||||
}
|
||||
@@ -123,8 +124,8 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
if (PluginMessageUtil.isMcBrand(packet)) {
|
||||
PluginMessagePacket rewritten = PluginMessageUtil.rewriteMinecraftBrand(packet,
|
||||
server.getVersion(), playerConnection.getProtocolVersion());
|
||||
AbstractPluginMessagePacket<?> rewritten = PluginMessageUtil.rewriteMinecraftBrand(packet,
|
||||
server.getVersion(), playerConnection.getProtocolVersion(), ClientboundPluginMessagePacket.FACTORY);
|
||||
playerConnection.write(rewritten);
|
||||
return true;
|
||||
}
|
||||
@@ -145,7 +146,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
server.getEventManager().fire(event)
|
||||
.thenAcceptAsync(pme -> {
|
||||
if (pme.getResult().isAllowed() && !playerConnection.isClosed()) {
|
||||
PluginMessagePacket copied = new PluginMessagePacket(packet.getChannel(),
|
||||
ClientboundPluginMessagePacket copied = new ClientboundPluginMessagePacket(packet.getChannel(),
|
||||
Unpooled.wrappedBuffer(copy));
|
||||
playerConnection.write(copied);
|
||||
}
|
||||
@@ -158,19 +159,19 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(TabCompleteResponsePacket packet) {
|
||||
public boolean handle(ClientboundTabCompleteResponsePacket packet) {
|
||||
playerSessionHandler.handleTabCompleteResponse(packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(PlayerListItemPacket packet) {
|
||||
public boolean handle(ClientboundPlayerListItemPacket packet) {
|
||||
serverConn.getPlayer().getTabList().processBackendPacket(packet);
|
||||
return false; //Forward packet to player
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(AvailableCommandsPacket commands) {
|
||||
public boolean handle(ClientboundAvailableCommandsPacket commands) {
|
||||
RootCommandNode<CommandSource> rootNode = commands.getRootNode();
|
||||
if (server.getConfiguration().isAnnounceProxyCommands()) {
|
||||
// Inject commands from the proxy.
|
||||
@@ -244,8 +245,8 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
@Override
|
||||
public void handleGeneric(Packet packet) {
|
||||
if (packet instanceof PluginMessagePacket) {
|
||||
((PluginMessagePacket) packet).retain();
|
||||
if (packet instanceof AbstractPluginMessagePacket<?>) {
|
||||
((AbstractPluginMessagePacket<?>) packet).retain();
|
||||
}
|
||||
playerConnection.delayedWrite(packet);
|
||||
}
|
||||
@@ -277,7 +278,7 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
if (!serverConn.isGracefulDisconnect() && !exceptionTriggered) {
|
||||
if (server.getConfiguration().isFailoverOnUnexpectedServerDisconnect()) {
|
||||
serverConn.getPlayer().handleConnectionException(serverConn.getServer(),
|
||||
DisconnectPacket.create(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR,
|
||||
ClientboundDisconnectPacket.create(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR,
|
||||
ProtocolVersion.MINECRAFT_1_16), true);
|
||||
} else {
|
||||
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.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.util.ByteBufDataInput;
|
||||
import com.velocitypowered.proxy.protocol.util.ByteBufDataOutput;
|
||||
import com.velocitypowered.proxy.network.buffer.ByteBufDataInput;
|
||||
import com.velocitypowered.proxy.network.buffer.ByteBufDataOutput;
|
||||
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -45,7 +46,7 @@ public class BungeeCordMessageResponder {
|
||||
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()
|
||||
.equals(message.getChannel());
|
||||
}
|
||||
@@ -303,7 +304,7 @@ public class BungeeCordMessageResponder {
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -312,7 +313,7 @@ public class BungeeCordMessageResponder {
|
||||
MinecraftConnection serverConnection = player.ensureAndGetCurrentServer().ensureConnected();
|
||||
String chan = getBungeeCordChannel(serverConnection.getProtocolVersion());
|
||||
|
||||
PluginMessagePacket msg = null;
|
||||
ServerboundPluginMessagePacket msg = null;
|
||||
boolean released = false;
|
||||
|
||||
try {
|
||||
@@ -322,7 +323,7 @@ public class BungeeCordMessageResponder {
|
||||
}
|
||||
|
||||
MinecraftConnection serverConn = vsc.ensureConnected();
|
||||
msg = new PluginMessagePacket(chan, buf);
|
||||
msg = new ServerboundPluginMessagePacket(chan, buf);
|
||||
serverConn.write(msg);
|
||||
released = true;
|
||||
} finally {
|
||||
@@ -332,7 +333,7 @@ public class BungeeCordMessageResponder {
|
||||
}
|
||||
}
|
||||
|
||||
boolean process(PluginMessagePacket message) {
|
||||
boolean process(AbstractPluginMessagePacket<?> message) {
|
||||
if (!proxy.getConfiguration().isBungeePluginChannelEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.connection.VelocityConstants;
|
||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
|
||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
||||
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.network.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundEncryptionRequestPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundLoginPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundServerLoginSuccessPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundSetCompressionPacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundLoginPluginResponsePacket;
|
||||
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@@ -49,12 +49,12 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(EncryptionRequestPacket packet) {
|
||||
public boolean handle(ClientboundEncryptionRequestPacket packet) {
|
||||
throw new IllegalStateException("Backend server is online-mode!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(LoginPluginMessagePacket packet) {
|
||||
public boolean handle(ClientboundLoginPluginMessagePacket packet) {
|
||||
MinecraftConnection mc = serverConn.ensureConnected();
|
||||
VelocityConfiguration configuration = server.getConfiguration();
|
||||
if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN && packet
|
||||
@@ -62,32 +62,33 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
ByteBuf forwardingData = createForwardingData(configuration.getForwardingSecret(),
|
||||
cleanRemoteAddress(serverConn.getPlayer().getRemoteAddress()),
|
||||
serverConn.getPlayer().getGameProfile());
|
||||
LoginPluginResponsePacket response = new LoginPluginResponsePacket(packet.getId(), true,
|
||||
forwardingData);
|
||||
ServerboundLoginPluginResponsePacket response = new ServerboundLoginPluginResponsePacket(
|
||||
packet.getId(), true, forwardingData);
|
||||
mc.write(response);
|
||||
informationForwarded = true;
|
||||
} else {
|
||||
// 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(DisconnectPacket packet) {
|
||||
public boolean handle(ClientboundDisconnectPacket packet) {
|
||||
resultFuture.complete(ConnectionRequestResults.forDisconnect(packet, serverConn.getServer()));
|
||||
serverConn.disconnect();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(SetCompressionPacket packet) {
|
||||
public boolean handle(ClientboundSetCompressionPacket packet) {
|
||||
serverConn.ensureConnected().setCompressionThreshold(packet.getThreshold());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ServerLoginSuccessPacket packet) {
|
||||
public boolean handle(ClientboundServerLoginSuccessPacket packet) {
|
||||
if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN
|
||||
&& !informationForwarded) {
|
||||
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.ConnectionRequestResults;
|
||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundJoinGamePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundKeepAlivePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -60,13 +60,13 @@ public class TransitionSessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(KeepAlivePacket packet) {
|
||||
public boolean handle(ClientboundKeepAlivePacket packet) {
|
||||
serverConn.ensureConnected().write(packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(JoinGamePacket packet) {
|
||||
public boolean handle(ClientboundJoinGamePacket packet) {
|
||||
MinecraftConnection smc = serverConn.ensureConnected();
|
||||
VelocityServerConnection existingConnection = serverConn.getPlayer().getConnectedServer();
|
||||
|
||||
@@ -132,7 +132,7 @@ public class TransitionSessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(DisconnectPacket packet) {
|
||||
public boolean handle(ClientboundDisconnectPacket packet) {
|
||||
final MinecraftConnection connection = serverConn.ensureConnected();
|
||||
serverConn.disconnect();
|
||||
|
||||
@@ -150,7 +150,7 @@ public class TransitionSessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(PluginMessagePacket packet) {
|
||||
public boolean handle(ClientboundPluginMessagePacket packet) {
|
||||
if (!serverConn.getPlayer().canForwardPluginMessage(serverConn.ensureConnected()
|
||||
.getProtocolVersion(), packet)) {
|
||||
return true;
|
||||
|
||||
@@ -20,11 +20,11 @@ import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.connection.registry.DimensionRegistry;
|
||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
||||
import com.velocitypowered.proxy.network.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundJoinGamePacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundHandshakePacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundServerLoginPacket;
|
||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@@ -143,7 +143,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
||||
|
||||
// Initiate the handshake.
|
||||
ProtocolVersion protocolVersion = proxyPlayer.getConnection().getProtocolVersion();
|
||||
HandshakePacket handshake = new HandshakePacket();
|
||||
ServerboundHandshakePacket handshake = new ServerboundHandshakePacket();
|
||||
handshake.setNextStatus(StateRegistry.LOGIN_ID);
|
||||
handshake.setProtocolVersion(protocolVersion);
|
||||
if (forwardingMode == PlayerInfoForwarding.LEGACY) {
|
||||
@@ -165,7 +165,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
||||
|
||||
mc.setProtocolVersion(protocolVersion);
|
||||
mc.setState(StateRegistry.LOGIN);
|
||||
mc.delayedWrite(new ServerLoginPacket(proxyPlayer.getUsername()));
|
||||
mc.delayedWrite(new ServerboundServerLoginPacket(proxyPlayer.getUsername()));
|
||||
mc.flush();
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
||||
|
||||
MinecraftConnection mc = ensureConnected();
|
||||
|
||||
PluginMessagePacket message = new PluginMessagePacket(identifier.getId(), data);
|
||||
ServerboundPluginMessagePacket message = new ServerboundPluginMessagePacket(identifier.getId(), data);
|
||||
mc.write(message);
|
||||
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.
|
||||
*
|
||||
* @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.forge.legacy.LegacyForgeHandshakeClientPhase;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||
|
||||
/**
|
||||
* Provides connection phase specific actions.
|
||||
@@ -22,7 +22,7 @@ public interface ClientConnectionPhase {
|
||||
* @return true if handled, false otherwise.
|
||||
*/
|
||||
default boolean handle(ConnectedPlayer player,
|
||||
PluginMessagePacket message,
|
||||
AbstractPluginMessagePacket<?> message,
|
||||
VelocityServerConnection server) {
|
||||
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_16;
|
||||
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.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.BungeeCordMessageResponder;
|
||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
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.JoinGamePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket.Offer;
|
||||
import com.velocitypowered.proxy.protocol.packet.TitlePacket;
|
||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.network.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.Packet;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundBossBarPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundJoinGamePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundRespawnPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTabCompleteResponsePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundTabCompleteResponsePacket.Offer;
|
||||
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.network.packet.serverbound.ServerboundKeepAlivePacket;
|
||||
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.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@@ -64,9 +66,9 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
private final ConnectedPlayer player;
|
||||
private boolean spawned = false;
|
||||
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 @Nullable TabCompleteRequestPacket outstandingTabComplete;
|
||||
private @Nullable ServerboundTabCompleteRequestPacket outstandingTabComplete;
|
||||
|
||||
/**
|
||||
* Constructs a client play session handler.
|
||||
@@ -83,7 +85,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
Collection<String> channels = server.getChannelRegistrar().getChannelsForProtocol(player
|
||||
.getProtocolVersion());
|
||||
if (!channels.isEmpty()) {
|
||||
PluginMessagePacket register = constructChannelsPacket(player.getProtocolVersion(), channels);
|
||||
AbstractPluginMessagePacket<?> register = constructChannelsPacket(player.getProtocolVersion(),
|
||||
channels, ClientboundPluginMessagePacket.FACTORY);
|
||||
player.getConnection().write(register);
|
||||
player.getKnownChannels().addAll(channels);
|
||||
}
|
||||
@@ -91,13 +94,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
@Override
|
||||
public void deactivated() {
|
||||
for (PluginMessagePacket message : loginPluginMessages) {
|
||||
for (ServerboundPluginMessagePacket message : loginPluginMessages) {
|
||||
ReferenceCountUtil.release(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(KeepAlivePacket packet) {
|
||||
public boolean handle(ServerboundKeepAlivePacket packet) {
|
||||
VelocityServerConnection serverConnection = player.getConnectedServer();
|
||||
if (serverConnection != null && packet.getRandomId() == serverConnection.getLastPingId()) {
|
||||
MinecraftConnection smc = serverConnection.getConnection();
|
||||
@@ -111,13 +114,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ClientSettingsPacket packet) {
|
||||
public boolean handle(ServerboundClientSettingsPacket packet) {
|
||||
player.setPlayerSettings(packet);
|
||||
return false; // will forward onto the server
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ChatPacket packet) {
|
||||
public boolean handle(ServerboundChatPacket packet) {
|
||||
VelocityServerConnection serverConnection = player.getConnectedServer();
|
||||
if (serverConnection == null) {
|
||||
return true;
|
||||
@@ -154,7 +157,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
if (chatResult.isAllowed()) {
|
||||
Optional<String> eventMsg = pme.getResult().getMessage();
|
||||
if (eventMsg.isPresent()) {
|
||||
smc.write(ChatPacket.createServerbound(eventMsg.get()));
|
||||
smc.write(new ServerboundChatPacket(eventMsg.get()));
|
||||
} else {
|
||||
smc.write(packet);
|
||||
}
|
||||
@@ -169,7 +172,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(TabCompleteRequestPacket packet) {
|
||||
public boolean handle(ServerboundTabCompleteRequestPacket packet) {
|
||||
boolean isCommand = !packet.isAssumeCommand() && packet.getCommand().startsWith("/");
|
||||
|
||||
if (isCommand) {
|
||||
@@ -180,7 +183,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(PluginMessagePacket packet) {
|
||||
public boolean handle(ServerboundPluginMessagePacket packet) {
|
||||
VelocityServerConnection serverConn = player.getConnectedServer();
|
||||
MinecraftConnection backendConn = serverConn != null ? serverConn.getConnection() : null;
|
||||
if (serverConn != null && backendConn != null) {
|
||||
@@ -195,7 +198,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
backendConn.write(packet.retain());
|
||||
} else if (PluginMessageUtil.isMcBrand(packet)) {
|
||||
backendConn.write(PluginMessageUtil
|
||||
.rewriteMinecraftBrand(packet, server.getVersion(), player.getProtocolVersion()));
|
||||
.rewriteMinecraftBrand(packet, server.getVersion(), player.getProtocolVersion(), ServerboundPluginMessagePacket.FACTORY));
|
||||
} else if (BungeeCordMessageResponder.isBungeeCordMessage(packet)) {
|
||||
return true;
|
||||
} else {
|
||||
@@ -228,7 +231,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
PluginMessageEvent event = new PluginMessageEvent(player, serverConn, id, copy);
|
||||
server.getEventManager().fire(event).thenAcceptAsync(pme -> {
|
||||
if (pme.getResult().isAllowed()) {
|
||||
PluginMessagePacket message = new PluginMessagePacket(packet.getChannel(),
|
||||
ServerboundPluginMessagePacket message = new ServerboundPluginMessagePacket(packet.getChannel(),
|
||||
Unpooled.wrappedBuffer(copy));
|
||||
backendConn.write(message);
|
||||
}
|
||||
@@ -248,7 +251,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ResourcePackResponsePacket packet) {
|
||||
public boolean handle(ServerboundResourcePackResponsePacket packet) {
|
||||
server.getEventManager().fireAndForget(new PlayerResourcePackStatusEvent(player,
|
||||
packet.getStatus()));
|
||||
return false;
|
||||
@@ -264,8 +267,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
MinecraftConnection smc = serverConnection.getConnection();
|
||||
if (smc != null && serverConnection.getPhase().consideredComplete()) {
|
||||
if (packet instanceof PluginMessagePacket) {
|
||||
((PluginMessagePacket) packet).retain();
|
||||
if (packet instanceof AbstractPluginMessagePacket<?>) {
|
||||
((AbstractPluginMessagePacket<?>) packet).retain();
|
||||
}
|
||||
smc.write(packet);
|
||||
}
|
||||
@@ -319,7 +322,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
* @param joinGame the join game packet
|
||||
* @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();
|
||||
|
||||
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
|
||||
// track them.
|
||||
for (UUID serverBossBar : serverBossBars) {
|
||||
BossBarPacket deletePacket = new BossBarPacket();
|
||||
ClientboundBossBarPacket deletePacket = new ClientboundBossBarPacket();
|
||||
deletePacket.setUuid(serverBossBar);
|
||||
deletePacket.setAction(BossBarPacket.REMOVE);
|
||||
deletePacket.setAction(ClientboundBossBarPacket.REMOVE);
|
||||
player.getConnection().delayedWrite(deletePacket);
|
||||
}
|
||||
serverBossBars.clear();
|
||||
@@ -354,19 +358,19 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
// Tell the server about this client's plugin message channels.
|
||||
ProtocolVersion serverVersion = serverMc.getProtocolVersion();
|
||||
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.
|
||||
PluginMessagePacket pm;
|
||||
ServerboundPluginMessagePacket pm;
|
||||
while ((pm = loginPluginMessages.poll()) != null) {
|
||||
serverMc.delayedWrite(pm);
|
||||
}
|
||||
|
||||
// Clear any title from the previous server.
|
||||
if (player.getProtocolVersion().compareTo(MINECRAFT_1_8) >= 0) {
|
||||
if (player.getProtocolVersion().gte(MINECRAFT_1_8)) {
|
||||
player.getConnection()
|
||||
.delayedWrite(TitlePacket.resetForProtocolVersion(player.getProtocolVersion()));
|
||||
.delayedWrite(ClientboundTitlePacket.reset(player.getProtocolVersion()));
|
||||
}
|
||||
|
||||
// Flush everything
|
||||
@@ -375,7 +379,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
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:
|
||||
//
|
||||
// - 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
|
||||
// improving compatibility with mods.
|
||||
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
|
||||
// additional respawn. On older versions of Minecraft this forces the client to perform
|
||||
// garbage collection which adds additional latency.
|
||||
@@ -394,13 +398,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
player.getConnection().delayedWrite(joinGame);
|
||||
|
||||
player.getConnection().delayedWrite(
|
||||
new RespawnPacket(sentOldDim, joinGame.getPartialHashedSeed(),
|
||||
new ClientboundRespawnPacket(sentOldDim, joinGame.getPartialHashedSeed(),
|
||||
joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType(),
|
||||
false, joinGame.getDimensionInfo(), joinGame.getPreviousGamemode(),
|
||||
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
|
||||
// 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).
|
||||
@@ -411,14 +415,14 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
// Send a respawn packet in a different dimension.
|
||||
int tempDim = joinGame.getDimension() == 0 ? -1 : 0;
|
||||
player.getConnection().delayedWrite(
|
||||
new RespawnPacket(tempDim, joinGame.getPartialHashedSeed(), joinGame.getDifficulty(),
|
||||
joinGame.getGamemode(), joinGame.getLevelType(),
|
||||
new ClientboundRespawnPacket(tempDim, joinGame.getPartialHashedSeed(),
|
||||
joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType(),
|
||||
false, joinGame.getDimensionInfo(), joinGame.getPreviousGamemode(),
|
||||
joinGame.getCurrentDimensionData()));
|
||||
|
||||
// Now send a respawn packet in the correct dimension.
|
||||
player.getConnection().delayedWrite(
|
||||
new RespawnPacket(joinGame.getDimension(), joinGame.getPartialHashedSeed(),
|
||||
new ClientboundRespawnPacket(joinGame.getDimension(), joinGame.getPartialHashedSeed(),
|
||||
joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType(),
|
||||
false, joinGame.getDimensionInfo(), joinGame.getPreviousGamemode(),
|
||||
joinGame.getCurrentDimensionData()));
|
||||
@@ -428,7 +432,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
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.
|
||||
String command = packet.getCommand().substring(1);
|
||||
int commandEndPosition = command.indexOf(' ');
|
||||
@@ -438,7 +442,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
String commandLabel = command.substring(0, commandEndPosition);
|
||||
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
|
||||
// additional tab completion support.
|
||||
outstandingTabComplete = packet;
|
||||
@@ -458,7 +462,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
int startPos = packet.getCommand().lastIndexOf(' ') + 1;
|
||||
if (startPos > 0) {
|
||||
TabCompleteResponsePacket resp = new TabCompleteResponsePacket();
|
||||
ClientboundTabCompleteResponsePacket resp = new ClientboundTabCompleteResponsePacket();
|
||||
resp.setTransactionId(packet.getTransactionId());
|
||||
resp.setStart(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.
|
||||
}
|
||||
|
||||
private boolean handleRegularTabComplete(TabCompleteRequestPacket packet) {
|
||||
if (player.getProtocolVersion().compareTo(MINECRAFT_1_13) < 0) {
|
||||
private boolean handleRegularTabComplete(ServerboundTabCompleteRequestPacket packet) {
|
||||
if (player.getProtocolVersion().lt(MINECRAFT_1_13)) {
|
||||
// Outstanding tab completes are recorded for use with 1.12 clients and below to provide
|
||||
// additional tab completion support.
|
||||
outstandingTabComplete = packet;
|
||||
@@ -488,7 +492,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
*
|
||||
* @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.getCommand().startsWith("/")) {
|
||||
this.finishCommandTabComplete(outstandingTabComplete, response);
|
||||
@@ -502,12 +506,12 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void finishCommandTabComplete(TabCompleteRequestPacket request,
|
||||
TabCompleteResponsePacket response) {
|
||||
private void finishCommandTabComplete(ServerboundTabCompleteRequestPacket request,
|
||||
ClientboundTabCompleteResponsePacket response) {
|
||||
String command = request.getCommand().substring(1);
|
||||
server.getCommandManager().offerSuggestions(player, command)
|
||||
.thenAcceptAsync(offers -> {
|
||||
boolean legacy = player.getProtocolVersion().compareTo(MINECRAFT_1_13) < 0;
|
||||
boolean legacy = player.getProtocolVersion().lt(MINECRAFT_1_13);
|
||||
try {
|
||||
for (String offer : offers) {
|
||||
offer = legacy && !offer.startsWith("/") ? "/" + offer : offer;
|
||||
@@ -532,8 +536,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
});
|
||||
}
|
||||
|
||||
private void finishRegularTabComplete(TabCompleteRequestPacket request,
|
||||
TabCompleteResponsePacket response) {
|
||||
private void finishRegularTabComplete(ServerboundTabCompleteRequestPacket request,
|
||||
ClientboundTabCompleteResponsePacket response) {
|
||||
List<String> offers = new ArrayList<>();
|
||||
for (Offer offer : response.getOffers()) {
|
||||
offers.add(offer.getText());
|
||||
@@ -563,13 +567,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
MinecraftConnection smc = player.ensureAndGetCurrentServer().ensureConnected();
|
||||
String commandToRun = result.getCommand().orElse(originalCommand);
|
||||
if (result.isForwardToServer()) {
|
||||
return CompletableFuture.runAsync(() -> smc.write(ChatPacket.createServerbound("/"
|
||||
return CompletableFuture.runAsync(() -> smc.write(new ServerboundChatPacket("/"
|
||||
+ commandToRun)), smc.eventLoop());
|
||||
} else {
|
||||
return server.getCommandManager().executeImmediately(player, commandToRun)
|
||||
.thenAcceptAsync(hasRun -> {
|
||||
if (!hasRun) {
|
||||
smc.write(ChatPacket.createServerbound("/" + commandToRun));
|
||||
smc.write(new ServerboundChatPacket("/" + commandToRun));
|
||||
}
|
||||
}, smc.eventLoop());
|
||||
}
|
||||
@@ -583,7 +587,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
if (serverConnection != null) {
|
||||
MinecraftConnection connection = serverConnection.getConnection();
|
||||
if (connection != null) {
|
||||
PluginMessagePacket pm;
|
||||
ServerboundPluginMessagePacket pm;
|
||||
while ((pm = loginPluginMessages.poll()) != null) {
|
||||
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.SkinParts;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundClientSettingsPacket;
|
||||
import java.util.Locale;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class ClientSettingsWrapper implements PlayerSettings {
|
||||
|
||||
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 @Nullable Locale locale;
|
||||
|
||||
ClientSettingsWrapper(ClientSettingsPacket settings) {
|
||||
ClientSettingsWrapper(ServerboundClientSettingsPacket settings) {
|
||||
this.settings = settings;
|
||||
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.util.ConnectionMessages;
|
||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
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.KeepAlivePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TitlePacket;
|
||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.network.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundChatPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundKeepAlivePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundResourcePackRequestPacket;
|
||||
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.tablist.VelocityTabList;
|
||||
import com.velocitypowered.proxy.tablist.VelocityTabListLegacy;
|
||||
import com.velocitypowered.proxy.util.DurationUtils;
|
||||
import com.velocitypowered.proxy.util.collect.CappedSet;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@@ -112,7 +113,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
ConnectedPlayer(VelocityServer server, GameProfile profile, MinecraftConnection connection,
|
||||
@Nullable InetSocketAddress virtualHost, boolean onlineMode) {
|
||||
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);
|
||||
} else {
|
||||
this.tabList = new VelocityTabListLegacy(connection);
|
||||
@@ -186,7 +187,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
return settings == null ? ClientSettingsWrapper.DEFAULT : this.settings;
|
||||
}
|
||||
|
||||
void setPlayerSettings(ClientSettingsPacket settings) {
|
||||
void setPlayerSettings(ServerboundClientSettingsPacket settings) {
|
||||
ClientSettingsWrapper cs = new ClientSettingsWrapper(settings);
|
||||
this.settings = cs;
|
||||
server.getEventManager().fireAndForget(new PlayerSettingsChangedEvent(this, cs));
|
||||
@@ -226,41 +227,40 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
return connection.getProtocolVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NonNull Identity identity, @NonNull Component message) {
|
||||
connection.write(ChatPacket.createClientbound(identity, message, this.getProtocolVersion()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NonNull Identity identity, @NonNull Component message,
|
||||
@NonNull MessageType type) {
|
||||
Preconditions.checkNotNull(message, "message");
|
||||
Preconditions.checkNotNull(type, "type");
|
||||
|
||||
ChatPacket packet = ChatPacket.createClientbound(identity, message, this.getProtocolVersion());
|
||||
packet.setType(type == MessageType.CHAT ? ChatPacket.CHAT_TYPE : ChatPacket.SYSTEM_TYPE);
|
||||
connection.write(packet);
|
||||
connection.write(new ClientboundChatPacket(
|
||||
ProtocolUtils.getJsonChatSerializer(this.getProtocolVersion()).serialize(message),
|
||||
type == MessageType.CHAT
|
||||
? ClientboundChatPacket.CHAT_TYPE
|
||||
: ClientboundChatPacket.SYSTEM_TYPE,
|
||||
identity.uuid()
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendActionBar(net.kyori.adventure.text.@NonNull Component message) {
|
||||
ProtocolVersion playerVersion = getProtocolVersion();
|
||||
if (playerVersion.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0) {
|
||||
if (playerVersion.gte(ProtocolVersion.MINECRAFT_1_11)) {
|
||||
// Use the title packet instead.
|
||||
TitlePacket pkt = new TitlePacket();
|
||||
pkt.setAction(TitlePacket.SET_ACTION_BAR);
|
||||
pkt.setComponent(ProtocolUtils.getJsonChatSerializer(playerVersion)
|
||||
.serialize(message));
|
||||
connection.write(pkt);
|
||||
connection.write(new ClientboundTitlePacket(
|
||||
ClientboundTitlePacket.SET_ACTION_BAR,
|
||||
ProtocolUtils.getJsonChatSerializer(playerVersion).serialize(message)
|
||||
));
|
||||
} else {
|
||||
// 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!
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("text", LegacyComponentSerializer.legacySection().serialize(message));
|
||||
ChatPacket chat = new ChatPacket();
|
||||
chat.setMessage(object.toString());
|
||||
chat.setType(ChatPacket.GAME_INFO_TYPE);
|
||||
connection.write(chat);
|
||||
connection.write(new ClientboundChatPacket(
|
||||
object.toString(),
|
||||
ClientboundChatPacket.GAME_INFO_TYPE,
|
||||
Identity.nil().uuid()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,36 +269,32 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
GsonComponentSerializer serializer = ProtocolUtils.getJsonChatSerializer(this
|
||||
.getProtocolVersion());
|
||||
|
||||
TitlePacket titlePkt = new TitlePacket();
|
||||
titlePkt.setAction(TitlePacket.SET_TITLE);
|
||||
titlePkt.setComponent(serializer.serialize(title.title()));
|
||||
connection.delayedWrite(titlePkt);
|
||||
connection.delayedWrite(new ClientboundTitlePacket(
|
||||
ClientboundTitlePacket.SET_TITLE,
|
||||
serializer.serialize(title.title())
|
||||
));
|
||||
|
||||
TitlePacket subtitlePkt = new TitlePacket();
|
||||
subtitlePkt.setAction(TitlePacket.SET_SUBTITLE);
|
||||
subtitlePkt.setComponent(serializer.serialize(title.subtitle()));
|
||||
connection.delayedWrite(subtitlePkt);
|
||||
connection.delayedWrite(new ClientboundTitlePacket(
|
||||
ClientboundTitlePacket.SET_SUBTITLE,
|
||||
serializer.serialize(title.subtitle())
|
||||
));
|
||||
|
||||
TitlePacket timesPkt = TitlePacket.timesForProtocolVersion(this.getProtocolVersion());
|
||||
net.kyori.adventure.title.Title.Times times = title.times();
|
||||
if (times != null) {
|
||||
timesPkt.setFadeIn((int) DurationUtils.toTicks(times.fadeIn()));
|
||||
timesPkt.setStay((int) DurationUtils.toTicks(times.stay()));
|
||||
timesPkt.setFadeOut((int) DurationUtils.toTicks(times.fadeOut()));
|
||||
connection.delayedWrite(ClientboundTitlePacket.times(this.getProtocolVersion(), times));
|
||||
}
|
||||
connection.delayedWrite(timesPkt);
|
||||
|
||||
connection.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearTitle() {
|
||||
connection.write(TitlePacket.hideForProtocolVersion(this.getProtocolVersion()));
|
||||
connection.write(ClientboundTitlePacket.hide(this.getProtocolVersion()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTitle() {
|
||||
connection.write(TitlePacket.resetForProtocolVersion(this.getProtocolVersion()));
|
||||
connection.write(ClientboundTitlePacket.reset(this.getProtocolVersion()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -343,7 +339,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
public void disconnect0(Component reason, boolean duringLogin) {
|
||||
logger.info("{} has disconnected: {}", this,
|
||||
LegacyComponentSerializer.legacySection().serialize(reason));
|
||||
connection.closeWith(DisconnectPacket.create(reason, this.getProtocolVersion()));
|
||||
connection.closeWith(ClientboundDisconnectPacket.create(reason, this.getProtocolVersion()));
|
||||
}
|
||||
|
||||
public @Nullable VelocityServerConnection getConnectedServer() {
|
||||
@@ -402,7 +398,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
* @param disconnect the disconnect packet
|
||||
* @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) {
|
||||
if (!isActive()) {
|
||||
// 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:
|
||||
Component reason = status.getReason()
|
||||
.orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
|
||||
handleConnectionException(res.getServer(), DisconnectPacket.create(reason,
|
||||
handleConnectionException(res.getServer(), ClientboundDisconnectPacket.create(reason,
|
||||
getProtocolVersion()), ((Impl) status).isSafe());
|
||||
break;
|
||||
case SUCCESS:
|
||||
@@ -664,7 +660,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
public boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data) {
|
||||
Preconditions.checkNotNull(identifier, "identifier");
|
||||
Preconditions.checkNotNull(data, "data");
|
||||
PluginMessagePacket message = new PluginMessagePacket(identifier.getId(),
|
||||
ClientboundPluginMessagePacket message = new ClientboundPluginMessagePacket(identifier.getId(),
|
||||
Unpooled.wrappedBuffer(data));
|
||||
connection.write(message);
|
||||
return true;
|
||||
@@ -672,20 +668,17 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
|
||||
@Override
|
||||
public void spoofChatInput(String input) {
|
||||
Preconditions.checkArgument(input.length() <= ChatPacket.MAX_SERVERBOUND_MESSAGE_LENGTH,
|
||||
"input cannot be greater than " + ChatPacket.MAX_SERVERBOUND_MESSAGE_LENGTH
|
||||
Preconditions.checkArgument(input.length() <= ServerboundChatPacket.MAX_MESSAGE_LENGTH,
|
||||
"input cannot be greater than " + ServerboundChatPacket.MAX_MESSAGE_LENGTH
|
||||
+ " characters in length");
|
||||
ensureBackendConnection().write(ChatPacket.createServerbound(input));
|
||||
ensureBackendConnection().write(new ServerboundChatPacket(input));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendResourcePack(String url) {
|
||||
Preconditions.checkNotNull(url, "url");
|
||||
|
||||
ResourcePackRequestPacket request = new ResourcePackRequestPacket();
|
||||
request.setUrl(url);
|
||||
request.setHash("");
|
||||
connection.write(request);
|
||||
connection.write(new ClientboundResourcePackRequestPacket(url, ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -694,22 +687,17 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
Preconditions.checkNotNull(hash, "hash");
|
||||
Preconditions.checkArgument(hash.length == 20, "Hash length is not 20");
|
||||
|
||||
ResourcePackRequestPacket request = new ResourcePackRequestPacket();
|
||||
request.setUrl(url);
|
||||
request.setHash(ByteBufUtil.hexDump(hash));
|
||||
connection.write(request);
|
||||
connection.write(new ClientboundResourcePackRequestPacket(url, ByteBufUtil.hexDump(hash)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* ID last sent by the server.
|
||||
*/
|
||||
public void sendKeepAlive() {
|
||||
if (connection.getState() == StateRegistry.PLAY) {
|
||||
KeepAlivePacket keepAlive = new KeepAlivePacket();
|
||||
keepAlive.setRandomId(ThreadLocalRandom.current().nextLong());
|
||||
connection.write(keepAlive);
|
||||
connection.write(new ClientboundKeepAlivePacket(ThreadLocalRandom.current().nextLong()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,11 +735,11 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
* @param message the plugin message to forward to the client
|
||||
* @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;
|
||||
|
||||
// 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();
|
||||
minecraftOrFmlMessage = channel.startsWith("MC|")
|
||||
|| channel.startsWith(LegacyForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)
|
||||
@@ -880,7 +868,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
case SERVER_DISCONNECTED:
|
||||
Component reason = status.getReason()
|
||||
.orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
|
||||
handleConnectionException(toConnect, DisconnectPacket.create(reason,
|
||||
handleConnectionException(toConnect, ClientboundDisconnectPacket.create(reason,
|
||||
getProtocolVersion()), status.isSafe());
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -12,12 +12,12 @@ import com.velocitypowered.proxy.connection.ConnectionTypes;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyDisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyHandshakePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyPingPacket;
|
||||
import com.velocitypowered.proxy.network.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.packet.Packet;
|
||||
import com.velocitypowered.proxy.network.packet.legacy.LegacyDisconnectPacket;
|
||||
import com.velocitypowered.proxy.network.packet.legacy.LegacyHandshakePacket;
|
||||
import com.velocitypowered.proxy.network.packet.legacy.LegacyPingPacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundHandshakePacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
@@ -58,7 +58,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(HandshakePacket handshake) {
|
||||
public boolean handle(ServerboundHandshakePacket handshake) {
|
||||
InitialInboundConnection ic = new InitialInboundConnection(connection,
|
||||
cleanVhost(handshake.getServerAddress()), handshake);
|
||||
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())) {
|
||||
ic.disconnectQuietly(Component.translatable("multiplayer.disconnect.outdated_client"));
|
||||
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
|
||||
// and lower, otherwise IP information will never get forwarded.
|
||||
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."));
|
||||
return;
|
||||
}
|
||||
@@ -123,12 +123,12 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
||||
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).
|
||||
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;
|
||||
} 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
|
||||
// forge handshake attempts. Also sends a reset handshake packet on every transition.
|
||||
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.backend.BungeeCordMessageResponder;
|
||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.network.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundPluginMessagePacket;
|
||||
|
||||
public class InitialConnectSessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
@@ -15,7 +15,7 @@ public class InitialConnectSessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(PluginMessagePacket packet) {
|
||||
public boolean handle(ServerboundPluginMessagePacket packet) {
|
||||
VelocityServerConnection serverConn = player.getConnectionInFlight();
|
||||
if (serverConn != null) {
|
||||
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.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundHandshakePacket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Optional;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@@ -20,10 +20,10 @@ public final class InitialInboundConnection implements InboundConnection,
|
||||
|
||||
private final MinecraftConnection connection;
|
||||
private final String cleanedAddress;
|
||||
private final HandshakePacket handshake;
|
||||
private final ServerboundHandshakePacket handshake;
|
||||
|
||||
InitialInboundConnection(MinecraftConnection connection, String cleanedAddress,
|
||||
HandshakePacket handshake) {
|
||||
ServerboundHandshakePacket handshake) {
|
||||
this.connection = connection;
|
||||
this.cleanedAddress = cleanedAddress;
|
||||
this.handshake = handshake;
|
||||
@@ -61,7 +61,7 @@ public final class InitialInboundConnection implements InboundConnection,
|
||||
public void disconnect(Component reason) {
|
||||
logger.info("{} has disconnected: {}", this,
|
||||
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
|
||||
*/
|
||||
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.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
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.ServerLoginPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
||||
import com.velocitypowered.proxy.network.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundDisconnectPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundEncryptionRequestPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundServerLoginSuccessPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundSetCompressionPacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundEncryptionResponsePacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundServerLoginPacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.GeneralSecurityException;
|
||||
@@ -58,7 +58,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
private final VelocityServer server;
|
||||
private final MinecraftConnection mcConnection;
|
||||
private final InitialInboundConnection inbound;
|
||||
private @MonotonicNonNull ServerLoginPacket login;
|
||||
private @MonotonicNonNull ServerboundServerLoginPacket login;
|
||||
private byte[] verify = EMPTY_BYTE_ARRAY;
|
||||
private @MonotonicNonNull ConnectedPlayer connectedPlayer;
|
||||
|
||||
@@ -70,15 +70,15 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ServerLoginPacket packet) {
|
||||
public boolean handle(ServerboundServerLoginPacket packet) {
|
||||
this.login = packet;
|
||||
beginPreLogin();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(EncryptionResponsePacket packet) {
|
||||
ServerLoginPacket login = this.login;
|
||||
public boolean handle(ServerboundEncryptionResponsePacket packet) {
|
||||
ServerboundServerLoginPacket login = this.login;
|
||||
if (login == null) {
|
||||
throw new IllegalStateException("No ServerLogin packet received yet.");
|
||||
}
|
||||
@@ -153,7 +153,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
private void beginPreLogin() {
|
||||
ServerLoginPacket login = this.login;
|
||||
ServerboundServerLoginPacket login = this.login;
|
||||
if (login == null) {
|
||||
throw new IllegalStateException("No ServerLogin packet received yet.");
|
||||
}
|
||||
@@ -169,7 +169,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
Optional<Component> disconnectReason = result.getReason();
|
||||
if (disconnectReason.isPresent()) {
|
||||
// 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()));
|
||||
return;
|
||||
}
|
||||
@@ -177,7 +177,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
if (!result.isForceOfflineMode() && (server.getConfiguration().isOnlineMode() || result
|
||||
.isOnlineModeAllowed())) {
|
||||
// Request encryption.
|
||||
EncryptionRequestPacket request = generateEncryptionRequest();
|
||||
ClientboundEncryptionRequestPacket request = generateEncryptionRequest();
|
||||
this.verify = Arrays.copyOf(request.getVerifyToken(), 4);
|
||||
mcConnection.write(request);
|
||||
} else {
|
||||
@@ -190,11 +190,11 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
});
|
||||
}
|
||||
|
||||
private EncryptionRequestPacket generateEncryptionRequest() {
|
||||
private ClientboundEncryptionRequestPacket generateEncryptionRequest() {
|
||||
byte[] verify = new byte[4];
|
||||
ThreadLocalRandom.current().nextBytes(verify);
|
||||
|
||||
EncryptionRequestPacket request = new EncryptionRequestPacket();
|
||||
ClientboundEncryptionRequestPacket request = new ClientboundEncryptionRequestPacket();
|
||||
request.setPublicKey(server.getServerKeyPair().getPublic().getEncoded());
|
||||
request.setVerifyToken(verify);
|
||||
return request;
|
||||
@@ -242,8 +242,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
private void completeLoginProtocolPhaseAndInitialize(ConnectedPlayer player) {
|
||||
int threshold = server.getConfiguration().getCompressionThreshold();
|
||||
if (threshold >= 0 && mcConnection.getProtocolVersion().compareTo(MINECRAFT_1_8) >= 0) {
|
||||
mcConnection.write(new SetCompressionPacket(threshold));
|
||||
if (threshold >= 0 && mcConnection.getProtocolVersion().gte(MINECRAFT_1_8)) {
|
||||
mcConnection.write(new ClientboundSetCompressionPacket(threshold));
|
||||
mcConnection.setCompressionThreshold(threshold);
|
||||
}
|
||||
VelocityConfiguration configuration = server.getConfiguration();
|
||||
@@ -251,10 +251,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.NONE) {
|
||||
playerUniqueId = UuidUtils.generateOfflinePlayerUuid(player.getUsername());
|
||||
}
|
||||
ServerLoginSuccessPacket success = new ServerLoginSuccessPacket();
|
||||
success.setUsername(player.getUsername());
|
||||
success.setUuid(playerUniqueId);
|
||||
mcConnection.write(success);
|
||||
mcConnection.write(new ClientboundServerLoginSuccessPacket(playerUniqueId, player.getUsername()));
|
||||
|
||||
mcConnection.setAssociation(player);
|
||||
mcConnection.setState(StateRegistry.PLAY);
|
||||
|
||||
@@ -13,11 +13,11 @@ import com.velocitypowered.proxy.config.PingPassthroughMode;
|
||||
import com.velocitypowered.proxy.config.VelocityConfiguration;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
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.legacy.LegacyDisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.legacy.LegacyPingPacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundStatusResponsePacket;
|
||||
import com.velocitypowered.proxy.network.packet.legacy.LegacyDisconnectPacket;
|
||||
import com.velocitypowered.proxy.network.packet.legacy.LegacyPingPacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundStatusPingPacket;
|
||||
import com.velocitypowered.proxy.network.packet.serverbound.ServerboundStatusRequestPacket;
|
||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -176,13 +176,13 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(StatusPingPacket packet) {
|
||||
public boolean handle(ServerboundStatusPingPacket packet) {
|
||||
connection.closeWith(packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(StatusRequestPacket packet) {
|
||||
public boolean handle(ServerboundStatusRequestPacket packet) {
|
||||
if (this.pingReceived) {
|
||||
throw EXPECTED_AWAITING_REQUEST;
|
||||
}
|
||||
@@ -195,7 +195,7 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
|
||||
StringBuilder json = new StringBuilder();
|
||||
VelocityServer.getPingGsonInstance(connection.getProtocolVersion())
|
||||
.toJson(event.getPing(), json);
|
||||
connection.write(new StatusResponsePacket(json));
|
||||
connection.write(new ClientboundStatusResponsePacket(json));
|
||||
},
|
||||
connection.eventLoop())
|
||||
.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.VelocityServerConnection;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -107,7 +107,7 @@ public enum LegacyForgeHandshakeBackendPhase implements BackendConnectionPhase {
|
||||
@Override
|
||||
public final boolean handle(VelocityServerConnection serverConnection,
|
||||
ConnectedPlayer player,
|
||||
PluginMessagePacket message) {
|
||||
AbstractPluginMessagePacket<?> message) {
|
||||
if (message.getChannel().equals(LegacyForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)) {
|
||||
// Get the phase and check if we need to start the next phase.
|
||||
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.
|
||||
*/
|
||||
private LegacyForgeHandshakeBackendPhase getNewPhase(VelocityServerConnection serverConnection,
|
||||
PluginMessagePacket packet) {
|
||||
AbstractPluginMessagePacket<?> packet) {
|
||||
if (packetToAdvanceOn != null
|
||||
&& LegacyForgeUtil.getHandshakePacketDiscriminator(packet) == packetToAdvanceOn) {
|
||||
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.ClientPlaySessionHandler;
|
||||
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 javax.annotation.Nullable;
|
||||
|
||||
@@ -39,7 +39,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
||||
|
||||
@Override
|
||||
boolean onHandle(ConnectedPlayer player,
|
||||
PluginMessagePacket message,
|
||||
AbstractPluginMessagePacket<?> message,
|
||||
MinecraftConnection backendConn) {
|
||||
// If we stay in this phase, we do nothing because it means the packet wasn't handled.
|
||||
// Returning false indicates this
|
||||
@@ -73,7 +73,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
||||
|
||||
@Override
|
||||
boolean onHandle(ConnectedPlayer player,
|
||||
PluginMessagePacket message,
|
||||
AbstractPluginMessagePacket<?> message,
|
||||
MinecraftConnection backendConn) {
|
||||
// Read the mod list if we haven't already.
|
||||
if (!player.getModInfo().isPresent()) {
|
||||
@@ -147,7 +147,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
||||
|
||||
@Override
|
||||
boolean onHandle(ConnectedPlayer player,
|
||||
PluginMessagePacket message,
|
||||
AbstractPluginMessagePacket<?> message,
|
||||
MinecraftConnection backendConn) {
|
||||
super.onHandle(player, message, backendConn);
|
||||
|
||||
@@ -180,7 +180,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
||||
|
||||
@Override
|
||||
public final boolean handle(ConnectedPlayer player,
|
||||
PluginMessagePacket message,
|
||||
AbstractPluginMessagePacket<?> message,
|
||||
VelocityServerConnection server) {
|
||||
if (server != null) {
|
||||
MinecraftConnection backendConn = server.getConnection();
|
||||
@@ -211,7 +211,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
||||
* @return true if handled, false otherwise.
|
||||
*/
|
||||
boolean onHandle(ConnectedPlayer player,
|
||||
PluginMessagePacket message,
|
||||
AbstractPluginMessagePacket<?> message,
|
||||
MinecraftConnection backendConn) {
|
||||
// Send the packet on to the server.
|
||||
backendConn.write(message.retain());
|
||||
@@ -241,7 +241,7 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
||||
* @param packet The packet
|
||||
* @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
|
||||
&& LegacyForgeUtil.getHandshakePacketDiscriminator(packet) == packetToAdvanceOn) {
|
||||
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.collect.ImmutableList;
|
||||
import com.velocitypowered.api.util.ModInfo;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.clientbound.ClientboundPluginMessagePacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.util.List;
|
||||
@@ -25,7 +26,7 @@ class LegacyForgeUtil {
|
||||
* @param message The message to analyse
|
||||
* @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.content().isReadable());
|
||||
return message.content().getByte(0);
|
||||
@@ -37,7 +38,7 @@ class LegacyForgeUtil {
|
||||
* @param message The message
|
||||
* @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.checkArgument(message.getChannel().equals(FORGE_LEGACY_HANDSHAKE_CHANNEL),
|
||||
"message is not a FML HS plugin message");
|
||||
@@ -65,10 +66,10 @@ class LegacyForgeUtil {
|
||||
*
|
||||
* @return A copy of the reset packet
|
||||
*/
|
||||
static PluginMessagePacket resetPacket() {
|
||||
PluginMessagePacket msg = new PluginMessagePacket();
|
||||
msg.setChannel(FORGE_LEGACY_HANDSHAKE_CHANNEL);
|
||||
msg.replace(Unpooled.wrappedBuffer(FORGE_LEGACY_HANDSHAKE_RESET_DATA.clone()));
|
||||
return msg;
|
||||
static AbstractPluginMessagePacket<?> resetPacket() {
|
||||
return new ClientboundPluginMessagePacket(
|
||||
FORGE_LEGACY_HANDSHAKE_CHANNEL,
|
||||
Unpooled.wrappedBuffer(FORGE_LEGACY_HANDSHAKE_RESET_DATA.clone())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ public final class DimensionData {
|
||||
String registryIdentifier = dimTag.getString("name");
|
||||
CompoundBinaryTag details;
|
||||
Integer dimensionId = null;
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||
dimensionId = dimTag.getInt("id");
|
||||
details = dimTag.getCompound("element");
|
||||
} else {
|
||||
@@ -243,7 +243,7 @@ public final class DimensionData {
|
||||
*/
|
||||
public CompoundBinaryTag encodeAsCompoundTag(ProtocolVersion version) {
|
||||
CompoundBinaryTag details = serializeDimensionDetails();
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||
if (dimensionId == null) {
|
||||
throw new IllegalStateException("Tried to serialize a 1.16.2+ dimension registry entry "
|
||||
+ "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.Status;
|
||||
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 javax.annotation.Nullable;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@@ -41,12 +41,12 @@ public class ConnectionRequestResults {
|
||||
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());
|
||||
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());
|
||||
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 com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.netty.AutoReadHolderHandler;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintFrameDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintLengthEncoder;
|
||||
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||
import com.velocitypowered.proxy.network.pipeline.AutoReadHolderHandler;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftEncoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftVarintFrameDecoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftVarintLengthEncoder;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
@@ -37,9 +37,9 @@ public class BackendChannelInitializer extends ChannelInitializer<Channel> {
|
||||
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
|
||||
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
|
||||
.addLast(MINECRAFT_DECODER,
|
||||
new MinecraftDecoder(ProtocolDirection.CLIENTBOUND))
|
||||
new MinecraftDecoder(PacketDirection.CLIENTBOUND))
|
||||
.addLast(FLOW_HANDLER, new AutoReadHolderHandler())
|
||||
.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.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);
|
||||
private ChannelInitializer<Channel> initializer;
|
||||
|
||||
BackendChannelInitializerHolder(final ChannelInitializer<Channel> initializer) {
|
||||
ChannelInitializerHolder(final String name, final ChannelInitializer<C> initializer) {
|
||||
this.name = name;
|
||||
this.initializer = initializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelInitializer<Channel> get() {
|
||||
public ChannelInitializer<C> get() {
|
||||
return this.initializer;
|
||||
}
|
||||
|
||||
@@ -27,8 +28,8 @@ public class BackendChannelInitializerHolder implements Supplier<ChannelInitiali
|
||||
* @deprecated Internal implementation detail
|
||||
*/
|
||||
@Deprecated
|
||||
public void set(final ChannelInitializer<Channel> initializer) {
|
||||
LOGGER.warn("The backend channel initializer has been replaced by {}",
|
||||
public void set(final ChannelInitializer<C> initializer) {
|
||||
LOGGER.warn("The {} initializer has been replaced by {}", this.name,
|
||||
Thread.currentThread().getStackTrace()[2]);
|
||||
this.initializer = initializer;
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import static org.asynchttpclient.Dsl.config;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.velocitypowered.natives.util.Natives;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.network.netty.SeparatePoolInetNameResolver;
|
||||
import com.velocitypowered.proxy.protocol.netty.GS4QueryHandler;
|
||||
import com.velocitypowered.proxy.network.pipeline.GS4QueryHandler;
|
||||
import com.velocitypowered.proxy.network.resolver.SeparatePoolInetNameResolver;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
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
|
||||
// protocol logic into the proxy.
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public final ServerChannelInitializerHolder serverChannelInitializer;
|
||||
public final ChannelInitializerHolder<Channel> serverChannelInitializer;
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public final BackendChannelInitializerHolder backendChannelInitializer;
|
||||
public final ChannelInitializerHolder<Channel> backendChannelInitializer;
|
||||
|
||||
private final SeparatePoolInetNameResolver resolver;
|
||||
private final AsyncHttpClient httpClient;
|
||||
@@ -60,9 +60,9 @@ public final class ConnectionManager {
|
||||
this.transportType = TransportType.bestType();
|
||||
this.bossGroup = this.transportType.createEventLoopGroup(TransportType.Type.BOSS);
|
||||
this.workerGroup = this.transportType.createEventLoopGroup(TransportType.Type.WORKER);
|
||||
this.serverChannelInitializer = new ServerChannelInitializerHolder(
|
||||
this.serverChannelInitializer = new ChannelInitializerHolder<>("server channel",
|
||||
new ServerChannelInitializer(this.server));
|
||||
this.backendChannelInitializer = new BackendChannelInitializerHolder(
|
||||
this.backendChannelInitializer = new ChannelInitializerHolder<>("backend channel",
|
||||
new BackendChannelInitializer(this.server));
|
||||
this.resolver = new SeparatePoolInetNameResolver(GlobalEventExecutor.INSTANCE);
|
||||
this.httpClient = asyncHttpClient(config()
|
||||
@@ -198,7 +198,7 @@ public final class ConnectionManager {
|
||||
return bossGroup;
|
||||
}
|
||||
|
||||
public ServerChannelInitializerHolder getServerChannelInitializer() {
|
||||
public ChannelInitializerHolder<Channel> getServerChannelInitializer() {
|
||||
return this.serverChannelInitializer;
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ public final class ConnectionManager {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public BackendChannelInitializerHolder getBackendChannelInitializer() {
|
||||
public ChannelInitializerHolder<Channel> getBackendChannelInitializer() {
|
||||
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.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||
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.checkNotNull;
|
||||
@@ -6,8 +6,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.api.util.ProxyVersion;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.network.packet.AbstractPluginMessagePacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -34,7 +33,7 @@ public final class PluginMessageUtil {
|
||||
* @param message the 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");
|
||||
return message.getChannel().equals(BRAND_CHANNEL_LEGACY) || message.getChannel()
|
||||
.equals(BRAND_CHANNEL);
|
||||
@@ -45,7 +44,7 @@ public final class PluginMessageUtil {
|
||||
* @param message the plugin message
|
||||
* @return whether we are registering plugin channels or not
|
||||
*/
|
||||
public static boolean isRegister(PluginMessagePacket message) {
|
||||
public static boolean isRegister(AbstractPluginMessagePacket<?> message) {
|
||||
checkNotNull(message, "message");
|
||||
return message.getChannel().equals(REGISTER_CHANNEL_LEGACY) || message.getChannel()
|
||||
.equals(REGISTER_CHANNEL);
|
||||
@@ -56,7 +55,7 @@ public final class PluginMessageUtil {
|
||||
* @param message the plugin message
|
||||
* @return whether we are unregistering plugin channels or not
|
||||
*/
|
||||
public static boolean isUnregister(PluginMessagePacket message) {
|
||||
public static boolean isUnregister(AbstractPluginMessagePacket<?> message) {
|
||||
checkNotNull(message, "message");
|
||||
return message.getChannel().equals(UNREGISTER_CHANNEL_LEGACY) || message.getChannel()
|
||||
.equals(UNREGISTER_CHANNEL);
|
||||
@@ -67,7 +66,7 @@ public final class PluginMessageUtil {
|
||||
* @param message the plugin message
|
||||
* @return whether this is a legacy register message
|
||||
*/
|
||||
public static boolean isLegacyRegister(PluginMessagePacket message) {
|
||||
public static boolean isLegacyRegister(AbstractPluginMessagePacket<?> message) {
|
||||
checkNotNull(message, "message");
|
||||
return message.getChannel().equals(REGISTER_CHANNEL_LEGACY);
|
||||
}
|
||||
@@ -78,7 +77,7 @@ public final class PluginMessageUtil {
|
||||
* @param message the plugin message
|
||||
* @return whether this is a legacy unregister message
|
||||
*/
|
||||
public static boolean isLegacyUnregister(PluginMessagePacket message) {
|
||||
public static boolean isLegacyUnregister(AbstractPluginMessagePacket<?> message) {
|
||||
checkNotNull(message, "message");
|
||||
return message.getChannel().equals(UNREGISTER_CHANNEL_LEGACY);
|
||||
}
|
||||
@@ -88,7 +87,7 @@ public final class PluginMessageUtil {
|
||||
* @param message the message to get the channels from
|
||||
* @return the channels, as an immutable list
|
||||
*/
|
||||
public static List<String> getChannels(PluginMessagePacket message) {
|
||||
public static List<String> getChannels(AbstractPluginMessagePacket<?> message) {
|
||||
checkNotNull(message, "message");
|
||||
checkArgument(isRegister(message) || isUnregister(message), "Unknown channel type %s",
|
||||
message.getChannel());
|
||||
@@ -107,15 +106,16 @@ public final class PluginMessageUtil {
|
||||
* @param channels the channels to register
|
||||
* @return the plugin message to send
|
||||
*/
|
||||
public static PluginMessagePacket constructChannelsPacket(ProtocolVersion protocolVersion,
|
||||
Collection<String> channels) {
|
||||
public static AbstractPluginMessagePacket<?> constructChannelsPacket(ProtocolVersion protocolVersion,
|
||||
Collection<String> channels,
|
||||
AbstractPluginMessagePacket.Factory<?> factory) {
|
||||
checkNotNull(channels, "channels");
|
||||
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;
|
||||
ByteBuf contents = Unpooled.buffer();
|
||||
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
|
||||
* @return the rewritten plugin message
|
||||
*/
|
||||
public static PluginMessagePacket rewriteMinecraftBrand(PluginMessagePacket message,
|
||||
public static AbstractPluginMessagePacket<?> rewriteMinecraftBrand(AbstractPluginMessagePacket<?> message,
|
||||
ProxyVersion version,
|
||||
ProtocolVersion protocolVersion) {
|
||||
ProtocolVersion protocolVersion,
|
||||
AbstractPluginMessagePacket.Factory<?> factory) {
|
||||
checkNotNull(message, "message");
|
||||
checkNotNull(version, "version");
|
||||
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());
|
||||
|
||||
ByteBuf rewrittenBuf = Unpooled.buffer();
|
||||
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
||||
if (protocolVersion.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||
ProtocolUtils.writeString(rewrittenBuf, rewrittenBrand);
|
||||
} else {
|
||||
rewrittenBuf.writeCharSequence(rewrittenBrand, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
return new PluginMessagePacket(message.getChannel(), rewrittenBuf);
|
||||
return factory.create(message.getChannel(), rewrittenBuf);
|
||||
}
|
||||
|
||||
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.velocitypowered.proxy.protocol.util.NettyPreconditions.checkFrame;
|
||||
import static com.velocitypowered.proxy.network.NettyPreconditions.checkFrame;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.api.util.GameProfile;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.protocol.util.VelocityLegacyHoverEventSerializer;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.network.serialization.VelocityLegacyHoverEventSerializer;
|
||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
@@ -459,7 +459,7 @@ public enum ProtocolUtils {
|
||||
* @return the appropriate {@link GsonComponentSerializer}
|
||||
*/
|
||||
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 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.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.netty.LegacyPingDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.LegacyPingEncoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintFrameDecoder;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftVarintLengthEncoder;
|
||||
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||
import com.velocitypowered.proxy.network.pipeline.LegacyPingDecoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.LegacyPingEncoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftEncoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftVarintFrameDecoder;
|
||||
import com.velocitypowered.proxy.network.pipeline.MinecraftVarintLengthEncoder;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
|
||||
@@ -43,8 +43,8 @@ public class ServerChannelInitializer extends ChannelInitializer<Channel> {
|
||||
.addLast(FRAME_DECODER, new MinecraftVarintFrameDecoder())
|
||||
.addLast(LEGACY_PING_ENCODER, LegacyPingEncoder.INSTANCE)
|
||||
.addLast(FRAME_ENCODER, MinecraftVarintLengthEncoder.INSTANCE)
|
||||
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(ProtocolDirection.SERVERBOUND))
|
||||
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(ProtocolDirection.CLIENTBOUND));
|
||||
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(PacketDirection.SERVERBOUND))
|
||||
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(PacketDirection.CLIENTBOUND));
|
||||
|
||||
final MinecraftConnection connection = new MinecraftConnection(ch, 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.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 com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
||||
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.network.packet.Packet;
|
||||
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||
import com.velocitypowered.proxy.network.packet.PacketReader;
|
||||
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.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;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.util.collection.IntObjectHashMap;
|
||||
import io.netty.util.collection.IntObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
@@ -52,133 +60,188 @@ import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public enum StateRegistry {
|
||||
|
||||
HANDSHAKE {
|
||||
HANDSHAKE(true) {
|
||||
{
|
||||
serverbound.register(HandshakePacket.class, HandshakePacket::new,
|
||||
map(0x00, MINECRAFT_1_7_2, false));
|
||||
serverbound.register(
|
||||
ServerboundHandshakePacket.class,
|
||||
ServerboundHandshakePacket.DECODER,
|
||||
map(0x00, MINECRAFT_1_7_2, false)
|
||||
);
|
||||
}
|
||||
},
|
||||
STATUS {
|
||||
STATUS(true) {
|
||||
{
|
||||
serverbound.register(StatusRequestPacket.class, () -> StatusRequestPacket.INSTANCE,
|
||||
map(0x00, MINECRAFT_1_7_2, false));
|
||||
serverbound.register(StatusPingPacket.class, StatusPingPacket::new,
|
||||
map(0x01, MINECRAFT_1_7_2, false));
|
||||
serverbound.register(
|
||||
ServerboundStatusRequestPacket.class,
|
||||
ServerboundStatusRequestPacket.DECODER,
|
||||
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,
|
||||
map(0x00, MINECRAFT_1_7_2, false));
|
||||
clientbound.register(StatusPingPacket.class, StatusPingPacket::new,
|
||||
map(0x01, MINECRAFT_1_7_2, false));
|
||||
clientbound.register(
|
||||
ClientboundStatusResponsePacket.class,
|
||||
ClientboundStatusResponsePacket.DECODER,
|
||||
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;
|
||||
clientbound.fallback = false;
|
||||
|
||||
serverbound.register(TabCompleteRequestPacket.class, TabCompleteRequestPacket::new,
|
||||
serverbound.register(
|
||||
ServerboundTabCompleteRequestPacket.class,
|
||||
ServerboundTabCompleteRequestPacket.DECODER,
|
||||
map(0x14, MINECRAFT_1_7_2, false),
|
||||
map(0x01, MINECRAFT_1_9, false),
|
||||
map(0x02, MINECRAFT_1_12, false),
|
||||
map(0x01, MINECRAFT_1_12_1, false),
|
||||
map(0x05, MINECRAFT_1_13, false),
|
||||
map(0x06, MINECRAFT_1_14, false));
|
||||
serverbound.register(ChatPacket.class, ChatPacket::new,
|
||||
map(0x06, MINECRAFT_1_14, false)
|
||||
);
|
||||
serverbound.register(
|
||||
ServerboundChatPacket.class,
|
||||
ServerboundChatPacket.DECODER,
|
||||
map(0x01, MINECRAFT_1_7_2, false),
|
||||
map(0x02, MINECRAFT_1_9, false),
|
||||
map(0x03, MINECRAFT_1_12, false),
|
||||
map(0x02, MINECRAFT_1_12_1, false),
|
||||
map(0x03, MINECRAFT_1_14, false));
|
||||
serverbound.register(ClientSettingsPacket.class, ClientSettingsPacket::new,
|
||||
map(0x03, MINECRAFT_1_14, false)
|
||||
);
|
||||
serverbound.register(
|
||||
ServerboundClientSettingsPacket.class,
|
||||
ServerboundClientSettingsPacket.DECODER,
|
||||
map(0x15, MINECRAFT_1_7_2, false),
|
||||
map(0x04, MINECRAFT_1_9, false),
|
||||
map(0x05, MINECRAFT_1_12, false),
|
||||
map(0x04, MINECRAFT_1_12_1, false),
|
||||
map(0x05, MINECRAFT_1_14, false));
|
||||
serverbound.register(PluginMessagePacket.class, PluginMessagePacket::new,
|
||||
map(0x05, MINECRAFT_1_14, false)
|
||||
);
|
||||
serverbound.register(
|
||||
ServerboundPluginMessagePacket.class,
|
||||
ServerboundPluginMessagePacket.DECODER,
|
||||
map(0x17, MINECRAFT_1_7_2, false),
|
||||
map(0x09, MINECRAFT_1_9, false),
|
||||
map(0x0A, MINECRAFT_1_12, false),
|
||||
map(0x09, MINECRAFT_1_12_1, false),
|
||||
map(0x0A, MINECRAFT_1_13, false),
|
||||
map(0x0B, MINECRAFT_1_14, false));
|
||||
serverbound.register(KeepAlivePacket.class, KeepAlivePacket::new,
|
||||
map(0x0B, MINECRAFT_1_14, false)
|
||||
);
|
||||
serverbound.register(
|
||||
ServerboundKeepAlivePacket.class,
|
||||
ServerboundKeepAlivePacket.DECODER,
|
||||
map(0x00, MINECRAFT_1_7_2, false),
|
||||
map(0x0B, MINECRAFT_1_9, false),
|
||||
map(0x0C, MINECRAFT_1_12, false),
|
||||
map(0x0B, MINECRAFT_1_12_1, false),
|
||||
map(0x0E, MINECRAFT_1_13, false),
|
||||
map(0x0F, MINECRAFT_1_14, false),
|
||||
map(0x10, MINECRAFT_1_16, false));
|
||||
serverbound.register(ResourcePackResponsePacket.class, ResourcePackResponsePacket::new,
|
||||
map(0x10, MINECRAFT_1_16, false)
|
||||
);
|
||||
serverbound.register(
|
||||
ServerboundResourcePackResponsePacket.class,
|
||||
ServerboundResourcePackResponsePacket.DECODER,
|
||||
map(0x19, MINECRAFT_1_8, false),
|
||||
map(0x16, MINECRAFT_1_9, false),
|
||||
map(0x18, MINECRAFT_1_12, false),
|
||||
map(0x1D, MINECRAFT_1_13, false),
|
||||
map(0x1F, MINECRAFT_1_14, 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(0x0D, MINECRAFT_1_15, false),
|
||||
map(0x0C, MINECRAFT_1_16, false));
|
||||
clientbound.register(ChatPacket.class, ChatPacket::new,
|
||||
map(0x0C, MINECRAFT_1_16, false)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundChatPacket.class,
|
||||
ClientboundChatPacket.DECODER,
|
||||
map(0x02, MINECRAFT_1_7_2, true),
|
||||
map(0x0F, MINECRAFT_1_9, true),
|
||||
map(0x0E, MINECRAFT_1_13, true),
|
||||
map(0x0F, MINECRAFT_1_15, true),
|
||||
map(0x0E, MINECRAFT_1_16, true));
|
||||
clientbound.register(TabCompleteResponsePacket.class, TabCompleteResponsePacket::new,
|
||||
map(0x0E, MINECRAFT_1_16, true)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundTabCompleteResponsePacket.class,
|
||||
ClientboundTabCompleteResponsePacket.DECODER,
|
||||
map(0x3A, MINECRAFT_1_7_2, false),
|
||||
map(0x0E, MINECRAFT_1_9, false),
|
||||
map(0x10, MINECRAFT_1_13, false),
|
||||
map(0x11, MINECRAFT_1_15, false),
|
||||
map(0x10, MINECRAFT_1_16, false),
|
||||
map(0x0F, MINECRAFT_1_16_2, false));
|
||||
clientbound.register(AvailableCommandsPacket.class, AvailableCommandsPacket::new,
|
||||
map(0x0F, MINECRAFT_1_16_2, false)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundAvailableCommandsPacket.class,
|
||||
ClientboundAvailableCommandsPacket.DECODER,
|
||||
map(0x11, MINECRAFT_1_13, false),
|
||||
map(0x12, MINECRAFT_1_15, false),
|
||||
map(0x11, MINECRAFT_1_16, false),
|
||||
map(0x10, MINECRAFT_1_16_2, false));
|
||||
clientbound.register(PluginMessagePacket.class, PluginMessagePacket::new,
|
||||
map(0x10, MINECRAFT_1_16_2, false)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundPluginMessagePacket.class,
|
||||
ClientboundPluginMessagePacket.DECODER,
|
||||
map(0x3F, MINECRAFT_1_7_2, false),
|
||||
map(0x18, MINECRAFT_1_9, false),
|
||||
map(0x19, MINECRAFT_1_13, false),
|
||||
map(0x18, MINECRAFT_1_14, false),
|
||||
map(0x19, MINECRAFT_1_15, false),
|
||||
map(0x18, MINECRAFT_1_16, false),
|
||||
map(0x17, MINECRAFT_1_16_2, false));
|
||||
clientbound.register(DisconnectPacket.class, DisconnectPacket::new,
|
||||
map(0x17, MINECRAFT_1_16_2, false)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundDisconnectPacket.class,
|
||||
ClientboundDisconnectPacket.DECODER,
|
||||
map(0x40, MINECRAFT_1_7_2, false),
|
||||
map(0x1A, MINECRAFT_1_9, false),
|
||||
map(0x1B, MINECRAFT_1_13, false),
|
||||
map(0x1A, MINECRAFT_1_14, false),
|
||||
map(0x1B, MINECRAFT_1_15, false),
|
||||
map(0x1A, MINECRAFT_1_16, false),
|
||||
map(0x19, MINECRAFT_1_16_2, false));
|
||||
clientbound.register(KeepAlivePacket.class, KeepAlivePacket::new,
|
||||
map(0x19, MINECRAFT_1_16_2, false)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundKeepAlivePacket.class,
|
||||
ClientboundKeepAlivePacket.DECODER,
|
||||
map(0x00, MINECRAFT_1_7_2, false),
|
||||
map(0x1F, MINECRAFT_1_9, false),
|
||||
map(0x21, MINECRAFT_1_13, false),
|
||||
map(0x20, MINECRAFT_1_14, false),
|
||||
map(0x21, MINECRAFT_1_15, false),
|
||||
map(0x20, MINECRAFT_1_16, false),
|
||||
map(0x1F, MINECRAFT_1_16_2, false));
|
||||
clientbound.register(JoinGamePacket.class, JoinGamePacket::new,
|
||||
map(0x1F, MINECRAFT_1_16_2, false)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundJoinGamePacket.class,
|
||||
ClientboundJoinGamePacket.DECODER,
|
||||
map(0x01, MINECRAFT_1_7_2, false),
|
||||
map(0x23, MINECRAFT_1_9, false),
|
||||
map(0x25, MINECRAFT_1_13, false),
|
||||
map(0x25, MINECRAFT_1_14, false),
|
||||
map(0x26, MINECRAFT_1_15, false),
|
||||
map(0x25, MINECRAFT_1_16, false),
|
||||
map(0x24, MINECRAFT_1_16_2, false));
|
||||
clientbound.register(RespawnPacket.class, RespawnPacket::new,
|
||||
map(0x24, MINECRAFT_1_16_2, false)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundRespawnPacket.class,
|
||||
ClientboundRespawnPacket.DECODER,
|
||||
map(0x07, MINECRAFT_1_7_2, true),
|
||||
map(0x33, MINECRAFT_1_9, true),
|
||||
map(0x34, MINECRAFT_1_12, true),
|
||||
@@ -187,8 +250,11 @@ public enum StateRegistry {
|
||||
map(0x3A, MINECRAFT_1_14, true),
|
||||
map(0x3B, MINECRAFT_1_15, true),
|
||||
map(0x3A, MINECRAFT_1_16, true),
|
||||
map(0x39, MINECRAFT_1_16_2, true));
|
||||
clientbound.register(ResourcePackRequestPacket.class, ResourcePackRequestPacket::new,
|
||||
map(0x39, MINECRAFT_1_16_2, true)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundResourcePackRequestPacket.class,
|
||||
ClientboundResourcePackRequestPacket.DECODER,
|
||||
map(0x48, MINECRAFT_1_8, true),
|
||||
map(0x32, MINECRAFT_1_9, true),
|
||||
map(0x33, MINECRAFT_1_12, true),
|
||||
@@ -197,8 +263,11 @@ public enum StateRegistry {
|
||||
map(0x39, MINECRAFT_1_14, true),
|
||||
map(0x3A, MINECRAFT_1_15, true),
|
||||
map(0x39, MINECRAFT_1_16, true),
|
||||
map(0x38, MINECRAFT_1_16_2, true));
|
||||
clientbound.register(HeaderAndFooterPacket.class, HeaderAndFooterPacket::new,
|
||||
map(0x38, MINECRAFT_1_16_2, true)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundHeaderAndFooterPacket.class,
|
||||
ClientboundHeaderAndFooterPacket.DECODER,
|
||||
map(0x47, MINECRAFT_1_8, true),
|
||||
map(0x48, MINECRAFT_1_9, true),
|
||||
map(0x47, MINECRAFT_1_9_4, true),
|
||||
@@ -207,8 +276,11 @@ public enum StateRegistry {
|
||||
map(0x4E, MINECRAFT_1_13, true),
|
||||
map(0x53, MINECRAFT_1_14, true),
|
||||
map(0x54, MINECRAFT_1_15, true),
|
||||
map(0x53, MINECRAFT_1_16, true));
|
||||
clientbound.register(TitlePacket.class, TitlePacket::new,
|
||||
map(0x53, MINECRAFT_1_16, true)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundTitlePacket.class,
|
||||
ClientboundTitlePacket.DECODER,
|
||||
map(0x45, MINECRAFT_1_8, true),
|
||||
map(0x45, MINECRAFT_1_9, true),
|
||||
map(0x47, MINECRAFT_1_12, true),
|
||||
@@ -216,8 +288,11 @@ public enum StateRegistry {
|
||||
map(0x4B, MINECRAFT_1_13, true),
|
||||
map(0x4F, MINECRAFT_1_14, true),
|
||||
map(0x50, MINECRAFT_1_15, true),
|
||||
map(0x4F, MINECRAFT_1_16, true));
|
||||
clientbound.register(PlayerListItemPacket.class, PlayerListItemPacket::new,
|
||||
map(0x4F, MINECRAFT_1_16, true)
|
||||
);
|
||||
clientbound.register(
|
||||
ClientboundPlayerListItemPacket.class,
|
||||
ClientboundPlayerListItemPacket.DECODER,
|
||||
map(0x38, MINECRAFT_1_7_2, false),
|
||||
map(0x2D, MINECRAFT_1_9, false),
|
||||
map(0x2E, MINECRAFT_1_12_1, false),
|
||||
@@ -225,49 +300,85 @@ public enum StateRegistry {
|
||||
map(0x33, MINECRAFT_1_14, false),
|
||||
map(0x34, MINECRAFT_1_15, 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,
|
||||
map(0x00, MINECRAFT_1_7_2, false));
|
||||
serverbound.register(EncryptionResponsePacket.class, EncryptionResponsePacket::new,
|
||||
map(0x01, MINECRAFT_1_7_2, false));
|
||||
serverbound.register(LoginPluginResponsePacket.class, LoginPluginResponsePacket::new,
|
||||
map(0x02, MINECRAFT_1_13, false));
|
||||
clientbound.register(DisconnectPacket.class, DisconnectPacket::new,
|
||||
map(0x00, MINECRAFT_1_7_2, false));
|
||||
clientbound.register(EncryptionRequestPacket.class, EncryptionRequestPacket::new,
|
||||
map(0x01, MINECRAFT_1_7_2, false));
|
||||
clientbound.register(ServerLoginSuccessPacket.class, ServerLoginSuccessPacket::new,
|
||||
map(0x02, MINECRAFT_1_7_2, false));
|
||||
clientbound.register(SetCompressionPacket.class, SetCompressionPacket::new,
|
||||
map(0x03, MINECRAFT_1_8, false));
|
||||
clientbound.register(LoginPluginMessagePacket.class, LoginPluginMessagePacket::new,
|
||||
map(0x04, MINECRAFT_1_13, false));
|
||||
serverbound.register(
|
||||
ServerboundServerLoginPacket.class,
|
||||
ServerboundServerLoginPacket.DECODER,
|
||||
map(0x00, MINECRAFT_1_7_2, false)
|
||||
);
|
||||
serverbound.register(
|
||||
ServerboundEncryptionResponsePacket.class,
|
||||
ServerboundEncryptionResponsePacket.DECODER,
|
||||
map(0x01, MINECRAFT_1_7_2, false)
|
||||
);
|
||||
serverbound.register(
|
||||
ServerboundLoginPluginResponsePacket.class,
|
||||
ServerboundLoginPluginResponsePacket.DECODER,
|
||||
map(0x02, 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 LOGIN_ID = 2;
|
||||
public final PacketRegistry clientbound = new PacketRegistry(ProtocolDirection.CLIENTBOUND);
|
||||
public final PacketRegistry serverbound = new PacketRegistry(ProtocolDirection.SERVERBOUND);
|
||||
public final PacketRegistry clientbound;
|
||||
public final PacketRegistry serverbound;
|
||||
|
||||
public PacketRegistry.ProtocolRegistry getProtocolRegistry(ProtocolDirection direction,
|
||||
ProtocolVersion version) {
|
||||
return (direction == ProtocolDirection.SERVERBOUND ? this.serverbound : this.clientbound)
|
||||
StateRegistry(boolean useMinimumIfVersionNotFound) {
|
||||
this.clientbound = new PacketRegistry(PacketDirection.CLIENTBOUND, useMinimumIfVersionNotFound);
|
||||
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);
|
||||
}
|
||||
|
||||
public static class PacketRegistry {
|
||||
|
||||
private final ProtocolDirection direction;
|
||||
private final PacketDirection direction;
|
||||
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.useMinimumIfVersionNotFound = useMinimumIfVersionNotFound;
|
||||
|
||||
Map<ProtocolVersion, ProtocolRegistry> mutableVersions = new EnumMap<>(ProtocolVersion.class);
|
||||
for (ProtocolVersion version : ProtocolVersion.values()) {
|
||||
@@ -282,7 +393,7 @@ public enum StateRegistry {
|
||||
ProtocolRegistry getProtocolRegistry(final ProtocolVersion version) {
|
||||
ProtocolRegistry registry = versions.get(version);
|
||||
if (registry == null) {
|
||||
if (fallback) {
|
||||
if (useMinimumIfVersionNotFound) {
|
||||
return getProtocolRegistry(MINIMUM_VERSION);
|
||||
}
|
||||
throw new IllegalArgumentException("Could not find data for protocol version " + version);
|
||||
@@ -290,7 +401,7 @@ public enum StateRegistry {
|
||||
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) {
|
||||
if (mappings.length == 0) {
|
||||
throw new IllegalArgumentException("At least one mapping must be provided.");
|
||||
@@ -317,7 +428,7 @@ public enum StateRegistry {
|
||||
+ current.protocolVersion);
|
||||
}
|
||||
|
||||
if (registry.packetIdToSupplier.containsKey(current.id)) {
|
||||
if (registry.packetIdToReader.containsKey(current.id)) {
|
||||
throw new IllegalArgumentException("Can not register class " + clazz.getSimpleName()
|
||||
+ " with id " + current.id + " for " + registry.version
|
||||
+ " because another packet is already registered");
|
||||
@@ -329,7 +440,7 @@ public enum StateRegistry {
|
||||
}
|
||||
|
||||
if (!current.encodeOnly) {
|
||||
registry.packetIdToSupplier.put(current.id, packetSupplier);
|
||||
registry.packetIdToReader.put(current.id, decoder);
|
||||
}
|
||||
registry.packetClassToId.put(clazz, current.id);
|
||||
}
|
||||
@@ -339,7 +450,7 @@ public enum StateRegistry {
|
||||
public class ProtocolRegistry {
|
||||
|
||||
public final ProtocolVersion version;
|
||||
final IntObjectMap<Supplier<? extends Packet>> packetIdToSupplier =
|
||||
final IntObjectMap<PacketReader<? extends Packet>> packetIdToReader =
|
||||
new IntObjectHashMap<>(16, 0.5f);
|
||||
final Object2IntMap<Class<? extends Packet>> packetClassToId =
|
||||
new Object2IntOpenHashMap<>(16, 0.5f);
|
||||
@@ -353,14 +464,18 @@ public enum StateRegistry {
|
||||
* Attempts to create a packet from the specified {@code 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
|
||||
*/
|
||||
public @Nullable Packet createPacket(final int id) {
|
||||
final Supplier<? extends Packet> supplier = this.packetIdToSupplier.get(id);
|
||||
if (supplier == null) {
|
||||
public @Nullable Packet readPacket(final int id, ByteBuf buf, PacketDirection direction,
|
||||
ProtocolVersion version) {
|
||||
final PacketReader<? extends Packet> decoder = this.packetIdToReader.get(id);
|
||||
if (decoder == null) {
|
||||
return null;
|
||||
}
|
||||
return supplier.get();
|
||||
return decoder.read(buf, direction, version);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,9 +500,9 @@ public enum StateRegistry {
|
||||
|
||||
public static final class PacketMapping {
|
||||
|
||||
private final int id;
|
||||
private final ProtocolVersion protocolVersion;
|
||||
private final boolean encodeOnly;
|
||||
final int id;
|
||||
final ProtocolVersion protocolVersion;
|
||||
final boolean encodeOnly;
|
||||
|
||||
PacketMapping(int id, ProtocolVersion protocolVersion, boolean packetDecoding) {
|
||||
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 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 io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
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.collect.ImmutableList;
|
||||
@@ -18,11 +18,12 @@ import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import com.mojang.brigadier.tree.RootCommandNode;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.packet.brigadier.ArgumentPropertyRegistry;
|
||||
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.network.serialization.brigadier.ArgumentPropertyRegistry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
|
||||
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.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 byte NODE_TYPE_ROOT = 0x00;
|
||||
@@ -61,7 +64,7 @@ public class AvailableCommandsPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion) {
|
||||
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion protocolVersion) {
|
||||
int commands = ProtocolUtils.readVarInt(buf);
|
||||
WireNode[] wireNodes = new WireNode[commands];
|
||||
for (int i = 0; i < commands; i++) {
|
||||
@@ -93,7 +96,7 @@ public class AvailableCommandsPacket implements Packet {
|
||||
}
|
||||
|
||||
@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.
|
||||
Deque<CommandNode<CommandSource>> childrenQueue = new ArrayDeque<>(ImmutableList.of(rootNode));
|
||||
Object2IntMap<CommandNode<CommandSource>> idMappings = new Object2IntLinkedOpenHashMap<>();
|
||||
@@ -163,7 +166,7 @@ public class AvailableCommandsPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
public boolean handle(PacketHandler handler) {
|
||||
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.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
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 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 REMOVE = 1;
|
||||
@@ -86,20 +90,7 @@ public class BossBarPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
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) {
|
||||
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
this.uuid = ProtocolUtils.readUuid(buf);
|
||||
this.action = ProtocolUtils.readVarInt(buf);
|
||||
switch (action) {
|
||||
@@ -131,7 +122,7 @@ public class BossBarPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
if (uuid == null) {
|
||||
throw new IllegalStateException("No boss bar UUID specified");
|
||||
}
|
||||
@@ -172,14 +163,27 @@ public class BossBarPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
public boolean handle(PacketHandler handler) {
|
||||
return handler.handle(this);
|
||||
}
|
||||
|
||||
public static BossBarPacket createRemovePacket(UUID id) {
|
||||
BossBarPacket packet = new BossBarPacket();
|
||||
public static ClientboundBossBarPacket createRemovePacket(UUID id) {
|
||||
ClientboundBossBarPacket packet = new ClientboundBossBarPacket();
|
||||
packet.setUuid(id);
|
||||
packet.setAction(REMOVE);
|
||||
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 com.google.common.base.MoreObjects;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
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.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 byte[] publicKey = EMPTY_BYTE_ARRAY;
|
||||
@@ -33,18 +35,10 @@ public class EncryptionRequestPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EncryptionRequest{"
|
||||
+ "publicKey=" + Arrays.toString(publicKey)
|
||||
+ ", verifyToken=" + Arrays.toString(verifyToken)
|
||||
+ '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
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);
|
||||
verifyToken = ProtocolUtils.readByteArray(buf, 16);
|
||||
} else {
|
||||
@@ -54,10 +48,10 @@ public class EncryptionRequestPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
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, verifyToken);
|
||||
} else {
|
||||
@@ -67,7 +61,16 @@ public class EncryptionRequestPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
public boolean handle(PacketHandler handler) {
|
||||
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.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.connection.registry.DimensionData;
|
||||
import com.velocitypowered.proxy.connection.registry.DimensionInfo;
|
||||
import com.velocitypowered.proxy.connection.registry.DimensionRegistry;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
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.nbt.BinaryTagTypes;
|
||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||
import net.kyori.adventure.nbt.ListBinaryTag;
|
||||
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 short gamemode;
|
||||
@@ -34,140 +37,18 @@ public class JoinGamePacket implements Packet {
|
||||
private short previousGamemode; // 1.16+
|
||||
private CompoundBinaryTag biomeRegistry; // 1.16.2+
|
||||
|
||||
public int getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
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 withDimension(int dimension) {
|
||||
this.dimension = dimension;
|
||||
}
|
||||
|
||||
public void setDimension(int 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
|
||||
public String toString() {
|
||||
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) {
|
||||
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
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.gamemode = buf.readByte();
|
||||
} else {
|
||||
@@ -177,12 +58,12 @@ public class JoinGamePacket implements Packet {
|
||||
}
|
||||
String dimensionIdentifier = null;
|
||||
String levelName = null;
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||
this.previousGamemode = buf.readByte();
|
||||
ImmutableSet<String> levelNames = ImmutableSet.copyOf(ProtocolUtils.readStringArray(buf));
|
||||
CompoundBinaryTag registryContainer = ProtocolUtils.readCompoundTag(buf);
|
||||
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")
|
||||
.getList("value", BinaryTagTypes.COMPOUND);
|
||||
this.biomeRegistry = registryContainer.getCompound("minecraft:worldgen/biome");
|
||||
@@ -193,7 +74,7 @@ public class JoinGamePacket implements Packet {
|
||||
ImmutableSet<DimensionData> readData =
|
||||
DimensionRegistry.fromGameData(dimensionRegistryContainer, version);
|
||||
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);
|
||||
dimensionIdentifier = ProtocolUtils.readString(buf);
|
||||
this.currentDimensionData = DimensionData.decodeBaseCompoundTag(currentDimDataTag, version)
|
||||
@@ -202,35 +83,35 @@ public class JoinGamePacket implements Packet {
|
||||
dimensionIdentifier = 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();
|
||||
} else {
|
||||
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();
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_14) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_14)) {
|
||||
this.viewDistance = ProtocolUtils.readVarInt(buf);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||
this.reducedDebugInfo = buf.readBoolean();
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||
this.showRespawnScreen = buf.readBoolean();
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||
boolean isDebug = buf.readBoolean();
|
||||
boolean isFlat = buf.readBoolean();
|
||||
this.dimensionInfo = new DimensionInfo(dimensionIdentifier, levelName, isFlat, isDebug);
|
||||
@@ -238,20 +119,20 @@ public class JoinGamePacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
buf.writeInt(entityId);
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||
buf.writeBoolean(isHardcore);
|
||||
buf.writeByte(gamemode);
|
||||
} else {
|
||||
buf.writeByte(isHardcore ? gamemode | 0x8 : gamemode);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||
buf.writeByte(previousGamemode);
|
||||
ProtocolUtils.writeStringArray(buf, dimensionRegistry.getLevelNames().toArray(new String[0]));
|
||||
CompoundBinaryTag.Builder registryContainer = CompoundBinaryTag.builder();
|
||||
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();
|
||||
dimensionRegistryEntry.putString("type", "minecraft:dimension_type");
|
||||
dimensionRegistryEntry.put("value", encodedDimensionRegistry);
|
||||
@@ -261,52 +142,134 @@ public class JoinGamePacket implements Packet {
|
||||
registryContainer.put("dimension", encodedDimensionRegistry);
|
||||
}
|
||||
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.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
||||
} else {
|
||||
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
||||
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);
|
||||
} else {
|
||||
buf.writeByte(dimension);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13_2) <= 0) {
|
||||
if (version.lte(ProtocolVersion.MINECRAFT_1_13_2)) {
|
||||
buf.writeByte(difficulty);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||
buf.writeLong(partialHashedSeed);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||
ProtocolUtils.writeVarInt(buf, maxPlayers);
|
||||
} else {
|
||||
buf.writeByte(maxPlayers);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) < 0) {
|
||||
if (version.lt(ProtocolVersion.MINECRAFT_1_16)) {
|
||||
if (levelType == null) {
|
||||
throw new IllegalStateException("No level type specified.");
|
||||
}
|
||||
ProtocolUtils.writeString(buf, levelType);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_14) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_14)) {
|
||||
ProtocolUtils.writeVarInt(buf, viewDistance);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||
buf.writeBoolean(reducedDebugInfo);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||
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.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
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
public boolean handle(PacketHandler handler) {
|
||||
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.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.api.proxy.player.TabListEntry;
|
||||
import com.velocitypowered.api.util.GameProfile;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
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.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -16,7 +18,8 @@ import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
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 UPDATE_GAMEMODE = 1;
|
||||
@@ -26,12 +29,12 @@ public class PlayerListItemPacket implements Packet {
|
||||
private int action;
|
||||
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.items.addAll(items);
|
||||
}
|
||||
|
||||
public PlayerListItemPacket() {
|
||||
public ClientboundPlayerListItemPacket() {
|
||||
}
|
||||
|
||||
public int getAction() {
|
||||
@@ -43,8 +46,8 @@ public class PlayerListItemPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
||||
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||
action = ProtocolUtils.readVarInt(buf);
|
||||
int length = ProtocolUtils.readVarInt(buf);
|
||||
|
||||
@@ -93,8 +96,8 @@ public class PlayerListItemPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
||||
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||
ProtocolUtils.writeVarInt(buf, action);
|
||||
ProtocolUtils.writeVarInt(buf, items.size());
|
||||
for (Item item : items) {
|
||||
@@ -144,7 +147,7 @@ public class PlayerListItemPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
public boolean handle(PacketHandler handler) {
|
||||
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 {
|
||||
|
||||
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.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.connection.registry.DimensionData;
|
||||
import com.velocitypowered.proxy.connection.registry.DimensionInfo;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
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.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 long partialHashedSeed;
|
||||
@@ -22,12 +25,12 @@ public class RespawnPacket implements Packet {
|
||||
private short previousGamemode; // 1.16+
|
||||
private DimensionData currentDimensionData; // 1.16.2+
|
||||
|
||||
public RespawnPacket() {
|
||||
public ClientboundRespawnPacket() {
|
||||
}
|
||||
|
||||
public RespawnPacket(int dimension, long partialHashedSeed, short difficulty, short gamemode,
|
||||
String levelType, boolean shouldKeepPlayerData, DimensionInfo dimensionInfo,
|
||||
short previousGamemode, DimensionData currentDimensionData) {
|
||||
public ClientboundRespawnPacket(int dimension, long partialHashedSeed, short difficulty, short gamemode,
|
||||
String levelType, boolean shouldKeepPlayerData, DimensionInfo dimensionInfo,
|
||||
short previousGamemode, DimensionData currentDimensionData) {
|
||||
this.dimension = dimension;
|
||||
this.partialHashedSeed = partialHashedSeed;
|
||||
this.difficulty = difficulty;
|
||||
@@ -96,27 +99,11 @@ public class RespawnPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
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) {
|
||||
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
String dimensionIdentifier = null;
|
||||
String levelName = null;
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||
CompoundBinaryTag dimDataTag = ProtocolUtils.readCompoundTag(buf);
|
||||
dimensionIdentifier = ProtocolUtils.readString(buf);
|
||||
this.currentDimensionData = DimensionData.decodeBaseCompoundTag(dimDataTag, version)
|
||||
@@ -128,14 +115,14 @@ public class RespawnPacket implements Packet {
|
||||
} else {
|
||||
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();
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||
this.partialHashedSeed = buf.readLong();
|
||||
}
|
||||
this.gamemode = buf.readByte();
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||
this.previousGamemode = buf.readByte();
|
||||
boolean isDebug = buf.readBoolean();
|
||||
boolean isFlat = buf.readBoolean();
|
||||
@@ -147,9 +134,9 @@ public class RespawnPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
||||
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||
ProtocolUtils.writeCompoundTag(buf, currentDimensionData.serializeDimensionDetails());
|
||||
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
||||
} else {
|
||||
@@ -159,14 +146,14 @@ public class RespawnPacket implements Packet {
|
||||
} else {
|
||||
buf.writeInt(dimension);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13_2) <= 0) {
|
||||
if (version.lte(ProtocolVersion.MINECRAFT_1_13_2)) {
|
||||
buf.writeByte(difficulty);
|
||||
}
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||
buf.writeLong(partialHashedSeed);
|
||||
}
|
||||
buf.writeByte(gamemode);
|
||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||
buf.writeByte(previousGamemode);
|
||||
buf.writeBoolean(dimensionInfo.isDebugType());
|
||||
buf.writeBoolean(dimensionInfo.isFlat());
|
||||
@@ -177,7 +164,22 @@ public class RespawnPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
public boolean handle(PacketHandler handler) {
|
||||
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;
|
||||
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
|
||||
package com.velocitypowered.proxy.network.packet.clientbound;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
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.ArrayList;
|
||||
import java.util.List;
|
||||
import net.kyori.adventure.text.Component;
|
||||
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 start;
|
||||
@@ -50,18 +50,8 @@ public class TabCompleteResponsePacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TabCompleteResponse{"
|
||||
+ "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) {
|
||||
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
||||
this.transactionId = ProtocolUtils.readVarInt(buf);
|
||||
this.start = ProtocolUtils.readVarInt(buf);
|
||||
this.length = ProtocolUtils.readVarInt(buf);
|
||||
@@ -81,8 +71,8 @@ public class TabCompleteResponsePacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||
if (version.compareTo(MINECRAFT_1_13) >= 0) {
|
||||
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
if (version.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
||||
ProtocolUtils.writeVarInt(buf, this.transactionId);
|
||||
ProtocolUtils.writeVarInt(buf, this.start);
|
||||
ProtocolUtils.writeVarInt(buf, this.length);
|
||||
@@ -104,10 +94,20 @@ public class TabCompleteResponsePacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
public boolean handle(PacketHandler handler) {
|
||||
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> {
|
||||
private final String text;
|
||||
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.velocitypowered.api.proxy.server.ServerPing;
|
||||
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.serializer.legacy.LegacyComponentSerializer;
|
||||
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,
|
||||
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 {
|
||||
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.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.packet.legacyping.LegacyMinecraftPingVersion;
|
||||
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;
|
||||
import java.net.InetSocketAddress;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class LegacyPingPacket implements Packet {
|
||||
public class LegacyPingPacket implements LegacyPacket, Packet {
|
||||
|
||||
private final LegacyMinecraftPingVersion version;
|
||||
private final @Nullable InetSocketAddress vhost;
|
||||
@@ -24,6 +23,16 @@ public class LegacyPingPacket implements Packet {
|
||||
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() {
|
||||
return version;
|
||||
}
|
||||
@@ -31,19 +40,4 @@ public class LegacyPingPacket implements Packet {
|
||||
public @Nullable InetSocketAddress getVhost() {
|
||||
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.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
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 ClientSettingsPacket implements Packet {
|
||||
public class ServerboundClientSettingsPacket implements Packet {
|
||||
public static final PacketReader<ServerboundClientSettingsPacket> DECODER = PacketReader.method(ServerboundClientSettingsPacket::new);
|
||||
|
||||
private @Nullable String locale;
|
||||
private byte viewDistance;
|
||||
@@ -18,11 +21,11 @@ public class ClientSettingsPacket implements Packet {
|
||||
private short skinParts;
|
||||
private int mainHand;
|
||||
|
||||
public ClientSettingsPacket() {
|
||||
public ServerboundClientSettingsPacket() {
|
||||
}
|
||||
|
||||
public ClientSettingsPacket(String locale, byte viewDistance, int chatVisibility, boolean chatColors,
|
||||
short skinParts, int mainHand) {
|
||||
public ServerboundClientSettingsPacket(String locale, byte viewDistance, int chatVisibility, boolean chatColors,
|
||||
short skinParts, int mainHand) {
|
||||
this.locale = locale;
|
||||
this.viewDistance = viewDistance;
|
||||
this.chatVisibility = chatVisibility;
|
||||
@@ -31,6 +34,50 @@ public class ClientSettingsPacket implements Packet {
|
||||
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() {
|
||||
if (locale == null) {
|
||||
throw new IllegalStateException("No locale specified");
|
||||
@@ -38,103 +85,36 @@ public class ClientSettingsPacket implements Packet {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public void setLocale(String locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public byte getViewDistance() {
|
||||
return viewDistance;
|
||||
}
|
||||
|
||||
public void setViewDistance(byte viewDistance) {
|
||||
this.viewDistance = viewDistance;
|
||||
}
|
||||
|
||||
public int getChatVisibility() {
|
||||
return chatVisibility;
|
||||
}
|
||||
|
||||
public void setChatVisibility(int chatVisibility) {
|
||||
this.chatVisibility = chatVisibility;
|
||||
}
|
||||
|
||||
public boolean isChatColors() {
|
||||
return chatColors;
|
||||
}
|
||||
|
||||
public void setChatColors(boolean chatColors) {
|
||||
this.chatColors = chatColors;
|
||||
}
|
||||
|
||||
public short getSkinParts() {
|
||||
return skinParts;
|
||||
}
|
||||
|
||||
public void setSkinParts(short skinParts) {
|
||||
this.skinParts = skinParts;
|
||||
}
|
||||
|
||||
public int getMainHand() {
|
||||
return mainHand;
|
||||
}
|
||||
|
||||
public void setMainHand(int mainHand) {
|
||||
this.mainHand = mainHand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ClientSettings{"
|
||||
+ "locale='" + locale + '\''
|
||||
+ ", viewDistance=" + viewDistance
|
||||
+ ", chatVisibility=" + chatVisibility
|
||||
+ ", chatColors=" + chatColors
|
||||
+ ", skinParts=" + skinParts
|
||||
+ ", mainHand=" + mainHand
|
||||
+ '}';
|
||||
}
|
||||
|
||||
@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);
|
||||
return MoreObjects.toStringHelper(this)
|
||||
.add("locale", this.locale)
|
||||
.add("viewDistance", this.viewDistance)
|
||||
.add("chatVisibility", this.chatVisibility)
|
||||
.add("chatColors", this.chatColors)
|
||||
.add("difficulty", this.difficulty)
|
||||
.add("skinParts", this.skinParts)
|
||||
.add("mainHand", this.mainHand)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -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_8;
|
||||
@@ -6,14 +6,16 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_9;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
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 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;
|
||||
|
||||
@@ -67,27 +69,16 @@ public class TabCompleteRequestPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(this)
|
||||
.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) {
|
||||
public void decode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
if (version.gte(MINECRAFT_1_13)) {
|
||||
this.transactionId = ProtocolUtils.readVarInt(buf);
|
||||
this.command = ProtocolUtils.readString(buf, VANILLA_MAX_TAB_COMPLETE_LEN);
|
||||
} else {
|
||||
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();
|
||||
}
|
||||
if (version.compareTo(MINECRAFT_1_8) >= 0) {
|
||||
if (version.gte(MINECRAFT_1_8)) {
|
||||
this.hasPosition = buf.readBoolean();
|
||||
if (hasPosition) {
|
||||
this.position = buf.readLong();
|
||||
@@ -97,20 +88,20 @@ public class TabCompleteRequestPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||
public void encode(ByteBuf buf, PacketDirection direction, ProtocolVersion version) {
|
||||
if (command == null) {
|
||||
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.writeString(buf, command);
|
||||
} else {
|
||||
ProtocolUtils.writeString(buf, command);
|
||||
if (version.compareTo(MINECRAFT_1_9) >= 0) {
|
||||
if (version.gte(MINECRAFT_1_9)) {
|
||||
buf.writeBoolean(assumeCommand);
|
||||
}
|
||||
if (version.compareTo(MINECRAFT_1_8) >= 0) {
|
||||
if (version.gte(MINECRAFT_1_8)) {
|
||||
buf.writeBoolean(hasPosition);
|
||||
if (hasPosition) {
|
||||
buf.writeLong(position);
|
||||
@@ -120,7 +111,18 @@ public class TabCompleteRequestPacket implements Packet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
public boolean handle(PacketHandler handler) {
|
||||
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.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.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.protocol.packet.legacy.LegacyPingPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.legacyping.LegacyMinecraftPingVersion;
|
||||
import com.velocitypowered.proxy.network.packet.legacy.LegacyHandshakePacket;
|
||||
import com.velocitypowered.proxy.network.packet.legacy.LegacyMinecraftPingVersion;
|
||||
import com.velocitypowered.proxy.network.packet.legacy.LegacyPingPacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
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.channel.ChannelHandler;
|
||||
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.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.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.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.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
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.util.MoreByteBufUtils;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
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.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.network.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.packet.Packet;
|
||||
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
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 "
|
||||
+ "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.PacketRegistry.ProtocolRegistry registry;
|
||||
|
||||
@@ -28,7 +28,7 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
||||
*
|
||||
* @param direction the direction from which we decode from
|
||||
*/
|
||||
public MinecraftDecoder(ProtocolDirection direction) {
|
||||
public MinecraftDecoder(PacketDirection direction) {
|
||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||
this.registry = StateRegistry.HANDSHAKE.getProtocolRegistry(direction,
|
||||
ProtocolVersion.MINIMUM_VERSION);
|
||||
@@ -53,18 +53,17 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
||||
|
||||
int originalReaderIndex = buf.readerIndex();
|
||||
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) {
|
||||
buf.readerIndex(originalReaderIndex);
|
||||
ctx.fireChannelRead(buf);
|
||||
} else {
|
||||
try {
|
||||
try {
|
||||
packet.decode(buf, direction, registry.version);
|
||||
} catch (Exception e) {
|
||||
throw handleDecodeFailure(e, packet, packetId);
|
||||
}
|
||||
|
||||
if (buf.isReadable()) {
|
||||
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.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.Packet;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.network.StateRegistry;
|
||||
import com.velocitypowered.proxy.network.packet.Packet;
|
||||
import com.velocitypowered.proxy.network.packet.PacketDirection;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
|
||||
public class MinecraftEncoder extends MessageToByteEncoder<Packet> {
|
||||
|
||||
private final ProtocolDirection direction;
|
||||
private final PacketDirection direction;
|
||||
private StateRegistry state;
|
||||
private StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
||||
|
||||
@@ -21,7 +21,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<Packet> {
|
||||
*
|
||||
* @param direction the direction to encode to
|
||||
*/
|
||||
public MinecraftEncoder(ProtocolDirection direction) {
|
||||
public MinecraftEncoder(PacketDirection direction) {
|
||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||
this.registry = StateRegistry.HANDSHAKE
|
||||
.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 io.netty.buffer.ByteBuf;
|
||||
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.util.Natives;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.network.ProtocolUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
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;
|
||||
|
||||
@@ -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.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.JsonDeserializer;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user