Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-17 05:20:14 +01:00
packets!
Dieser Commit ist enthalten in:
Ursprung
b599e7b45c
Commit
0615b024cf
@ -27,6 +27,7 @@ dependencies {
|
|||||||
api "net.kyori:adventure-text-serializer-gson:${adventureVersion}"
|
api "net.kyori:adventure-text-serializer-gson:${adventureVersion}"
|
||||||
api "net.kyori:adventure-text-serializer-legacy:${adventureVersion}"
|
api "net.kyori:adventure-text-serializer-legacy:${adventureVersion}"
|
||||||
api "net.kyori:adventure-text-serializer-plain:${adventureVersion}"
|
api "net.kyori:adventure-text-serializer-plain:${adventureVersion}"
|
||||||
|
api("net.kyori:coffee:1.0.0-SNAPSHOT")
|
||||||
|
|
||||||
api "org.slf4j:slf4j-api:${slf4jVersion}"
|
api "org.slf4j:slf4j-api:${slf4jVersion}"
|
||||||
api 'com.google.inject:guice:4.2.3'
|
api 'com.google.inject:guice:4.2.3'
|
||||||
|
@ -6,11 +6,12 @@ import java.util.EnumSet;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import net.kyori.coffee.Ordered;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents each Minecraft protocol version.
|
* Represents each Minecraft protocol version.
|
||||||
*/
|
*/
|
||||||
public enum ProtocolVersion {
|
public enum ProtocolVersion implements Ordered<ProtocolVersion> {
|
||||||
UNKNOWN(-1, "Unknown"),
|
UNKNOWN(-1, "Unknown"),
|
||||||
LEGACY(-2, "Legacy"),
|
LEGACY(-2, "Legacy"),
|
||||||
MINECRAFT_1_7_2(4, "1.7.2"),
|
MINECRAFT_1_7_2(4, "1.7.2"),
|
||||||
|
@ -645,7 +645,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Gson getPingGsonInstance(ProtocolVersion version) {
|
public static Gson getPingGsonInstance(ProtocolVersion version) {
|
||||||
return version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0 ? POST_1_16_PING_SERIALIZER
|
return version.gte(ProtocolVersion.MINECRAFT_1_16) ? POST_1_16_PING_SERIALIZER
|
||||||
: PRE_1_16_PING_SERIALIZER;
|
: PRE_1_16_PING_SERIALIZER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,8 +224,8 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
*/
|
*/
|
||||||
public void closeWith(Object msg) {
|
public void closeWith(Object msg) {
|
||||||
if (channel.isActive()) {
|
if (channel.isActive()) {
|
||||||
boolean is17 = this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) < 0
|
boolean is17 = this.getProtocolVersion().lt(ProtocolVersion.MINECRAFT_1_8)
|
||||||
&& this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_7_2) >= 0;
|
&& this.getProtocolVersion().gte(ProtocolVersion.MINECRAFT_1_7_2);
|
||||||
if (is17 && this.getState() != StateRegistry.STATUS) {
|
if (is17 && this.getState() != StateRegistry.STATUS) {
|
||||||
channel.eventLoop().execute(() -> {
|
channel.eventLoop().execute(() -> {
|
||||||
// 1.7.x versions have a race condition with switching protocol states, so just explicitly
|
// 1.7.x versions have a race condition with switching protocol states, so just explicitly
|
||||||
|
@ -3,8 +3,8 @@ package com.velocitypowered.proxy.connection;
|
|||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.protocol.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
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.ClientSettingsPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.ClientboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionResponsePacket;
|
import com.velocitypowered.proxy.protocol.packet.EncryptionResponsePacket;
|
||||||
@ -21,6 +21,7 @@ import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
|||||||
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.ServerboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusRequestPacket;
|
import com.velocitypowered.proxy.protocol.packet.StatusRequestPacket;
|
||||||
@ -82,7 +83,11 @@ public interface MinecraftSessionHandler {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean handle(ChatPacket packet) {
|
default boolean handle(ClientboundChatPacket packet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean handle(ServerboundChatPacket packet) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ public class BungeeCordMessageResponder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static String getBungeeCordChannel(ProtocolVersion version) {
|
static String getBungeeCordChannel(ProtocolVersion version) {
|
||||||
return version.compareTo(ProtocolVersion.MINECRAFT_1_13) >= 0 ? MODERN_CHANNEL.getId()
|
return version.gte(ProtocolVersion.MINECRAFT_1_13) ? MODERN_CHANNEL.getId()
|
||||||
: LEGACY_CHANNEL.getId();
|
: LEGACY_CHANNEL.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,13 +22,14 @@ import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
|||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.protocol.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
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.ClientSettingsPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.ClientboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
|
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.ServerboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket.Offer;
|
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket.Offer;
|
||||||
@ -117,7 +118,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(ChatPacket packet) {
|
public boolean handle(ClientboundChatPacket packet) {
|
||||||
VelocityServerConnection serverConnection = player.getConnectedServer();
|
VelocityServerConnection serverConnection = player.getConnectedServer();
|
||||||
if (serverConnection == null) {
|
if (serverConnection == null) {
|
||||||
return true;
|
return true;
|
||||||
@ -154,7 +155,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
if (chatResult.isAllowed()) {
|
if (chatResult.isAllowed()) {
|
||||||
Optional<String> eventMsg = pme.getResult().getMessage();
|
Optional<String> eventMsg = pme.getResult().getMessage();
|
||||||
if (eventMsg.isPresent()) {
|
if (eventMsg.isPresent()) {
|
||||||
smc.write(ChatPacket.createServerbound(eventMsg.get()));
|
smc.write(new ServerboundChatPacket(eventMsg.get()));
|
||||||
} else {
|
} else {
|
||||||
smc.write(packet);
|
smc.write(packet);
|
||||||
}
|
}
|
||||||
@ -365,7 +366,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear any title from the previous server.
|
// Clear any title from the previous server.
|
||||||
if (player.getProtocolVersion().compareTo(MINECRAFT_1_8) >= 0) {
|
if (player.getProtocolVersion().gte(MINECRAFT_1_8)) {
|
||||||
player.getConnection()
|
player.getConnection()
|
||||||
.delayedWrite(TitlePacket.resetForProtocolVersion(player.getProtocolVersion()));
|
.delayedWrite(TitlePacket.resetForProtocolVersion(player.getProtocolVersion()));
|
||||||
}
|
}
|
||||||
@ -386,7 +387,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
// to perform entity ID rewrites, eliminating potential issues from rewriting packets and
|
// to perform entity ID rewrites, eliminating potential issues from rewriting packets and
|
||||||
// improving compatibility with mods.
|
// improving compatibility with mods.
|
||||||
int sentOldDim = joinGame.getDimension();
|
int sentOldDim = joinGame.getDimension();
|
||||||
if (player.getProtocolVersion().compareTo(MINECRAFT_1_16) < 0) {
|
if (player.getProtocolVersion().lt(MINECRAFT_1_16)) {
|
||||||
// Before Minecraft 1.16, we could not switch to the same dimension without sending an
|
// Before Minecraft 1.16, we could not switch to the same dimension without sending an
|
||||||
// additional respawn. On older versions of Minecraft this forces the client to perform
|
// additional respawn. On older versions of Minecraft this forces the client to perform
|
||||||
// garbage collection which adds additional latency.
|
// garbage collection which adds additional latency.
|
||||||
@ -439,7 +440,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
String commandLabel = command.substring(0, commandEndPosition);
|
String commandLabel = command.substring(0, commandEndPosition);
|
||||||
if (!server.getCommandManager().hasCommand(commandLabel)) {
|
if (!server.getCommandManager().hasCommand(commandLabel)) {
|
||||||
if (player.getProtocolVersion().compareTo(MINECRAFT_1_13) < 0) {
|
if (player.getProtocolVersion().lt(MINECRAFT_1_13)) {
|
||||||
// Outstanding tab completes are recorded for use with 1.12 clients and below to provide
|
// Outstanding tab completes are recorded for use with 1.12 clients and below to provide
|
||||||
// additional tab completion support.
|
// additional tab completion support.
|
||||||
outstandingTabComplete = packet;
|
outstandingTabComplete = packet;
|
||||||
@ -476,7 +477,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleRegularTabComplete(TabCompleteRequestPacket packet) {
|
private boolean handleRegularTabComplete(TabCompleteRequestPacket packet) {
|
||||||
if (player.getProtocolVersion().compareTo(MINECRAFT_1_13) < 0) {
|
if (player.getProtocolVersion().lt(MINECRAFT_1_13)) {
|
||||||
// Outstanding tab completes are recorded for use with 1.12 clients and below to provide
|
// Outstanding tab completes are recorded for use with 1.12 clients and below to provide
|
||||||
// additional tab completion support.
|
// additional tab completion support.
|
||||||
outstandingTabComplete = packet;
|
outstandingTabComplete = packet;
|
||||||
@ -508,7 +509,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
String command = request.getCommand().substring(1);
|
String command = request.getCommand().substring(1);
|
||||||
server.getCommandManager().offerSuggestions(player, command)
|
server.getCommandManager().offerSuggestions(player, command)
|
||||||
.thenAcceptAsync(offers -> {
|
.thenAcceptAsync(offers -> {
|
||||||
boolean legacy = player.getProtocolVersion().compareTo(MINECRAFT_1_13) < 0;
|
boolean legacy = player.getProtocolVersion().lt(MINECRAFT_1_13);
|
||||||
try {
|
try {
|
||||||
for (String offer : offers) {
|
for (String offer : offers) {
|
||||||
offer = legacy && !offer.startsWith("/") ? "/" + offer : offer;
|
offer = legacy && !offer.startsWith("/") ? "/" + offer : offer;
|
||||||
@ -564,13 +565,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
MinecraftConnection smc = player.ensureAndGetCurrentServer().ensureConnected();
|
MinecraftConnection smc = player.ensureAndGetCurrentServer().ensureConnected();
|
||||||
String commandToRun = result.getCommand().orElse(originalCommand);
|
String commandToRun = result.getCommand().orElse(originalCommand);
|
||||||
if (result.isForwardToServer()) {
|
if (result.isForwardToServer()) {
|
||||||
return CompletableFuture.runAsync(() -> smc.write(ChatPacket.createServerbound("/"
|
return CompletableFuture.runAsync(() -> smc.write(new ServerboundChatPacket("/"
|
||||||
+ commandToRun)), smc.eventLoop());
|
+ commandToRun)), smc.eventLoop());
|
||||||
} else {
|
} else {
|
||||||
return server.getCommandManager().executeImmediately(player, commandToRun)
|
return server.getCommandManager().executeImmediately(player, commandToRun)
|
||||||
.thenAcceptAsync(hasRun -> {
|
.thenAcceptAsync(hasRun -> {
|
||||||
if (!hasRun) {
|
if (!hasRun) {
|
||||||
smc.write(ChatPacket.createServerbound("/" + commandToRun));
|
smc.write(new ServerboundChatPacket("/" + commandToRun));
|
||||||
}
|
}
|
||||||
}, smc.eventLoop());
|
}, smc.eventLoop());
|
||||||
}
|
}
|
||||||
|
@ -38,12 +38,13 @@ import com.velocitypowered.proxy.connection.util.ConnectionMessages;
|
|||||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
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.ClientSettingsPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.ClientboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequestPacket;
|
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequestPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.ServerboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TitlePacket;
|
import com.velocitypowered.proxy.protocol.packet.TitlePacket;
|
||||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||||
@ -112,7 +113,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
ConnectedPlayer(VelocityServer server, GameProfile profile, MinecraftConnection connection,
|
ConnectedPlayer(VelocityServer server, GameProfile profile, MinecraftConnection connection,
|
||||||
@Nullable InetSocketAddress virtualHost, boolean onlineMode) {
|
@Nullable InetSocketAddress virtualHost, boolean onlineMode) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
if (connection.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (connection.getProtocolVersion().gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
this.tabList = new VelocityTabList(connection);
|
this.tabList = new VelocityTabList(connection);
|
||||||
} else {
|
} else {
|
||||||
this.tabList = new VelocityTabListLegacy(connection);
|
this.tabList = new VelocityTabListLegacy(connection);
|
||||||
@ -226,26 +227,25 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
return connection.getProtocolVersion();
|
return connection.getProtocolVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendMessage(@NonNull Identity identity, @NonNull Component message) {
|
|
||||||
connection.write(ChatPacket.createClientbound(identity, message, this.getProtocolVersion()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(@NonNull Identity identity, @NonNull Component message,
|
public void sendMessage(@NonNull Identity identity, @NonNull Component message,
|
||||||
@NonNull MessageType type) {
|
@NonNull MessageType type) {
|
||||||
Preconditions.checkNotNull(message, "message");
|
Preconditions.checkNotNull(message, "message");
|
||||||
Preconditions.checkNotNull(type, "type");
|
Preconditions.checkNotNull(type, "type");
|
||||||
|
|
||||||
ChatPacket packet = ChatPacket.createClientbound(identity, message, this.getProtocolVersion());
|
connection.write(new ClientboundChatPacket(
|
||||||
packet.setType(type == MessageType.CHAT ? ChatPacket.CHAT_TYPE : ChatPacket.SYSTEM_TYPE);
|
ProtocolUtils.getJsonChatSerializer(this.getProtocolVersion()).serialize(message),
|
||||||
connection.write(packet);
|
type == MessageType.CHAT
|
||||||
|
? ClientboundChatPacket.CHAT_TYPE
|
||||||
|
: ClientboundChatPacket.SYSTEM_TYPE,
|
||||||
|
identity.uuid()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendActionBar(net.kyori.adventure.text.@NonNull Component message) {
|
public void sendActionBar(net.kyori.adventure.text.@NonNull Component message) {
|
||||||
ProtocolVersion playerVersion = getProtocolVersion();
|
ProtocolVersion playerVersion = getProtocolVersion();
|
||||||
if (playerVersion.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0) {
|
if (playerVersion.gte(ProtocolVersion.MINECRAFT_1_11)) {
|
||||||
// Use the title packet instead.
|
// Use the title packet instead.
|
||||||
TitlePacket pkt = new TitlePacket();
|
TitlePacket pkt = new TitlePacket();
|
||||||
pkt.setAction(TitlePacket.SET_ACTION_BAR);
|
pkt.setAction(TitlePacket.SET_ACTION_BAR);
|
||||||
@ -257,10 +257,11 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
// legacy message and then inject the legacy text into a component... yuck!
|
// legacy message and then inject the legacy text into a component... yuck!
|
||||||
JsonObject object = new JsonObject();
|
JsonObject object = new JsonObject();
|
||||||
object.addProperty("text", LegacyComponentSerializer.legacySection().serialize(message));
|
object.addProperty("text", LegacyComponentSerializer.legacySection().serialize(message));
|
||||||
ChatPacket chat = new ChatPacket();
|
connection.write(new ClientboundChatPacket(
|
||||||
chat.setMessage(object.toString());
|
object.toString(),
|
||||||
chat.setType(ChatPacket.GAME_INFO_TYPE);
|
ClientboundChatPacket.GAME_INFO_TYPE,
|
||||||
connection.write(chat);
|
Identity.nil().uuid()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,10 +673,10 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spoofChatInput(String input) {
|
public void spoofChatInput(String input) {
|
||||||
Preconditions.checkArgument(input.length() <= ChatPacket.MAX_SERVERBOUND_MESSAGE_LENGTH,
|
Preconditions.checkArgument(input.length() <= ServerboundChatPacket.MAX_MESSAGE_LENGTH,
|
||||||
"input cannot be greater than " + ChatPacket.MAX_SERVERBOUND_MESSAGE_LENGTH
|
"input cannot be greater than " + ServerboundChatPacket.MAX_MESSAGE_LENGTH
|
||||||
+ " characters in length");
|
+ " characters in length");
|
||||||
ensureBackendConnection().write(ChatPacket.createServerbound(input));
|
ensureBackendConnection().write(new ServerboundChatPacket(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -707,9 +708,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
*/
|
*/
|
||||||
public void sendKeepAlive() {
|
public void sendKeepAlive() {
|
||||||
if (connection.getState() == StateRegistry.PLAY) {
|
if (connection.getState() == StateRegistry.PLAY) {
|
||||||
KeepAlivePacket keepAlive = new KeepAlivePacket();
|
connection.write(new KeepAlivePacket(ThreadLocalRandom.current().nextLong()));
|
||||||
keepAlive.setRandomId(ThreadLocalRandom.current().nextLong());
|
|
||||||
connection.write(keepAlive);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,7 +750,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
boolean minecraftOrFmlMessage;
|
boolean minecraftOrFmlMessage;
|
||||||
|
|
||||||
// By default, all internal Minecraft and Forge channels are forwarded from the server.
|
// By default, all internal Minecraft and Forge channels are forwarded from the server.
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_12_2) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_12_2)) {
|
||||||
String channel = message.getChannel();
|
String channel = message.getChannel();
|
||||||
minecraftOrFmlMessage = channel.startsWith("MC|")
|
minecraftOrFmlMessage = channel.startsWith("MC|")
|
||||||
|| channel.startsWith(LegacyForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)
|
|| channel.startsWith(LegacyForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)
|
||||||
|
@ -114,7 +114,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
// If the proxy is configured for modern forwarding, we must deny connections from 1.12.2
|
// If the proxy is configured for modern forwarding, we must deny connections from 1.12.2
|
||||||
// and lower, otherwise IP information will never get forwarded.
|
// and lower, otherwise IP information will never get forwarded.
|
||||||
if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN
|
if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN
|
||||||
&& handshake.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_13) < 0) {
|
&& handshake.getProtocolVersion().lt(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
ic.disconnectQuietly(Component.text("This server is only compatible with 1.13 and above."));
|
ic.disconnectQuietly(Component.text("This server is only compatible with 1.13 and above."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -126,9 +126,9 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
private ConnectionType getHandshakeConnectionType(HandshakePacket handshake) {
|
private ConnectionType getHandshakeConnectionType(HandshakePacket handshake) {
|
||||||
// Determine if we're using Forge (1.8 to 1.12, may not be the case in 1.13).
|
// Determine if we're using Forge (1.8 to 1.12, may not be the case in 1.13).
|
||||||
if (handshake.getServerAddress().endsWith(LegacyForgeConstants.HANDSHAKE_HOSTNAME_TOKEN)
|
if (handshake.getServerAddress().endsWith(LegacyForgeConstants.HANDSHAKE_HOSTNAME_TOKEN)
|
||||||
&& handshake.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_13) < 0) {
|
&& handshake.getProtocolVersion().lt(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
return ConnectionTypes.LEGACY_FORGE;
|
return ConnectionTypes.LEGACY_FORGE;
|
||||||
} else if (handshake.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_7_6) <= 0) {
|
} else if (handshake.getProtocolVersion().lte(ProtocolVersion.MINECRAFT_1_7_6)) {
|
||||||
// 1.7 Forge will not notify us during handshake. UNDETERMINED will listen for incoming
|
// 1.7 Forge will not notify us during handshake. UNDETERMINED will listen for incoming
|
||||||
// forge handshake attempts. Also sends a reset handshake packet on every transition.
|
// forge handshake attempts. Also sends a reset handshake packet on every transition.
|
||||||
return ConnectionTypes.UNDETERMINED_17;
|
return ConnectionTypes.UNDETERMINED_17;
|
||||||
|
@ -242,7 +242,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
private void completeLoginProtocolPhaseAndInitialize(ConnectedPlayer player) {
|
private void completeLoginProtocolPhaseAndInitialize(ConnectedPlayer player) {
|
||||||
int threshold = server.getConfiguration().getCompressionThreshold();
|
int threshold = server.getConfiguration().getCompressionThreshold();
|
||||||
if (threshold >= 0 && mcConnection.getProtocolVersion().compareTo(MINECRAFT_1_8) >= 0) {
|
if (threshold >= 0 && mcConnection.getProtocolVersion().gte(MINECRAFT_1_8)) {
|
||||||
mcConnection.write(new SetCompressionPacket(threshold));
|
mcConnection.write(new SetCompressionPacket(threshold));
|
||||||
mcConnection.setCompressionThreshold(threshold);
|
mcConnection.setCompressionThreshold(threshold);
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ public final class DimensionData {
|
|||||||
String registryIdentifier = dimTag.getString("name");
|
String registryIdentifier = dimTag.getString("name");
|
||||||
CompoundBinaryTag details;
|
CompoundBinaryTag details;
|
||||||
Integer dimensionId = null;
|
Integer dimensionId = null;
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
dimensionId = dimTag.getInt("id");
|
dimensionId = dimTag.getInt("id");
|
||||||
details = dimTag.getCompound("element");
|
details = dimTag.getCompound("element");
|
||||||
} else {
|
} else {
|
||||||
@ -243,7 +243,7 @@ public final class DimensionData {
|
|||||||
*/
|
*/
|
||||||
public CompoundBinaryTag encodeAsCompoundTag(ProtocolVersion version) {
|
public CompoundBinaryTag encodeAsCompoundTag(ProtocolVersion version) {
|
||||||
CompoundBinaryTag details = serializeDimensionDetails();
|
CompoundBinaryTag details = serializeDimensionDetails();
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
if (dimensionId == null) {
|
if (dimensionId == null) {
|
||||||
throw new IllegalStateException("Tried to serialize a 1.16.2+ dimension registry entry "
|
throw new IllegalStateException("Tried to serialize a 1.16.2+ dimension registry entry "
|
||||||
+ "without an ID");
|
+ "without an ID");
|
||||||
|
@ -6,9 +6,16 @@ import io.netty.buffer.ByteBuf;
|
|||||||
|
|
||||||
public interface Packet {
|
public interface Packet {
|
||||||
|
|
||||||
void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion);
|
@Deprecated
|
||||||
|
default void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion);
|
void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion);
|
||||||
|
|
||||||
boolean handle(MinecraftSessionHandler handler);
|
boolean handle(MinecraftSessionHandler handler);
|
||||||
|
|
||||||
|
interface Decoder<P extends Packet> {
|
||||||
|
P decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -459,7 +459,7 @@ public enum ProtocolUtils {
|
|||||||
* @return the appropriate {@link GsonComponentSerializer}
|
* @return the appropriate {@link GsonComponentSerializer}
|
||||||
*/
|
*/
|
||||||
public static GsonComponentSerializer getJsonChatSerializer(ProtocolVersion version) {
|
public static GsonComponentSerializer getJsonChatSerializer(ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
return MODERN_SERIALIZER;
|
return MODERN_SERIALIZER;
|
||||||
}
|
}
|
||||||
return PRE_1_16_SERIALIZER;
|
return PRE_1_16_SERIALIZER;
|
||||||
|
@ -18,8 +18,8 @@ import static com.velocitypowered.api.network.ProtocolVersion.SUPPORTED_VERSIONS
|
|||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
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.ClientSettingsPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.ClientboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.EncryptionResponsePacket;
|
import com.velocitypowered.proxy.protocol.packet.EncryptionResponsePacket;
|
||||||
@ -36,6 +36,7 @@ import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
|||||||
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.ServerboundChatPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusRequestPacket;
|
import com.velocitypowered.proxy.protocol.packet.StatusRequestPacket;
|
||||||
@ -43,6 +44,7 @@ import com.velocitypowered.proxy.protocol.packet.StatusResponsePacket;
|
|||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.TitlePacket;
|
import com.velocitypowered.proxy.protocol.packet.TitlePacket;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.util.collection.IntObjectHashMap;
|
import io.netty.util.collection.IntObjectHashMap;
|
||||||
import io.netty.util.collection.IntObjectMap;
|
import io.netty.util.collection.IntObjectMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
@ -65,14 +67,14 @@ public enum StateRegistry {
|
|||||||
},
|
},
|
||||||
STATUS {
|
STATUS {
|
||||||
{
|
{
|
||||||
serverbound.register(StatusRequestPacket.class, () -> StatusRequestPacket.INSTANCE,
|
serverbound.registerNew(StatusRequestPacket.class, StatusRequestPacket.DECODER,
|
||||||
map(0x00, MINECRAFT_1_7_2, false));
|
map(0x00, MINECRAFT_1_7_2, false));
|
||||||
serverbound.register(StatusPingPacket.class, StatusPingPacket::new,
|
serverbound.registerNew(StatusPingPacket.class, StatusPingPacket.DECODER,
|
||||||
map(0x01, MINECRAFT_1_7_2, false));
|
map(0x01, MINECRAFT_1_7_2, false));
|
||||||
|
|
||||||
clientbound.register(StatusResponsePacket.class, StatusResponsePacket::new,
|
clientbound.register(StatusResponsePacket.class, StatusResponsePacket::new,
|
||||||
map(0x00, MINECRAFT_1_7_2, false));
|
map(0x00, MINECRAFT_1_7_2, false));
|
||||||
clientbound.register(StatusPingPacket.class, StatusPingPacket::new,
|
clientbound.registerNew(StatusPingPacket.class, StatusPingPacket.DECODER,
|
||||||
map(0x01, MINECRAFT_1_7_2, false));
|
map(0x01, MINECRAFT_1_7_2, false));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -88,7 +90,7 @@ public enum StateRegistry {
|
|||||||
map(0x01, MINECRAFT_1_12_1, false),
|
map(0x01, MINECRAFT_1_12_1, false),
|
||||||
map(0x05, MINECRAFT_1_13, false),
|
map(0x05, MINECRAFT_1_13, false),
|
||||||
map(0x06, MINECRAFT_1_14, false));
|
map(0x06, MINECRAFT_1_14, false));
|
||||||
serverbound.register(ChatPacket.class, ChatPacket::new,
|
serverbound.registerNew(ServerboundChatPacket.class, ServerboundChatPacket.DECODER,
|
||||||
map(0x01, MINECRAFT_1_7_2, false),
|
map(0x01, MINECRAFT_1_7_2, false),
|
||||||
map(0x02, MINECRAFT_1_9, false),
|
map(0x02, MINECRAFT_1_9, false),
|
||||||
map(0x03, MINECRAFT_1_12, false),
|
map(0x03, MINECRAFT_1_12, false),
|
||||||
@ -107,7 +109,7 @@ public enum StateRegistry {
|
|||||||
map(0x09, MINECRAFT_1_12_1, false),
|
map(0x09, MINECRAFT_1_12_1, false),
|
||||||
map(0x0A, MINECRAFT_1_13, false),
|
map(0x0A, MINECRAFT_1_13, false),
|
||||||
map(0x0B, MINECRAFT_1_14, false));
|
map(0x0B, MINECRAFT_1_14, false));
|
||||||
serverbound.register(KeepAlivePacket.class, KeepAlivePacket::new,
|
serverbound.registerNew(KeepAlivePacket.class, KeepAlivePacket.DECODER,
|
||||||
map(0x00, MINECRAFT_1_7_2, false),
|
map(0x00, MINECRAFT_1_7_2, false),
|
||||||
map(0x0B, MINECRAFT_1_9, false),
|
map(0x0B, MINECRAFT_1_9, false),
|
||||||
map(0x0C, MINECRAFT_1_12, false),
|
map(0x0C, MINECRAFT_1_12, false),
|
||||||
@ -128,7 +130,7 @@ public enum StateRegistry {
|
|||||||
map(0x0C, MINECRAFT_1_9, false),
|
map(0x0C, MINECRAFT_1_9, false),
|
||||||
map(0x0D, MINECRAFT_1_15, false),
|
map(0x0D, MINECRAFT_1_15, false),
|
||||||
map(0x0C, MINECRAFT_1_16, false));
|
map(0x0C, MINECRAFT_1_16, false));
|
||||||
clientbound.register(ChatPacket.class, ChatPacket::new,
|
clientbound.register(ClientboundChatPacket.class, ClientboundChatPacket::new,
|
||||||
map(0x02, MINECRAFT_1_7_2, true),
|
map(0x02, MINECRAFT_1_7_2, true),
|
||||||
map(0x0F, MINECRAFT_1_9, true),
|
map(0x0F, MINECRAFT_1_9, true),
|
||||||
map(0x0E, MINECRAFT_1_13, true),
|
map(0x0E, MINECRAFT_1_13, true),
|
||||||
@ -162,7 +164,7 @@ public enum StateRegistry {
|
|||||||
map(0x1B, MINECRAFT_1_15, false),
|
map(0x1B, MINECRAFT_1_15, false),
|
||||||
map(0x1A, MINECRAFT_1_16, false),
|
map(0x1A, MINECRAFT_1_16, false),
|
||||||
map(0x19, MINECRAFT_1_16_2, false));
|
map(0x19, MINECRAFT_1_16_2, false));
|
||||||
clientbound.register(KeepAlivePacket.class, KeepAlivePacket::new,
|
clientbound.registerNew(KeepAlivePacket.class, KeepAlivePacket.DECODER,
|
||||||
map(0x00, MINECRAFT_1_7_2, false),
|
map(0x00, MINECRAFT_1_7_2, false),
|
||||||
map(0x1F, MINECRAFT_1_9, false),
|
map(0x1F, MINECRAFT_1_9, false),
|
||||||
map(0x21, MINECRAFT_1_13, false),
|
map(0x21, MINECRAFT_1_13, false),
|
||||||
@ -242,7 +244,7 @@ public enum StateRegistry {
|
|||||||
map(0x01, MINECRAFT_1_7_2, false));
|
map(0x01, MINECRAFT_1_7_2, false));
|
||||||
clientbound.register(ServerLoginSuccessPacket.class, ServerLoginSuccessPacket::new,
|
clientbound.register(ServerLoginSuccessPacket.class, ServerLoginSuccessPacket::new,
|
||||||
map(0x02, MINECRAFT_1_7_2, false));
|
map(0x02, MINECRAFT_1_7_2, false));
|
||||||
clientbound.register(SetCompressionPacket.class, SetCompressionPacket::new,
|
clientbound.registerNew(SetCompressionPacket.class, SetCompressionPacket.DECODER,
|
||||||
map(0x03, MINECRAFT_1_8, false));
|
map(0x03, MINECRAFT_1_8, false));
|
||||||
clientbound.register(LoginPluginMessagePacket.class, LoginPluginMessagePacket::new,
|
clientbound.register(LoginPluginMessagePacket.class, LoginPluginMessagePacket::new,
|
||||||
map(0x04, MINECRAFT_1_13, false));
|
map(0x04, MINECRAFT_1_13, false));
|
||||||
@ -290,7 +292,7 @@ public enum StateRegistry {
|
|||||||
return registry;
|
return registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
<P extends Packet> void register(Class<P> clazz, Supplier<P> packetSupplier,
|
<P extends Packet> void registerNew(Class<P> clazz, Packet.Decoder<P> decoder,
|
||||||
PacketMapping... mappings) {
|
PacketMapping... mappings) {
|
||||||
if (mappings.length == 0) {
|
if (mappings.length == 0) {
|
||||||
throw new IllegalArgumentException("At least one mapping must be provided.");
|
throw new IllegalArgumentException("At least one mapping must be provided.");
|
||||||
@ -307,6 +309,53 @@ public enum StateRegistry {
|
|||||||
"Next mapping version (%s) should be lower then current (%s)", to, from));
|
"Next mapping version (%s) should be lower then current (%s)", to, from));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (ProtocolVersion protocol : EnumSet.range(from, to)) {
|
||||||
|
if (protocol == to && next != current) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ProtocolRegistry registry = this.versions.get(protocol);
|
||||||
|
if (registry == null) {
|
||||||
|
throw new IllegalArgumentException("Unknown protocol version "
|
||||||
|
+ current.protocolVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registry.packetIdToSupplier.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");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registry.packetClassToId.containsKey(clazz)) {
|
||||||
|
throw new IllegalArgumentException(clazz.getSimpleName()
|
||||||
|
+ " is already registered for version " + registry.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!current.encodeOnly) {
|
||||||
|
registry.packetIdToDecoder.put(current.id, decoder);
|
||||||
|
}
|
||||||
|
registry.packetClassToId.put(clazz, current.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
<P extends Packet> void register(Class<P> clazz, Supplier<P> packetSupplier,
|
||||||
|
PacketMapping... mappings) {
|
||||||
|
if (mappings.length == 0) {
|
||||||
|
throw new IllegalArgumentException("At least one mapping must be provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mappings.length; i++) {
|
||||||
|
PacketMapping current = mappings[i];
|
||||||
|
PacketMapping next = (i + 1 < mappings.length) ? mappings[i + 1] : current;
|
||||||
|
ProtocolVersion from = current.protocolVersion;
|
||||||
|
ProtocolVersion to = current == next ? getLast(SUPPORTED_VERSIONS) : next.protocolVersion;
|
||||||
|
|
||||||
|
if (from.gte(to) && from != getLast(SUPPORTED_VERSIONS)) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"Next mapping version (%s) should be lower then current (%s)", to, from));
|
||||||
|
}
|
||||||
|
|
||||||
for (ProtocolVersion protocol : EnumSet.range(from, to)) {
|
for (ProtocolVersion protocol : EnumSet.range(from, to)) {
|
||||||
if (protocol == to && next != current) {
|
if (protocol == to && next != current) {
|
||||||
break;
|
break;
|
||||||
@ -339,8 +388,11 @@ public enum StateRegistry {
|
|||||||
public class ProtocolRegistry {
|
public class ProtocolRegistry {
|
||||||
|
|
||||||
public final ProtocolVersion version;
|
public final ProtocolVersion version;
|
||||||
|
@Deprecated
|
||||||
final IntObjectMap<Supplier<? extends Packet>> packetIdToSupplier =
|
final IntObjectMap<Supplier<? extends Packet>> packetIdToSupplier =
|
||||||
new IntObjectHashMap<>(16, 0.5f);
|
new IntObjectHashMap<>(16, 0.5f);
|
||||||
|
final IntObjectMap<Packet.Decoder<? extends Packet>> packetIdToDecoder =
|
||||||
|
new IntObjectHashMap<>(16, 0.5f);
|
||||||
final Object2IntMap<Class<? extends Packet>> packetClassToId =
|
final Object2IntMap<Class<? extends Packet>> packetClassToId =
|
||||||
new Object2IntOpenHashMap<>(16, 0.5f);
|
new Object2IntOpenHashMap<>(16, 0.5f);
|
||||||
|
|
||||||
@ -355,6 +407,7 @@ public enum StateRegistry {
|
|||||||
* @param id the packet ID
|
* @param id the packet ID
|
||||||
* @return the packet instance, or {@code null} if the ID is not registered
|
* @return the packet instance, or {@code null} if the ID is not registered
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public @Nullable Packet createPacket(final int id) {
|
public @Nullable Packet createPacket(final int id) {
|
||||||
final Supplier<? extends Packet> supplier = this.packetIdToSupplier.get(id);
|
final Supplier<? extends Packet> supplier = this.packetIdToSupplier.get(id);
|
||||||
if (supplier == null) {
|
if (supplier == null) {
|
||||||
@ -363,6 +416,14 @@ public enum StateRegistry {
|
|||||||
return supplier.get();
|
return supplier.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable Packet decodePacket(final int id, ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion) {
|
||||||
|
final Packet.Decoder<? extends Packet> decoder = this.packetIdToDecoder.get(id);
|
||||||
|
if (decoder == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return decoder.decode(buf, direction, protocolVersion);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to look up the packet ID for an {@code packet}.
|
* Attempts to look up the packet ID for an {@code packet}.
|
||||||
*
|
*
|
||||||
|
@ -53,16 +53,25 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
int originalReaderIndex = buf.readerIndex();
|
int originalReaderIndex = buf.readerIndex();
|
||||||
int packetId = ProtocolUtils.readVarInt(buf);
|
int packetId = ProtocolUtils.readVarInt(buf);
|
||||||
Packet packet = this.registry.createPacket(packetId);
|
final boolean decoded;
|
||||||
|
Packet packet = this.registry.decodePacket(packetId, buf, direction, registry.version);
|
||||||
|
if (packet == null) {
|
||||||
|
packet = this.registry.createPacket(packetId);
|
||||||
|
decoded = false;
|
||||||
|
} else {
|
||||||
|
decoded = true;
|
||||||
|
}
|
||||||
if (packet == null) {
|
if (packet == null) {
|
||||||
buf.readerIndex(originalReaderIndex);
|
buf.readerIndex(originalReaderIndex);
|
||||||
ctx.fireChannelRead(buf);
|
ctx.fireChannelRead(buf);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
try {
|
if (!decoded) {
|
||||||
packet.decode(buf, direction, registry.version);
|
try {
|
||||||
} catch (Exception e) {
|
packet.decode(buf, direction, registry.version);
|
||||||
throw handleDecodeFailure(e, packet, packetId);
|
} catch (Exception e) {
|
||||||
|
throw handleDecodeFailure(e, packet, packetId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf.isReadable()) {
|
if (buf.isReadable()) {
|
||||||
|
@ -101,13 +101,13 @@ public class ClientSettingsPacket implements Packet {
|
|||||||
this.chatVisibility = ProtocolUtils.readVarInt(buf);
|
this.chatVisibility = ProtocolUtils.readVarInt(buf);
|
||||||
this.chatColors = buf.readBoolean();
|
this.chatColors = buf.readBoolean();
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_7_6) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_7_6)) {
|
||||||
this.difficulty = buf.readByte();
|
this.difficulty = buf.readByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.skinParts = buf.readUnsignedByte();
|
this.skinParts = buf.readUnsignedByte();
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_9) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_9)) {
|
||||||
this.mainHand = ProtocolUtils.readVarInt(buf);
|
this.mainHand = ProtocolUtils.readVarInt(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,13 +122,13 @@ public class ClientSettingsPacket implements Packet {
|
|||||||
ProtocolUtils.writeVarInt(buf, chatVisibility);
|
ProtocolUtils.writeVarInt(buf, chatVisibility);
|
||||||
buf.writeBoolean(chatColors);
|
buf.writeBoolean(chatColors);
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_7_6) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_7_6)) {
|
||||||
buf.writeByte(difficulty);
|
buf.writeByte(difficulty);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.writeByte(skinParts);
|
buf.writeByte(skinParts);
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_9) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_9)) {
|
||||||
ProtocolUtils.writeVarInt(buf, mainHand);
|
ProtocolUtils.writeVarInt(buf, mainHand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,29 @@
|
|||||||
package com.velocitypowered.proxy.protocol.packet;
|
package com.velocitypowered.proxy.protocol.packet;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.protocol.Packet;
|
import com.velocitypowered.proxy.protocol.Packet;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
import com.velocitypowered.proxy.protocol.ProtocolDirection;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.kyori.adventure.identity.Identity;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ChatPacket implements Packet {
|
public class ClientboundChatPacket implements Packet {
|
||||||
|
|
||||||
public static final byte CHAT_TYPE = (byte) 0;
|
public static final byte CHAT_TYPE = (byte) 0;
|
||||||
public static final byte SYSTEM_TYPE = (byte) 1;
|
public static final byte SYSTEM_TYPE = (byte) 1;
|
||||||
public static final byte GAME_INFO_TYPE = (byte) 2;
|
public static final byte GAME_INFO_TYPE = (byte) 2;
|
||||||
|
|
||||||
public static final int MAX_SERVERBOUND_MESSAGE_LENGTH = 256;
|
|
||||||
public static final UUID EMPTY_SENDER = new UUID(0, 0);
|
|
||||||
|
|
||||||
private @Nullable String message;
|
private @Nullable String message;
|
||||||
private byte type;
|
private byte type;
|
||||||
private @Nullable UUID sender;
|
private @Nullable UUID sender;
|
||||||
|
|
||||||
public ChatPacket() {
|
public ClientboundChatPacket() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatPacket(String message, byte type, UUID sender) {
|
public ClientboundChatPacket(String message, byte type, UUID sender) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.sender = sender;
|
this.sender = sender;
|
||||||
@ -42,29 +36,17 @@ public class ChatPacket implements Packet {
|
|||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte getType() {
|
public byte getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(byte type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID getSenderUuid() {
|
public UUID getSenderUuid() {
|
||||||
return sender;
|
return sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSenderUuid(UUID sender) {
|
|
||||||
this.sender = sender;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Chat{"
|
return "ClientboundChatPacket{"
|
||||||
+ "message='" + message + '\''
|
+ "message='" + message + '\''
|
||||||
+ ", type=" + type
|
+ ", type=" + type
|
||||||
+ ", sender=" + sender
|
+ ", sender=" + sender
|
||||||
@ -74,9 +56,9 @@ public class ChatPacket implements Packet {
|
|||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
message = ProtocolUtils.readString(buf);
|
message = ProtocolUtils.readString(buf);
|
||||||
if (direction == ProtocolDirection.CLIENTBOUND && version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
type = buf.readByte();
|
type = buf.readByte();
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
sender = ProtocolUtils.readUuid(buf);
|
sender = ProtocolUtils.readUuid(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,10 +70,10 @@ public class ChatPacket implements Packet {
|
|||||||
throw new IllegalStateException("Message is not specified");
|
throw new IllegalStateException("Message is not specified");
|
||||||
}
|
}
|
||||||
ProtocolUtils.writeString(buf, message);
|
ProtocolUtils.writeString(buf, message);
|
||||||
if (direction == ProtocolDirection.CLIENTBOUND && version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
buf.writeByte(type);
|
buf.writeByte(type);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
||||||
ProtocolUtils.writeUuid(buf, sender == null ? EMPTY_SENDER : sender);
|
ProtocolUtils.writeUuid(buf, sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,20 +82,4 @@ public class ChatPacket implements Packet {
|
|||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(MinecraftSessionHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChatPacket createClientbound(Identity identity,
|
|
||||||
Component component, ProtocolVersion version) {
|
|
||||||
return createClientbound(component, CHAT_TYPE, identity.uuid(), version);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ChatPacket createClientbound(Component component, byte type,
|
|
||||||
UUID sender, ProtocolVersion version) {
|
|
||||||
Preconditions.checkNotNull(component, "component");
|
|
||||||
return new ChatPacket(ProtocolUtils.getJsonChatSerializer(version).serialize(component), type,
|
|
||||||
sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ChatPacket createServerbound(String message) {
|
|
||||||
return new ChatPacket(message, CHAT_TYPE, EMPTY_SENDER);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -44,7 +44,7 @@ public class EncryptionRequestPacket implements Packet {
|
|||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
this.serverId = ProtocolUtils.readString(buf, 20);
|
this.serverId = ProtocolUtils.readString(buf, 20);
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
publicKey = ProtocolUtils.readByteArray(buf, 256);
|
publicKey = ProtocolUtils.readByteArray(buf, 256);
|
||||||
verifyToken = ProtocolUtils.readByteArray(buf, 16);
|
verifyToken = ProtocolUtils.readByteArray(buf, 16);
|
||||||
} else {
|
} else {
|
||||||
@ -57,7 +57,7 @@ public class EncryptionRequestPacket implements Packet {
|
|||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
ProtocolUtils.writeString(buf, this.serverId);
|
ProtocolUtils.writeString(buf, this.serverId);
|
||||||
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
ProtocolUtils.writeByteArray(buf, publicKey);
|
ProtocolUtils.writeByteArray(buf, publicKey);
|
||||||
ProtocolUtils.writeByteArray(buf, verifyToken);
|
ProtocolUtils.writeByteArray(buf, verifyToken);
|
||||||
} else {
|
} else {
|
||||||
|
@ -33,7 +33,7 @@ public class EncryptionResponsePacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
this.sharedSecret = ProtocolUtils.readByteArray(buf, 256);
|
this.sharedSecret = ProtocolUtils.readByteArray(buf, 256);
|
||||||
this.verifyToken = ProtocolUtils.readByteArray(buf, 128);
|
this.verifyToken = ProtocolUtils.readByteArray(buf, 128);
|
||||||
} else {
|
} else {
|
||||||
@ -44,7 +44,7 @@ public class EncryptionResponsePacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
ProtocolUtils.writeByteArray(buf, sharedSecret);
|
ProtocolUtils.writeByteArray(buf, sharedSecret);
|
||||||
ProtocolUtils.writeByteArray(buf, verifyToken);
|
ProtocolUtils.writeByteArray(buf, verifyToken);
|
||||||
} else {
|
} else {
|
||||||
|
@ -167,7 +167,7 @@ public class JoinGamePacket implements Packet {
|
|||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
this.entityId = buf.readInt();
|
this.entityId = buf.readInt();
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
this.isHardcore = buf.readBoolean();
|
this.isHardcore = buf.readBoolean();
|
||||||
this.gamemode = buf.readByte();
|
this.gamemode = buf.readByte();
|
||||||
} else {
|
} else {
|
||||||
@ -177,12 +177,12 @@ public class JoinGamePacket implements Packet {
|
|||||||
}
|
}
|
||||||
String dimensionIdentifier = null;
|
String dimensionIdentifier = null;
|
||||||
String levelName = null;
|
String levelName = null;
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
this.previousGamemode = buf.readByte();
|
this.previousGamemode = buf.readByte();
|
||||||
ImmutableSet<String> levelNames = ImmutableSet.copyOf(ProtocolUtils.readStringArray(buf));
|
ImmutableSet<String> levelNames = ImmutableSet.copyOf(ProtocolUtils.readStringArray(buf));
|
||||||
CompoundBinaryTag registryContainer = ProtocolUtils.readCompoundTag(buf);
|
CompoundBinaryTag registryContainer = ProtocolUtils.readCompoundTag(buf);
|
||||||
ListBinaryTag dimensionRegistryContainer = null;
|
ListBinaryTag dimensionRegistryContainer = null;
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
dimensionRegistryContainer = registryContainer.getCompound("minecraft:dimension_type")
|
dimensionRegistryContainer = registryContainer.getCompound("minecraft:dimension_type")
|
||||||
.getList("value", BinaryTagTypes.COMPOUND);
|
.getList("value", BinaryTagTypes.COMPOUND);
|
||||||
this.biomeRegistry = registryContainer.getCompound("minecraft:worldgen/biome");
|
this.biomeRegistry = registryContainer.getCompound("minecraft:worldgen/biome");
|
||||||
@ -193,7 +193,7 @@ public class JoinGamePacket implements Packet {
|
|||||||
ImmutableSet<DimensionData> readData =
|
ImmutableSet<DimensionData> readData =
|
||||||
DimensionRegistry.fromGameData(dimensionRegistryContainer, version);
|
DimensionRegistry.fromGameData(dimensionRegistryContainer, version);
|
||||||
this.dimensionRegistry = new DimensionRegistry(readData, levelNames);
|
this.dimensionRegistry = new DimensionRegistry(readData, levelNames);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
CompoundBinaryTag currentDimDataTag = ProtocolUtils.readCompoundTag(buf);
|
CompoundBinaryTag currentDimDataTag = ProtocolUtils.readCompoundTag(buf);
|
||||||
dimensionIdentifier = ProtocolUtils.readString(buf);
|
dimensionIdentifier = ProtocolUtils.readString(buf);
|
||||||
this.currentDimensionData = DimensionData.decodeBaseCompoundTag(currentDimDataTag, version)
|
this.currentDimensionData = DimensionData.decodeBaseCompoundTag(currentDimDataTag, version)
|
||||||
@ -202,35 +202,35 @@ public class JoinGamePacket implements Packet {
|
|||||||
dimensionIdentifier = ProtocolUtils.readString(buf);
|
dimensionIdentifier = ProtocolUtils.readString(buf);
|
||||||
levelName = ProtocolUtils.readString(buf);
|
levelName = ProtocolUtils.readString(buf);
|
||||||
}
|
}
|
||||||
} else if (version.compareTo(ProtocolVersion.MINECRAFT_1_9_1) >= 0) {
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_9_1)) {
|
||||||
this.dimension = buf.readInt();
|
this.dimension = buf.readInt();
|
||||||
} else {
|
} else {
|
||||||
this.dimension = buf.readByte();
|
this.dimension = buf.readByte();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13_2) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_13_2)) {
|
||||||
this.difficulty = buf.readUnsignedByte();
|
this.difficulty = buf.readUnsignedByte();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
this.partialHashedSeed = buf.readLong();
|
this.partialHashedSeed = buf.readLong();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
this.maxPlayers = ProtocolUtils.readVarInt(buf);
|
this.maxPlayers = ProtocolUtils.readVarInt(buf);
|
||||||
} else {
|
} else {
|
||||||
this.maxPlayers = buf.readUnsignedByte();
|
this.maxPlayers = buf.readUnsignedByte();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) < 0) {
|
if (version.lt(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
this.levelType = ProtocolUtils.readString(buf, 16);
|
this.levelType = ProtocolUtils.readString(buf, 16);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_14) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_14)) {
|
||||||
this.viewDistance = ProtocolUtils.readVarInt(buf);
|
this.viewDistance = ProtocolUtils.readVarInt(buf);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
this.reducedDebugInfo = buf.readBoolean();
|
this.reducedDebugInfo = buf.readBoolean();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
this.showRespawnScreen = buf.readBoolean();
|
this.showRespawnScreen = buf.readBoolean();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
boolean isDebug = buf.readBoolean();
|
boolean isDebug = buf.readBoolean();
|
||||||
boolean isFlat = buf.readBoolean();
|
boolean isFlat = buf.readBoolean();
|
||||||
this.dimensionInfo = new DimensionInfo(dimensionIdentifier, levelName, isFlat, isDebug);
|
this.dimensionInfo = new DimensionInfo(dimensionIdentifier, levelName, isFlat, isDebug);
|
||||||
@ -240,18 +240,18 @@ public class JoinGamePacket implements Packet {
|
|||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
buf.writeInt(entityId);
|
buf.writeInt(entityId);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
buf.writeBoolean(isHardcore);
|
buf.writeBoolean(isHardcore);
|
||||||
buf.writeByte(gamemode);
|
buf.writeByte(gamemode);
|
||||||
} else {
|
} else {
|
||||||
buf.writeByte(isHardcore ? gamemode | 0x8 : gamemode);
|
buf.writeByte(isHardcore ? gamemode | 0x8 : gamemode);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
buf.writeByte(previousGamemode);
|
buf.writeByte(previousGamemode);
|
||||||
ProtocolUtils.writeStringArray(buf, dimensionRegistry.getLevelNames().toArray(new String[0]));
|
ProtocolUtils.writeStringArray(buf, dimensionRegistry.getLevelNames().toArray(new String[0]));
|
||||||
CompoundBinaryTag.Builder registryContainer = CompoundBinaryTag.builder();
|
CompoundBinaryTag.Builder registryContainer = CompoundBinaryTag.builder();
|
||||||
ListBinaryTag encodedDimensionRegistry = dimensionRegistry.encodeRegistry(version);
|
ListBinaryTag encodedDimensionRegistry = dimensionRegistry.encodeRegistry(version);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
CompoundBinaryTag.Builder dimensionRegistryEntry = CompoundBinaryTag.builder();
|
CompoundBinaryTag.Builder dimensionRegistryEntry = CompoundBinaryTag.builder();
|
||||||
dimensionRegistryEntry.putString("type", "minecraft:dimension_type");
|
dimensionRegistryEntry.putString("type", "minecraft:dimension_type");
|
||||||
dimensionRegistryEntry.put("value", encodedDimensionRegistry);
|
dimensionRegistryEntry.put("value", encodedDimensionRegistry);
|
||||||
@ -261,45 +261,45 @@ public class JoinGamePacket implements Packet {
|
|||||||
registryContainer.put("dimension", encodedDimensionRegistry);
|
registryContainer.put("dimension", encodedDimensionRegistry);
|
||||||
}
|
}
|
||||||
ProtocolUtils.writeCompoundTag(buf, registryContainer.build());
|
ProtocolUtils.writeCompoundTag(buf, registryContainer.build());
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
ProtocolUtils.writeCompoundTag(buf, currentDimensionData.serializeDimensionDetails());
|
ProtocolUtils.writeCompoundTag(buf, currentDimensionData.serializeDimensionDetails());
|
||||||
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
||||||
} else {
|
} else {
|
||||||
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
||||||
ProtocolUtils.writeString(buf, dimensionInfo.getLevelName());
|
ProtocolUtils.writeString(buf, dimensionInfo.getLevelName());
|
||||||
}
|
}
|
||||||
} else if (version.compareTo(ProtocolVersion.MINECRAFT_1_9_1) >= 0) {
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_9_1)) {
|
||||||
buf.writeInt(dimension);
|
buf.writeInt(dimension);
|
||||||
} else {
|
} else {
|
||||||
buf.writeByte(dimension);
|
buf.writeByte(dimension);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13_2) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_13_2)) {
|
||||||
buf.writeByte(difficulty);
|
buf.writeByte(difficulty);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
buf.writeLong(partialHashedSeed);
|
buf.writeLong(partialHashedSeed);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
ProtocolUtils.writeVarInt(buf, maxPlayers);
|
ProtocolUtils.writeVarInt(buf, maxPlayers);
|
||||||
} else {
|
} else {
|
||||||
buf.writeByte(maxPlayers);
|
buf.writeByte(maxPlayers);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) < 0) {
|
if (version.lt(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
if (levelType == null) {
|
if (levelType == null) {
|
||||||
throw new IllegalStateException("No level type specified.");
|
throw new IllegalStateException("No level type specified.");
|
||||||
}
|
}
|
||||||
ProtocolUtils.writeString(buf, levelType);
|
ProtocolUtils.writeString(buf, levelType);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_14) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_14)) {
|
||||||
ProtocolUtils.writeVarInt(buf, viewDistance);
|
ProtocolUtils.writeVarInt(buf, viewDistance);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
buf.writeBoolean(reducedDebugInfo);
|
buf.writeBoolean(reducedDebugInfo);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
buf.writeBoolean(showRespawnScreen);
|
buf.writeBoolean(showRespawnScreen);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
buf.writeBoolean(dimensionInfo.isDebugType());
|
buf.writeBoolean(dimensionInfo.isDebugType());
|
||||||
buf.writeBoolean(dimensionInfo.isFlat());
|
buf.writeBoolean(dimensionInfo.isFlat());
|
||||||
}
|
}
|
||||||
|
@ -9,47 +9,48 @@ import io.netty.buffer.ByteBuf;
|
|||||||
|
|
||||||
public class KeepAlivePacket implements Packet {
|
public class KeepAlivePacket implements Packet {
|
||||||
|
|
||||||
private long randomId;
|
public static final Decoder<KeepAlivePacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final long randomId;
|
||||||
public long getRandomId() {
|
|
||||||
return randomId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRandomId(long randomId) {
|
|
||||||
this.randomId = randomId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "KeepAlive{"
|
|
||||||
+ "randomId=" + randomId
|
|
||||||
+ '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_12_2) >= 0) {
|
if (version.compareTo(ProtocolVersion.MINECRAFT_1_12_2) >= 0) {
|
||||||
randomId = buf.readLong();
|
randomId = buf.readLong();
|
||||||
} else if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
randomId = ProtocolUtils.readVarInt(buf);
|
randomId = ProtocolUtils.readVarInt(buf);
|
||||||
} else {
|
} else {
|
||||||
randomId = buf.readInt();
|
randomId = buf.readInt();
|
||||||
}
|
}
|
||||||
|
return new KeepAlivePacket(randomId);
|
||||||
|
};
|
||||||
|
|
||||||
|
private final long randomId;
|
||||||
|
|
||||||
|
public KeepAlivePacket(final long randomId) {
|
||||||
|
this.randomId = randomId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_12_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_12_2)) {
|
||||||
buf.writeLong(randomId);
|
buf.writeLong(randomId);
|
||||||
} else if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
ProtocolUtils.writeVarInt(buf, (int) randomId);
|
ProtocolUtils.writeVarInt(buf, (int) randomId);
|
||||||
} else {
|
} else {
|
||||||
buf.writeInt((int) randomId);
|
buf.writeInt((int) randomId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getRandomId() {
|
||||||
|
return randomId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(MinecraftSessionHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "KeepAlive{"
|
||||||
|
+ "randomId=" + randomId
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class PlayerListItemPacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
action = ProtocolUtils.readVarInt(buf);
|
action = ProtocolUtils.readVarInt(buf);
|
||||||
int length = ProtocolUtils.readVarInt(buf);
|
int length = ProtocolUtils.readVarInt(buf);
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ public class PlayerListItemPacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
ProtocolUtils.writeVarInt(buf, action);
|
ProtocolUtils.writeVarInt(buf, action);
|
||||||
ProtocolUtils.writeVarInt(buf, items.size());
|
ProtocolUtils.writeVarInt(buf, items.size());
|
||||||
for (Item item : items) {
|
for (Item item : items) {
|
||||||
|
@ -48,10 +48,10 @@ public class PluginMessagePacket extends DeferredByteBufHolder implements Packet
|
|||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
this.channel = ProtocolUtils.readString(buf);
|
this.channel = ProtocolUtils.readString(buf);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
this.channel = transformLegacyToModernChannel(this.channel);
|
this.channel = transformLegacyToModernChannel(this.channel);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
this.replace(buf.readRetainedSlice(buf.readableBytes()));
|
this.replace(buf.readRetainedSlice(buf.readableBytes()));
|
||||||
} else {
|
} else {
|
||||||
this.replace(ProtocolUtils.readRetainedByteBufSlice17(buf));
|
this.replace(ProtocolUtils.readRetainedByteBufSlice17(buf));
|
||||||
@ -64,12 +64,12 @@ public class PluginMessagePacket extends DeferredByteBufHolder implements Packet
|
|||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
throw new IllegalStateException("Channel is not specified.");
|
throw new IllegalStateException("Channel is not specified.");
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
ProtocolUtils.writeString(buf, transformLegacyToModernChannel(this.channel));
|
ProtocolUtils.writeString(buf, transformLegacyToModernChannel(this.channel));
|
||||||
} else {
|
} else {
|
||||||
ProtocolUtils.writeString(buf, this.channel);
|
ProtocolUtils.writeString(buf, this.channel);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
buf.writeBytes(content());
|
buf.writeBytes(content());
|
||||||
} else {
|
} else {
|
||||||
ProtocolUtils.writeByteBuf17(content(), buf, true); // True for Forge support
|
ProtocolUtils.writeByteBuf17(content(), buf, true); // True for Forge support
|
||||||
|
@ -23,7 +23,7 @@ public class ResourcePackResponsePacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion) {
|
||||||
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_9_4) <= 0) {
|
if (protocolVersion.lte(ProtocolVersion.MINECRAFT_1_9_4)) {
|
||||||
this.hash = ProtocolUtils.readString(buf);
|
this.hash = ProtocolUtils.readString(buf);
|
||||||
}
|
}
|
||||||
this.status = Status.values()[ProtocolUtils.readVarInt(buf)];
|
this.status = Status.values()[ProtocolUtils.readVarInt(buf)];
|
||||||
@ -31,7 +31,7 @@ public class ResourcePackResponsePacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion) {
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion) {
|
||||||
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_9_4) <= 0) {
|
if (protocolVersion.lte(ProtocolVersion.MINECRAFT_1_9_4)) {
|
||||||
ProtocolUtils.writeString(buf, hash);
|
ProtocolUtils.writeString(buf, hash);
|
||||||
}
|
}
|
||||||
ProtocolUtils.writeVarInt(buf, status.ordinal());
|
ProtocolUtils.writeVarInt(buf, status.ordinal());
|
||||||
|
@ -115,8 +115,8 @@ public class RespawnPacket implements Packet {
|
|||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
String dimensionIdentifier = null;
|
String dimensionIdentifier = null;
|
||||||
String levelName = null;
|
String levelName = null;
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
CompoundBinaryTag dimDataTag = ProtocolUtils.readCompoundTag(buf);
|
CompoundBinaryTag dimDataTag = ProtocolUtils.readCompoundTag(buf);
|
||||||
dimensionIdentifier = ProtocolUtils.readString(buf);
|
dimensionIdentifier = ProtocolUtils.readString(buf);
|
||||||
this.currentDimensionData = DimensionData.decodeBaseCompoundTag(dimDataTag, version)
|
this.currentDimensionData = DimensionData.decodeBaseCompoundTag(dimDataTag, version)
|
||||||
@ -128,14 +128,14 @@ public class RespawnPacket implements Packet {
|
|||||||
} else {
|
} else {
|
||||||
this.dimension = buf.readInt();
|
this.dimension = buf.readInt();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13_2) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_13_2)) {
|
||||||
this.difficulty = buf.readUnsignedByte();
|
this.difficulty = buf.readUnsignedByte();
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
this.partialHashedSeed = buf.readLong();
|
this.partialHashedSeed = buf.readLong();
|
||||||
}
|
}
|
||||||
this.gamemode = buf.readByte();
|
this.gamemode = buf.readByte();
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
this.previousGamemode = buf.readByte();
|
this.previousGamemode = buf.readByte();
|
||||||
boolean isDebug = buf.readBoolean();
|
boolean isDebug = buf.readBoolean();
|
||||||
boolean isFlat = buf.readBoolean();
|
boolean isFlat = buf.readBoolean();
|
||||||
@ -148,8 +148,8 @@ public class RespawnPacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16_2)) {
|
||||||
ProtocolUtils.writeCompoundTag(buf, currentDimensionData.serializeDimensionDetails());
|
ProtocolUtils.writeCompoundTag(buf, currentDimensionData.serializeDimensionDetails());
|
||||||
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
|
||||||
} else {
|
} else {
|
||||||
@ -159,14 +159,14 @@ public class RespawnPacket implements Packet {
|
|||||||
} else {
|
} else {
|
||||||
buf.writeInt(dimension);
|
buf.writeInt(dimension);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_13_2) <= 0) {
|
if (version.lte(ProtocolVersion.MINECRAFT_1_13_2)) {
|
||||||
buf.writeByte(difficulty);
|
buf.writeByte(difficulty);
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_15)) {
|
||||||
buf.writeLong(partialHashedSeed);
|
buf.writeLong(partialHashedSeed);
|
||||||
}
|
}
|
||||||
buf.writeByte(gamemode);
|
buf.writeByte(gamemode);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
buf.writeByte(previousGamemode);
|
buf.writeByte(previousGamemode);
|
||||||
buf.writeBoolean(dimensionInfo.isDebugType());
|
buf.writeBoolean(dimensionInfo.isDebugType());
|
||||||
buf.writeBoolean(dimensionInfo.isFlat());
|
buf.writeBoolean(dimensionInfo.isFlat());
|
||||||
|
@ -47,9 +47,9 @@ public class ServerLoginSuccessPacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
uuid = ProtocolUtils.readUuidIntArray(buf);
|
uuid = ProtocolUtils.readUuidIntArray(buf);
|
||||||
} else if (version.compareTo(ProtocolVersion.MINECRAFT_1_7_6) >= 0) {
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_7_6)) {
|
||||||
uuid = UUID.fromString(ProtocolUtils.readString(buf, 36));
|
uuid = UUID.fromString(ProtocolUtils.readString(buf, 36));
|
||||||
} else {
|
} else {
|
||||||
uuid = UuidUtils.fromUndashed(ProtocolUtils.readString(buf, 32));
|
uuid = UuidUtils.fromUndashed(ProtocolUtils.readString(buf, 32));
|
||||||
@ -62,9 +62,9 @@ public class ServerLoginSuccessPacket implements Packet {
|
|||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
throw new IllegalStateException("No UUID specified!");
|
throw new IllegalStateException("No UUID specified!");
|
||||||
}
|
}
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
ProtocolUtils.writeUuidIntArray(buf, uuid);
|
ProtocolUtils.writeUuidIntArray(buf, uuid);
|
||||||
} else if (version.compareTo(ProtocolVersion.MINECRAFT_1_7_6) >= 0) {
|
} else if (version.gte(ProtocolVersion.MINECRAFT_1_7_6)) {
|
||||||
ProtocolUtils.writeString(buf, uuid.toString());
|
ProtocolUtils.writeString(buf, uuid.toString());
|
||||||
} else {
|
} else {
|
||||||
ProtocolUtils.writeString(buf, UuidUtils.toUndashed(uuid));
|
ProtocolUtils.writeString(buf, UuidUtils.toUndashed(uuid));
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.velocitypowered.proxy.protocol.packet;
|
||||||
|
|
||||||
|
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 io.netty.buffer.ByteBuf;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public class ServerboundChatPacket implements Packet {
|
||||||
|
|
||||||
|
public static final Decoder<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 @Nullable String message;
|
||||||
|
|
||||||
|
public ServerboundChatPacket(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
|
if (message == null) {
|
||||||
|
throw new IllegalStateException("Message is not specified");
|
||||||
|
}
|
||||||
|
ProtocolUtils.writeString(buf, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
if (message == null) {
|
||||||
|
throw new IllegalStateException("Message is not specified");
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(MinecraftSessionHandler handler) {
|
||||||
|
return handler.handle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Chat{"
|
||||||
|
+ "message='" + message + '\''
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
}
|
@ -9,42 +9,35 @@ import io.netty.buffer.ByteBuf;
|
|||||||
|
|
||||||
public class SetCompressionPacket implements Packet {
|
public class SetCompressionPacket implements Packet {
|
||||||
|
|
||||||
private int threshold;
|
public static final Decoder<SetCompressionPacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final int threshold = ProtocolUtils.readVarInt(buf);
|
||||||
|
return new SetCompressionPacket(threshold);
|
||||||
|
};
|
||||||
|
|
||||||
public SetCompressionPacket() {
|
private final int threshold;
|
||||||
}
|
|
||||||
|
|
||||||
public SetCompressionPacket(int threshold) {
|
public SetCompressionPacket(int threshold) {
|
||||||
this.threshold = threshold;
|
this.threshold = threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getThreshold() {
|
|
||||||
return threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setThreshold(int threshold) {
|
|
||||||
this.threshold = threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SetCompression{"
|
|
||||||
+ "threshold=" + threshold
|
|
||||||
+ '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
this.threshold = ProtocolUtils.readVarInt(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
ProtocolUtils.writeVarInt(buf, threshold);
|
ProtocolUtils.writeVarInt(buf, threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getThreshold() {
|
||||||
|
return threshold;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(MinecraftSessionHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SetCompression{"
|
||||||
|
+ "threshold=" + threshold
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,15 @@ import io.netty.buffer.ByteBuf;
|
|||||||
|
|
||||||
public class StatusPingPacket implements Packet {
|
public class StatusPingPacket implements Packet {
|
||||||
|
|
||||||
private long randomId;
|
public static Decoder<StatusPingPacket> DECODER = (buf, direction, version) -> {
|
||||||
|
final long randomId = buf.readLong();
|
||||||
|
return new StatusPingPacket(randomId);
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
private final long randomId;
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
randomId = buf.readLong();
|
public StatusPingPacket(final long randomId) {
|
||||||
|
this.randomId = randomId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -9,14 +9,9 @@ import io.netty.buffer.ByteBuf;
|
|||||||
public class StatusRequestPacket implements Packet {
|
public class StatusRequestPacket implements Packet {
|
||||||
|
|
||||||
public static final StatusRequestPacket INSTANCE = new StatusRequestPacket();
|
public static final StatusRequestPacket INSTANCE = new StatusRequestPacket();
|
||||||
|
public static Decoder<StatusRequestPacket> DECODER = (buf, direction, version) -> INSTANCE;
|
||||||
|
|
||||||
private StatusRequestPacket() {
|
private StatusRequestPacket() {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
|
||||||
// There is no additional data to decode.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -24,13 +19,13 @@ public class StatusRequestPacket implements Packet {
|
|||||||
// There is no data to decode.
|
// There is no data to decode.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "StatusRequest";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(MinecraftSessionHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "StatusRequestPacket";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,15 +79,15 @@ public class TabCompleteRequestPacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(MINECRAFT_1_13) >= 0) {
|
if (version.gte(MINECRAFT_1_13)) {
|
||||||
this.transactionId = ProtocolUtils.readVarInt(buf);
|
this.transactionId = ProtocolUtils.readVarInt(buf);
|
||||||
this.command = ProtocolUtils.readString(buf, VANILLA_MAX_TAB_COMPLETE_LEN);
|
this.command = ProtocolUtils.readString(buf, VANILLA_MAX_TAB_COMPLETE_LEN);
|
||||||
} else {
|
} else {
|
||||||
this.command = ProtocolUtils.readString(buf, VANILLA_MAX_TAB_COMPLETE_LEN);
|
this.command = ProtocolUtils.readString(buf, VANILLA_MAX_TAB_COMPLETE_LEN);
|
||||||
if (version.compareTo(MINECRAFT_1_9) >= 0) {
|
if (version.gte(MINECRAFT_1_9)) {
|
||||||
this.assumeCommand = buf.readBoolean();
|
this.assumeCommand = buf.readBoolean();
|
||||||
}
|
}
|
||||||
if (version.compareTo(MINECRAFT_1_8) >= 0) {
|
if (version.gte(MINECRAFT_1_8)) {
|
||||||
this.hasPosition = buf.readBoolean();
|
this.hasPosition = buf.readBoolean();
|
||||||
if (hasPosition) {
|
if (hasPosition) {
|
||||||
this.position = buf.readLong();
|
this.position = buf.readLong();
|
||||||
@ -102,15 +102,15 @@ public class TabCompleteRequestPacket implements Packet {
|
|||||||
throw new IllegalStateException("Command is not specified");
|
throw new IllegalStateException("Command is not specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version.compareTo(MINECRAFT_1_13) >= 0) {
|
if (version.gte(MINECRAFT_1_13)) {
|
||||||
ProtocolUtils.writeVarInt(buf, transactionId);
|
ProtocolUtils.writeVarInt(buf, transactionId);
|
||||||
ProtocolUtils.writeString(buf, command);
|
ProtocolUtils.writeString(buf, command);
|
||||||
} else {
|
} else {
|
||||||
ProtocolUtils.writeString(buf, command);
|
ProtocolUtils.writeString(buf, command);
|
||||||
if (version.compareTo(MINECRAFT_1_9) >= 0) {
|
if (version.gte(MINECRAFT_1_9)) {
|
||||||
buf.writeBoolean(assumeCommand);
|
buf.writeBoolean(assumeCommand);
|
||||||
}
|
}
|
||||||
if (version.compareTo(MINECRAFT_1_8) >= 0) {
|
if (version.gte(MINECRAFT_1_8)) {
|
||||||
buf.writeBoolean(hasPosition);
|
buf.writeBoolean(hasPosition);
|
||||||
if (hasPosition) {
|
if (hasPosition) {
|
||||||
buf.writeLong(position);
|
buf.writeLong(position);
|
||||||
|
@ -61,7 +61,7 @@ public class TabCompleteResponsePacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(MINECRAFT_1_13) >= 0) {
|
if (version.gte(MINECRAFT_1_13)) {
|
||||||
this.transactionId = ProtocolUtils.readVarInt(buf);
|
this.transactionId = ProtocolUtils.readVarInt(buf);
|
||||||
this.start = ProtocolUtils.readVarInt(buf);
|
this.start = ProtocolUtils.readVarInt(buf);
|
||||||
this.length = ProtocolUtils.readVarInt(buf);
|
this.length = ProtocolUtils.readVarInt(buf);
|
||||||
@ -82,7 +82,7 @@ public class TabCompleteResponsePacket implements Packet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
if (version.compareTo(MINECRAFT_1_13) >= 0) {
|
if (version.gte(MINECRAFT_1_13)) {
|
||||||
ProtocolUtils.writeVarInt(buf, this.transactionId);
|
ProtocolUtils.writeVarInt(buf, this.transactionId);
|
||||||
ProtocolUtils.writeVarInt(buf, this.start);
|
ProtocolUtils.writeVarInt(buf, this.start);
|
||||||
ProtocolUtils.writeVarInt(buf, this.length);
|
ProtocolUtils.writeVarInt(buf, this.length);
|
||||||
|
@ -34,7 +34,7 @@ public class TitlePacket implements Packet {
|
|||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
public void encode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) {
|
||||||
ProtocolUtils.writeVarInt(buf, action);
|
ProtocolUtils.writeVarInt(buf, action);
|
||||||
if (version.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0) {
|
if (version.gte(ProtocolVersion.MINECRAFT_1_11)) {
|
||||||
// 1.11+ shifted the action enum by 1 to handle the action bar
|
// 1.11+ shifted the action enum by 1 to handle the action bar
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case SET_TITLE:
|
case SET_TITLE:
|
||||||
@ -121,21 +121,21 @@ public class TitlePacket implements Packet {
|
|||||||
|
|
||||||
public static TitlePacket hideForProtocolVersion(ProtocolVersion version) {
|
public static TitlePacket hideForProtocolVersion(ProtocolVersion version) {
|
||||||
TitlePacket packet = new TitlePacket();
|
TitlePacket packet = new TitlePacket();
|
||||||
packet.setAction(version.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0 ? TitlePacket.HIDE
|
packet.setAction(version.gte(ProtocolVersion.MINECRAFT_1_11) ? TitlePacket.HIDE
|
||||||
: TitlePacket.HIDE_OLD);
|
: TitlePacket.HIDE_OLD);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TitlePacket resetForProtocolVersion(ProtocolVersion version) {
|
public static TitlePacket resetForProtocolVersion(ProtocolVersion version) {
|
||||||
TitlePacket packet = new TitlePacket();
|
TitlePacket packet = new TitlePacket();
|
||||||
packet.setAction(version.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0 ? TitlePacket.RESET
|
packet.setAction(version.gte(ProtocolVersion.MINECRAFT_1_11) ? TitlePacket.RESET
|
||||||
: TitlePacket.RESET_OLD);
|
: TitlePacket.RESET_OLD);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TitlePacket timesForProtocolVersion(ProtocolVersion version) {
|
public static TitlePacket timesForProtocolVersion(ProtocolVersion version) {
|
||||||
TitlePacket packet = new TitlePacket();
|
TitlePacket packet = new TitlePacket();
|
||||||
packet.setAction(version.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0 ? TitlePacket.SET_TIMES
|
packet.setAction(version.gte(ProtocolVersion.MINECRAFT_1_11) ? TitlePacket.SET_TIMES
|
||||||
: TitlePacket.SET_TIMES_OLD);
|
: TitlePacket.SET_TIMES_OLD);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ public final class PluginMessageUtil {
|
|||||||
Collection<String> channels) {
|
Collection<String> channels) {
|
||||||
checkNotNull(channels, "channels");
|
checkNotNull(channels, "channels");
|
||||||
checkArgument(!channels.isEmpty(), "no channels specified");
|
checkArgument(!channels.isEmpty(), "no channels specified");
|
||||||
String channelName = protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_13) >= 0
|
String channelName = protocolVersion.gte(ProtocolVersion.MINECRAFT_1_13)
|
||||||
? REGISTER_CHANNEL : REGISTER_CHANNEL_LEGACY;
|
? REGISTER_CHANNEL : REGISTER_CHANNEL_LEGACY;
|
||||||
ByteBuf contents = Unpooled.buffer();
|
ByteBuf contents = Unpooled.buffer();
|
||||||
contents.writeCharSequence(String.join("\0", channels), StandardCharsets.UTF_8);
|
contents.writeCharSequence(String.join("\0", channels), StandardCharsets.UTF_8);
|
||||||
@ -135,7 +135,7 @@ public final class PluginMessageUtil {
|
|||||||
String rewrittenBrand = String.format("%s (%s)", currentBrand, version.getName());
|
String rewrittenBrand = String.format("%s (%s)", currentBrand, version.getName());
|
||||||
|
|
||||||
ByteBuf rewrittenBuf = Unpooled.buffer();
|
ByteBuf rewrittenBuf = Unpooled.buffer();
|
||||||
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
|
if (protocolVersion.gte(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
ProtocolUtils.writeString(rewrittenBuf, rewrittenBrand);
|
ProtocolUtils.writeString(rewrittenBuf, rewrittenBrand);
|
||||||
} else {
|
} else {
|
||||||
rewrittenBuf.writeCharSequence(rewrittenBrand, StandardCharsets.UTF_8);
|
rewrittenBuf.writeCharSequence(rewrittenBrand, StandardCharsets.UTF_8);
|
||||||
|
@ -94,7 +94,7 @@ public class VelocityChannelRegistrar implements ChannelRegistrar {
|
|||||||
* @return the list of channels to register
|
* @return the list of channels to register
|
||||||
*/
|
*/
|
||||||
public Collection<String> getChannelsForProtocol(ProtocolVersion protocolVersion) {
|
public Collection<String> getChannelsForProtocol(ProtocolVersion protocolVersion) {
|
||||||
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_13) >= 0) {
|
if (protocolVersion.gte(ProtocolVersion.MINECRAFT_1_13)) {
|
||||||
return getModernChannelIds();
|
return getModernChannelIds();
|
||||||
}
|
}
|
||||||
return getLegacyChannelIds();
|
return getLegacyChannelIds();
|
||||||
|
@ -112,7 +112,7 @@ public class AdventureBossBarManager implements BossBar.Listener {
|
|||||||
BossBarPacket rgbPacket = holder.createTitleUpdate(
|
BossBarPacket rgbPacket = holder.createTitleUpdate(
|
||||||
newName, ProtocolVersion.MINECRAFT_1_16);
|
newName, ProtocolVersion.MINECRAFT_1_16);
|
||||||
for (ConnectedPlayer player : holder.subscribers) {
|
for (ConnectedPlayer player : holder.subscribers) {
|
||||||
if (player.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
|
if (player.getProtocolVersion().gte(ProtocolVersion.MINECRAFT_1_16)) {
|
||||||
player.getConnection().write(rgbPacket);
|
player.getConnection().write(rgbPacket);
|
||||||
} else {
|
} else {
|
||||||
player.getConnection().write(pre116Packet);
|
player.getConnection().write(pre116Packet);
|
||||||
|
@ -93,7 +93,7 @@ class PacketRegistryTest {
|
|||||||
() -> registry.register(HandshakePacket.class, HandshakePacket::new,
|
() -> registry.register(HandshakePacket.class, HandshakePacket::new,
|
||||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12, false)));
|
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12, false)));
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> registry.register(StatusPingPacket.class, StatusPingPacket::new,
|
() -> registry.registerNew(StatusPingPacket.class, StatusPingPacket.DECODER,
|
||||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_13, false)));
|
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_13, false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren