mirror of
https://github.com/PaperMC/Velocity.git
synced 2026-02-17 14:37:43 +01:00
Break up StateRegistry
This commit is contained in:
@@ -0,0 +1,797 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Velocity Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.proxy.protocol;
|
||||
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_11;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12_1;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14_4;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_15;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_15_2;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_1;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_2;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_4;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_17;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_17_1;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_18;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_18_2;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_19;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_19_1;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_19_3;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_19_4;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_20;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_20_2;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_20_3;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_20_5;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_21;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_21_2;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_21_4;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_21_5;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_21_6;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_21_9;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_7_2;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_9;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_9_1;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_9_4;
|
||||
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
|
||||
import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.BundleDelimiterPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundCookieRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundSoundEntityPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundStopSoundPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundStoreCookiePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.DialogClearPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.DialogShowPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.EncryptionResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.HeaderAndFooterPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItemPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginAcknowledgedPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PingIdentifyPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfoPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.RemoveResourcePackPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerDataPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerboundCookieResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerboundCustomClickActionPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.StatusRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.StatusResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TransferPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfoPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.chat.ChatAcknowledgementPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.chat.PlayerChatCompletionPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.chat.SystemChatPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.chat.keyed.KeyedPlayerChatPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.chat.keyed.KeyedPlayerCommandPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.chat.legacy.LegacyChatPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.chat.session.SessionPlayerChatPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.chat.session.SessionPlayerCommandPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.chat.session.UnsignedPlayerCommandPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.ActiveFeaturesPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.ClientboundCustomReportDetailsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.ClientboundServerLinksPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.CodeOfConductAcceptPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.CodeOfConductPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.FinishedUpdatePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.KnownPacksPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.RegistrySyncPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.StartUpdatePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.TagsUpdatePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.title.LegacyTitlePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.title.TitleActionbarPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.title.TitleClearPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.title.TitleSubtitlePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.title.TitleTextPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.title.TitleTimesPacket;
|
||||
import com.velocitypowered.proxy.protocol.registry.MultiVersionPacketRegistry;
|
||||
import com.velocitypowered.proxy.protocol.registry.MultiVersionPacketRegistry.VersionRange;
|
||||
import com.velocitypowered.proxy.protocol.registry.ProtocolToPacketRegistry;
|
||||
import com.velocitypowered.proxy.protocol.registry.SimplePacketRegistry;
|
||||
|
||||
/**
|
||||
* Defines the packet mappings for all protocol states and versions supported by Velocity.
|
||||
*/
|
||||
public class ProtocolStates {
|
||||
|
||||
public static final ProtocolToPacketRegistry HANDSHAKE_CLIENTBOUND;
|
||||
public static final ProtocolToPacketRegistry HANDSHAKE_SERVERBOUND;
|
||||
public static final ProtocolToPacketRegistry STATUS_SERVERBOUND;
|
||||
public static final ProtocolToPacketRegistry STATUS_CLIENTBOUND;
|
||||
public static final ProtocolToPacketRegistry CONFIG_SERVERBOUND;
|
||||
public static final ProtocolToPacketRegistry CONFIG_CLIENTBOUND;
|
||||
public static final ProtocolToPacketRegistry PLAY_SERVERBOUND;
|
||||
public static final ProtocolToPacketRegistry PLAY_CLIENTBOUND;
|
||||
public static final ProtocolToPacketRegistry LOGIN_SERVERBOUND;
|
||||
public static final ProtocolToPacketRegistry LOGIN_CLIENTBOUND;
|
||||
|
||||
static {
|
||||
HANDSHAKE_CLIENTBOUND = new SimplePacketRegistry(Direction.CLIENTBOUND);
|
||||
|
||||
SimplePacketRegistry handshakeServerbound = new SimplePacketRegistry(Direction.SERVERBOUND);
|
||||
handshakeServerbound.register(0x00, HandshakePacket.class, HandshakePacket.Codec.INSTANCE);
|
||||
HANDSHAKE_SERVERBOUND = handshakeServerbound;
|
||||
|
||||
SimplePacketRegistry statusServerbound = new SimplePacketRegistry(Direction.SERVERBOUND);
|
||||
statusServerbound.register(0x00,
|
||||
StatusRequestPacket.class, StatusRequestPacket.Codec.INSTANCE);
|
||||
statusServerbound.register(0x01, StatusPingPacket.class, StatusPingPacket.Codec.INSTANCE);
|
||||
STATUS_SERVERBOUND = statusServerbound;
|
||||
|
||||
SimplePacketRegistry statusClientbound = new SimplePacketRegistry(Direction.CLIENTBOUND);
|
||||
statusClientbound.register(0x00,
|
||||
StatusResponsePacket.class, StatusResponsePacket.Codec.INSTANCE);
|
||||
statusClientbound.register(0x01, StatusPingPacket.class, StatusPingPacket.Codec.INSTANCE);
|
||||
STATUS_CLIENTBOUND = statusClientbound;
|
||||
|
||||
CONFIG_SERVERBOUND = MultiVersionPacketRegistry.builder(Direction.SERVERBOUND)
|
||||
.register(ClientSettingsPacket.class, ClientSettingsPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, 0x00))
|
||||
.register(ServerboundCookieResponsePacket.class,
|
||||
ServerboundCookieResponsePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x01))
|
||||
.register(PluginMessagePacket.class, PluginMessagePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x01),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x02))
|
||||
.register(FinishedUpdatePacket.class, FinishedUpdatePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x02),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x03))
|
||||
.register(KeepAlivePacket.class, KeepAlivePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x03),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x04))
|
||||
.register(PingIdentifyPacket.class, PingIdentifyPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x04),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x05))
|
||||
.register(ResourcePackResponsePacket.class, ResourcePackResponsePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x05),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x06))
|
||||
.register(KnownPacksPacket.class, KnownPacksPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x07))
|
||||
.register(ServerboundCustomClickActionPacket.class,
|
||||
ServerboundCustomClickActionPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x08))
|
||||
.register(CodeOfConductAcceptPacket.class, CodeOfConductAcceptPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x09))
|
||||
.build();
|
||||
|
||||
CONFIG_CLIENTBOUND = MultiVersionPacketRegistry.builder(Direction.CLIENTBOUND)
|
||||
.register(ClientboundCookieRequestPacket.class,
|
||||
ClientboundCookieRequestPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x00))
|
||||
.register(PluginMessagePacket.class, PluginMessagePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x00),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x01))
|
||||
.register(DisconnectPacket.class, new DisconnectPacket.Codec(StateRegistry.CONFIG),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x01),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x02))
|
||||
.register(FinishedUpdatePacket.class, FinishedUpdatePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x02),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x03))
|
||||
.register(KeepAlivePacket.class, KeepAlivePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x03),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x04))
|
||||
.register(PingIdentifyPacket.class, PingIdentifyPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x04),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x05))
|
||||
.register(RegistrySyncPacket.class, RegistrySyncPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x05),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x07))
|
||||
.register(RemoveResourcePackPacket.class, RemoveResourcePackPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x06),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x08))
|
||||
.register(ResourcePackRequestPacket.class, ResourcePackRequestPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x06),
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x07),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x09))
|
||||
.register(ClientboundStoreCookiePacket.class, ClientboundStoreCookiePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x0A))
|
||||
.register(TransferPacket.class, TransferPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x0B))
|
||||
.register(ActiveFeaturesPacket.class, ActiveFeaturesPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x07),
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x08),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x0C))
|
||||
.register(TagsUpdatePacket.class, TagsUpdatePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x08),
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x09),
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x0D))
|
||||
.register(KnownPacksPacket.class, KnownPacksPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x0E))
|
||||
.register(ClientboundCustomReportDetailsPacket.class,
|
||||
ClientboundCustomReportDetailsPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_21, 0x0F))
|
||||
.register(ClientboundServerLinksPacket.class, ClientboundServerLinksPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_21, 0x10))
|
||||
.register(DialogClearPacket.class, DialogClearPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x11))
|
||||
.register(DialogShowPacket.class, new DialogShowPacket.Codec(StateRegistry.CONFIG),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x12))
|
||||
.register(CodeOfConductPacket.class, CodeOfConductPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x13))
|
||||
.build();
|
||||
|
||||
LOGIN_SERVERBOUND = MultiVersionPacketRegistry.builder(Direction.SERVERBOUND)
|
||||
.register(ServerLoginPacket.class, ServerLoginPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, 0x00))
|
||||
.register(EncryptionResponsePacket.class, EncryptionResponsePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, 0x01))
|
||||
.register(LoginPluginResponsePacket.class, LoginPluginResponsePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_13, 0x02))
|
||||
.register(LoginAcknowledgedPacket.class, LoginAcknowledgedPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, 0x03))
|
||||
.register(ServerboundCookieResponsePacket.class,
|
||||
ServerboundCookieResponsePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x04))
|
||||
.build();
|
||||
|
||||
LOGIN_CLIENTBOUND = MultiVersionPacketRegistry.builder(Direction.CLIENTBOUND)
|
||||
.register(DisconnectPacket.class, new DisconnectPacket.Codec(StateRegistry.LOGIN),
|
||||
VersionRange.of(MINECRAFT_1_7_2, 0x00))
|
||||
.register(EncryptionRequestPacket.class, EncryptionRequestPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, 0x01))
|
||||
.register(ServerLoginSuccessPacket.class, ServerLoginSuccessPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, 0x02))
|
||||
.register(SetCompressionPacket.class, SetCompressionPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_8, 0x03))
|
||||
.register(LoginPluginMessagePacket.class, LoginPluginMessagePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_13, 0x04))
|
||||
.register(ClientboundCookieRequestPacket.class,
|
||||
ClientboundCookieRequestPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, 0x05))
|
||||
.build();
|
||||
|
||||
// PLAY state is much larger, will continue below
|
||||
PLAY_SERVERBOUND = buildPlayServerbound();
|
||||
PLAY_CLIENTBOUND = buildPlayClientbound();
|
||||
}
|
||||
|
||||
private static ProtocolToPacketRegistry buildPlayServerbound() {
|
||||
return MultiVersionPacketRegistry.builder(Direction.SERVERBOUND)
|
||||
.register(TabCompleteRequestPacket.class, TabCompleteRequestPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x14),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_11, 0x01),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_12, 0x02),
|
||||
VersionRange.of(MINECRAFT_1_12_1, MINECRAFT_1_12_1, 0x01),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_13, 0x05),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_18_2, 0x06),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x08),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x09),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x08),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x09),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x0A),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x0B),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x0D),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x0E))
|
||||
.register(LegacyChatPacket.class, LegacyChatPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x01),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_11, 0x02),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_12, 0x03),
|
||||
VersionRange.of(MINECRAFT_1_12_1, MINECRAFT_1_13, 0x02),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_18_2, 0x03))
|
||||
.register(ChatAcknowledgementPacket.class, ChatAcknowledgementPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_21, 0x03),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x04),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x05))
|
||||
.register(KeyedPlayerCommandPacket.class, KeyedPlayerCommandPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x03),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x04))
|
||||
.register(KeyedPlayerChatPacket.class, KeyedPlayerChatPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x04),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x05))
|
||||
.register(SessionPlayerCommandPacket.class, SessionPlayerCommandPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_20_3, 0x04),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x05),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x06),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x07))
|
||||
.register(UnsignedPlayerCommandPacket.class, UnsignedPlayerCommandPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x04),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x05),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x06))
|
||||
.register(SessionPlayerChatPacket.class, SessionPlayerChatPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_20_3, 0x05),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x06),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x07),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x08))
|
||||
.register(ClientSettingsPacket.class, ClientSettingsPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x15),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_11, 0x04),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_12, 0x05),
|
||||
VersionRange.of(MINECRAFT_1_12_1, MINECRAFT_1_13, 0x04),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_18_2, 0x05),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x07),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x08),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x07),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x08),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x09),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x0A),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x0C),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x0D))
|
||||
.register(ServerboundCookieResponsePacket.class,
|
||||
ServerboundCookieResponsePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x11),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x13),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x14))
|
||||
.register(PluginMessagePacket.class, PluginMessagePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x17),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_11, 0x09),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_12, 0x0A),
|
||||
VersionRange.of(MINECRAFT_1_12_1, MINECRAFT_1_12_1, 0x09),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_13, 0x0A),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_16_4, 0x0B),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x0A),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x0C),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x0D),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x0C),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x0D),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x0F),
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x10),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x12),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x14),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x15))
|
||||
.register(KeepAlivePacket.class, KeepAlivePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x00),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_11, 0x0B),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_12, 0x0C),
|
||||
VersionRange.of(MINECRAFT_1_12_1, MINECRAFT_1_12_1, 0x0B),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_13, 0x0E),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_15_2, 0x0F),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_4, 0x10),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x0F),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x11),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x12),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x11),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x12),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x14),
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x15),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x18),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x1A),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x1B))
|
||||
.register(ResourcePackResponsePacket.class, ResourcePackResponsePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_8, MINECRAFT_1_8, 0x19),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_11, 0x16),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_12, 0x18),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_13, 0x1D),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_15_2, 0x1F),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_1, 0x20),
|
||||
VersionRange.of(MINECRAFT_1_16_2, MINECRAFT_1_18_2, 0x21),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x23),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_20, 0x24),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x27),
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x28),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x2B),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_2, 0x2D),
|
||||
VersionRange.of(MINECRAFT_1_21_4, MINECRAFT_1_21_4, 0x2F),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x30))
|
||||
.register(FinishedUpdatePacket.class, FinishedUpdatePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x0B),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x0C),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x0E),
|
||||
VersionRange.of(MINECRAFT_1_21_6, 0x0F))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static ProtocolToPacketRegistry buildPlayClientbound() {
|
||||
return MultiVersionPacketRegistry.builder(Direction.CLIENTBOUND)
|
||||
.register(BossBarPacket.class, BossBarPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_14, 0x0C),
|
||||
VersionRange.of(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x0D),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_4, 0x0C),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x0D),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19_3, 0x0A),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x0B),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_21_4, 0x0A),
|
||||
VersionRange.of(MINECRAFT_1_21_5, 0x09))
|
||||
.register(LegacyChatPacket.class, LegacyChatPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x02),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_9, MINECRAFT_1_12, 0x0F),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_13, MINECRAFT_1_13, 0x0E),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x0F),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_16, MINECRAFT_1_16_4, 0x0E),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x0F))
|
||||
.register(TabCompleteResponsePacket.class, TabCompleteResponsePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x3A),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_12, 0x0E),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_14, 0x10),
|
||||
VersionRange.of(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x11),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_1, 0x10),
|
||||
VersionRange.of(MINECRAFT_1_16_2, MINECRAFT_1_16_4, 0x0F),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x11),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19_1, 0x0E),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x0D),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x0F),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_21_4, 0x10),
|
||||
VersionRange.of(MINECRAFT_1_21_5, 0x0F))
|
||||
.register(AvailableCommandsPacket.class, AvailableCommandsPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_14, 0x11),
|
||||
VersionRange.of(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x12),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_1, 0x11),
|
||||
VersionRange.of(MINECRAFT_1_16_2, MINECRAFT_1_16_4, 0x10),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x12),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19_1, 0x0F),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x0E),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x10),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_21_4, 0x11),
|
||||
VersionRange.of(MINECRAFT_1_21_5, 0x10))
|
||||
.register(ClientboundCookieRequestPacket.class,
|
||||
ClientboundCookieRequestPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21_4, 0x16),
|
||||
VersionRange.of(MINECRAFT_1_21_5, 0x15))
|
||||
.register(ClientboundSoundEntityPacket.class, ClientboundSoundEntityPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x5D),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x61),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x63),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x65),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x67),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x6E),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x6D),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_9, 0x72))
|
||||
.register(ClientboundStopSoundPacket.class, ClientboundStopSoundPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x5F),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x63),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x66),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x68),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x6A),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x71),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x70),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_9, 0x75))
|
||||
.register(PluginMessagePacket.class, PluginMessagePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x3F),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_12, 0x18),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_13, 0x19),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_14, 0x18),
|
||||
VersionRange.of(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x19),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_1, 0x18),
|
||||
VersionRange.of(MINECRAFT_1_16_2, MINECRAFT_1_16_4, 0x17),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x18),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x15),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x16),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x15),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x17),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x18),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21_4, 0x19),
|
||||
VersionRange.of(MINECRAFT_1_21_5, 0x18))
|
||||
.register(DisconnectPacket.class, new DisconnectPacket.Codec(StateRegistry.PLAY),
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x40),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_12, 0x1A),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_13, 0x1B),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_14, 0x1A),
|
||||
VersionRange.of(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x1B),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_1, 0x1A),
|
||||
VersionRange.of(MINECRAFT_1_16_2, MINECRAFT_1_16_4, 0x19),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x1A),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x17),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x19),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x17),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x1A),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x1B),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21_4, 0x1D),
|
||||
VersionRange.of(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x1C),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x20))
|
||||
.register(KeepAlivePacket.class, KeepAlivePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x00),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_12, 0x1F),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_13, 0x21),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_14_4, 0x20),
|
||||
VersionRange.of(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x21),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_1, 0x20),
|
||||
VersionRange.of(MINECRAFT_1_16_2, MINECRAFT_1_16_4, 0x1F),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x21),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x1E),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x20),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x1F),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x23),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x24),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x26),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x27),
|
||||
VersionRange.of(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x26),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x2B))
|
||||
.register(JoinGamePacket.class, JoinGamePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x01),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_12, 0x23),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_14, 0x25),
|
||||
VersionRange.of(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x26),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_1, 0x25),
|
||||
VersionRange.of(MINECRAFT_1_16_2, MINECRAFT_1_16_4, 0x24),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x26),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x23),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x25),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x24),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x28),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x29),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x2B),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x2C),
|
||||
VersionRange.of(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x2B),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x30))
|
||||
.register(RespawnPacket.class, RespawnPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x07),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_9, MINECRAFT_1_11, 0x33),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_12, MINECRAFT_1_12, 0x34),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_12_1, MINECRAFT_1_12_1, 0x35),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_13, MINECRAFT_1_13, 0x38),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_14, MINECRAFT_1_14, 0x3A),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x3B),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_16, MINECRAFT_1_16_1, 0x3A),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_16_2, MINECRAFT_1_16_4, 0x39),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x3D),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19, MINECRAFT_1_19, 0x3B),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x3E),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x3D),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x41),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x43),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x45),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x47),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x4C),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x4B),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_9, 0x50))
|
||||
.register(RemoveResourcePackPacket.class, RemoveResourcePackPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x43),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x45),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x4A),
|
||||
VersionRange.of(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x49),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x4E))
|
||||
.register(ResourcePackRequestPacket.class, ResourcePackRequestPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_8, MINECRAFT_1_8, 0x48),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_11, 0x32),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_12, 0x33),
|
||||
VersionRange.of(MINECRAFT_1_12_1, MINECRAFT_1_12_1, 0x34),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_13, 0x37),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_14, 0x39),
|
||||
VersionRange.of(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x3A),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_1, 0x39),
|
||||
VersionRange.of(MINECRAFT_1_16_2, MINECRAFT_1_16_4, 0x38),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x3C),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x3A),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x3D),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x3C),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x40),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x42),
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x44),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x46),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x4B),
|
||||
VersionRange.of(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x4A),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x4F))
|
||||
.register(HeaderAndFooterPacket.class, HeaderAndFooterPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_8, MINECRAFT_1_8, 0x47),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_9, MINECRAFT_1_9_1, 0x48),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_9_4, MINECRAFT_1_11, 0x47),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_12, MINECRAFT_1_12, 0x49),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_12_1, MINECRAFT_1_12_1, 0x4A),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_13, MINECRAFT_1_13, 0x4E),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_14, MINECRAFT_1_14, 0x53),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x54),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_16, MINECRAFT_1_16_4, 0x53),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_17, MINECRAFT_1_17_1, 0x5E),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_18, MINECRAFT_1_18_2, 0x5F),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19, MINECRAFT_1_19, 0x60),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x63),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x61),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x65),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x68),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x6A),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x6D),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x74),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x73),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_9, 0x78))
|
||||
.register(LegacyTitlePacket.class, LegacyTitlePacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_8, MINECRAFT_1_11, 0x45),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_12, MINECRAFT_1_12, 0x47),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_12_1, MINECRAFT_1_12_1, 0x48),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_13, MINECRAFT_1_13, 0x4B),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_14, MINECRAFT_1_14_4, 0x4F),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x50),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_16, MINECRAFT_1_16_4, 0x4F))
|
||||
.register(TitleSubtitlePacket.class, TitleSubtitlePacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_17, MINECRAFT_1_17_1, 0x57),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_18, MINECRAFT_1_18_2, 0x58),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x5B),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x59),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x5D),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x5F),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x61),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x63),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x6A),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x69),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_9, 0x6E))
|
||||
.register(TitleTextPacket.class, TitleTextPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_17, MINECRAFT_1_17_1, 0x59),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_18, MINECRAFT_1_18_2, 0x5A),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x5D),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x5B),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x5F),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x61),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x63),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x65),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x6C),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x6B),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_9, 0x70))
|
||||
.register(TitleActionbarPacket.class, TitleActionbarPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x41),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19, MINECRAFT_1_19, 0x40),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x43),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x42),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x46),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x48),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x4A),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x4C),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x51),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x50),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_9, 0x55))
|
||||
.register(TitleTimesPacket.class, TitleTimesPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_17, MINECRAFT_1_17_1, 0x5A),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_18, MINECRAFT_1_18_2, 0x5B),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x5E),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x5C),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x60),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x62),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x64),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x66),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x6D),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x6C),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_9, 0x71))
|
||||
.register(TitleClearPacket.class, TitleClearPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x10),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19, MINECRAFT_1_19_1, 0x0D),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x0C),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x0E),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_21_4, 0x0F),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, 0x0E))
|
||||
.register(LegacyPlayerListItemPacket.class, LegacyPlayerListItemPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_7_2, MINECRAFT_1_8, 0x38),
|
||||
VersionRange.of(MINECRAFT_1_9, MINECRAFT_1_12, 0x2D),
|
||||
VersionRange.of(MINECRAFT_1_12_1, MINECRAFT_1_12_1, 0x2E),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_13, 0x30),
|
||||
VersionRange.of(MINECRAFT_1_14, MINECRAFT_1_14, 0x33),
|
||||
VersionRange.of(MINECRAFT_1_15, MINECRAFT_1_15_2, 0x34),
|
||||
VersionRange.of(MINECRAFT_1_16, MINECRAFT_1_16_1, 0x33),
|
||||
VersionRange.of(MINECRAFT_1_16_2, MINECRAFT_1_16_4, 0x32),
|
||||
VersionRange.of(MINECRAFT_1_17, MINECRAFT_1_18_2, 0x36),
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x34),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x37))
|
||||
.register(RemovePlayerInfoPacket.class, RemovePlayerInfoPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x35),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x39),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x3B),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x3D),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x3F),
|
||||
VersionRange.of(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x3E),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x43))
|
||||
.register(UpsertPlayerInfoPacket.class, UpsertPlayerInfoPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x36),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x3A),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x3C),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x3E),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x40),
|
||||
VersionRange.of(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x3F),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x44))
|
||||
.register(ClientboundStoreCookiePacket.class, ClientboundStoreCookiePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x6B),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x72),
|
||||
VersionRange.of(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x71),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x76))
|
||||
.register(SystemChatPacket.class, SystemChatPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19, MINECRAFT_1_19, 0x5F),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x62),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x60),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x64),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x67),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x69),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x6C),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x73),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x72),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_9, 0x77))
|
||||
.register(PlayerChatCompletionPacket.class, PlayerChatCompletionPacket.Codec.INSTANCE,
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x15),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x14),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x16),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_2, MINECRAFT_1_20_3, 0x17),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_20_5, MINECRAFT_1_21_4, 0x18),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_21_5, 0x17))
|
||||
.register(ServerDataPacket.class, ServerDataPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_19, MINECRAFT_1_19, 0x3F),
|
||||
VersionRange.of(MINECRAFT_1_19_1, MINECRAFT_1_19_1, 0x42),
|
||||
VersionRange.of(MINECRAFT_1_19_3, MINECRAFT_1_19_3, 0x41),
|
||||
VersionRange.of(MINECRAFT_1_19_4, MINECRAFT_1_20, 0x45),
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x47),
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x49),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x4B),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x50),
|
||||
VersionRange.of(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x4F),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x54))
|
||||
.register(StartUpdatePacket.class, StartUpdatePacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_2, MINECRAFT_1_20_2, 0x65),
|
||||
VersionRange.of(MINECRAFT_1_20_3, MINECRAFT_1_20_3, 0x67),
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x69),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_4, 0x70),
|
||||
VersionRange.of(MINECRAFT_1_21_5, MINECRAFT_1_21_6, 0x6F),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x74))
|
||||
.register(BundleDelimiterPacket.class, BundleDelimiterPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_19_4, 0x00))
|
||||
.register(TransferPacket.class, TransferPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_20_5, MINECRAFT_1_21, 0x73),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_6, 0x7A),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x7F))
|
||||
.register(ClientboundCustomReportDetailsPacket.class,
|
||||
ClientboundCustomReportDetailsPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_21, MINECRAFT_1_21, 0x7A),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_6, 0x81),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x86))
|
||||
.register(ClientboundServerLinksPacket.class, ClientboundServerLinksPacket.Codec.INSTANCE,
|
||||
VersionRange.of(MINECRAFT_1_21, MINECRAFT_1_21, 0x7B),
|
||||
VersionRange.of(MINECRAFT_1_21_2, MINECRAFT_1_21_6, 0x82),
|
||||
VersionRange.of(MINECRAFT_1_21_9, 0x87))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ProtocolToPacketRegistry handshake(Direction direction) {
|
||||
return direction == Direction.SERVERBOUND ? HANDSHAKE_SERVERBOUND : HANDSHAKE_CLIENTBOUND;
|
||||
}
|
||||
|
||||
public static ProtocolToPacketRegistry status(Direction direction) {
|
||||
return direction == Direction.SERVERBOUND ? STATUS_SERVERBOUND : STATUS_CLIENTBOUND;
|
||||
}
|
||||
|
||||
public static ProtocolToPacketRegistry login(Direction direction) {
|
||||
return direction == Direction.SERVERBOUND ? LOGIN_SERVERBOUND : LOGIN_CLIENTBOUND;
|
||||
}
|
||||
|
||||
public static ProtocolToPacketRegistry configuration(Direction direction) {
|
||||
return direction == Direction.SERVERBOUND ? CONFIG_SERVERBOUND : CONFIG_CLIENTBOUND;
|
||||
}
|
||||
|
||||
public static ProtocolToPacketRegistry play(Direction direction) {
|
||||
return direction == Direction.SERVERBOUND ? PLAY_SERVERBOUND : PLAY_CLIENTBOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the packet registry for the specified state and direction.
|
||||
*
|
||||
* @param registry the protocol state
|
||||
* @param direction the packet direction
|
||||
* @return the packet registry for the specified state and direction
|
||||
*/
|
||||
public static ProtocolToPacketRegistry lookup(StateRegistry registry, Direction direction) {
|
||||
return switch (registry) {
|
||||
case HANDSHAKE -> handshake(direction);
|
||||
case STATUS -> status(direction);
|
||||
case LOGIN -> login(direction);
|
||||
case CONFIG -> configuration(direction);
|
||||
case PLAY -> play(direction);
|
||||
};
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,8 +20,10 @@ package com.velocitypowered.proxy.protocol.netty;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolStates;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.registry.PacketRegistry;
|
||||
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@@ -39,8 +41,9 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
||||
+ "information, launch Velocity with -Dvelocity.packet-decode-logging=true to see more.");
|
||||
|
||||
private final ProtocolUtils.Direction direction;
|
||||
private ProtocolVersion version;
|
||||
private StateRegistry state;
|
||||
private StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
||||
private PacketRegistry registry;
|
||||
|
||||
/**
|
||||
* Creates a new {@code MinecraftDecoder} decoding packets from the specified {@code direction}.
|
||||
@@ -49,8 +52,8 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
||||
*/
|
||||
public MinecraftDecoder(ProtocolUtils.Direction direction) {
|
||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||
this.registry = StateRegistry.HANDSHAKE.getProtocolRegistry(
|
||||
direction, ProtocolVersion.MINIMUM_VERSION);
|
||||
this.version = ProtocolVersion.MINIMUM_VERSION;
|
||||
this.registry = ProtocolStates.handshake(direction).forVersion(ProtocolVersion.MINIMUM_VERSION);
|
||||
this.state = StateRegistry.HANDSHAKE;
|
||||
}
|
||||
|
||||
@@ -82,11 +85,13 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
||||
|
||||
MinecraftPacket packet;
|
||||
try {
|
||||
packet = codec.decode(buf, direction, registry.version);
|
||||
packet = codec.decode(buf, direction, this.version);
|
||||
} catch (Exception e) {
|
||||
throw handleDecodeFailure(e, codec, packetId);
|
||||
}
|
||||
|
||||
System.out.println(packet);
|
||||
|
||||
if (buf.isReadable()) {
|
||||
throw handleOverflow(packet, buf.readerIndex(), buf.writerIndex());
|
||||
}
|
||||
@@ -100,8 +105,8 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
||||
private void doLengthSanityChecks(ByteBuf buf,
|
||||
com.velocitypowered.proxy.protocol.PacketCodec<? extends MinecraftPacket> codec)
|
||||
throws Exception {
|
||||
int expectedMinLen = codec.decodeExpectedMinLength(buf, direction, registry.version);
|
||||
int expectedMaxLen = codec.decodeExpectedMaxLength(buf, direction, registry.version);
|
||||
int expectedMinLen = codec.decodeExpectedMinLength(buf, direction, this.version);
|
||||
int expectedMaxLen = codec.decodeExpectedMaxLength(buf, direction, this.version);
|
||||
if (expectedMaxLen != -1 && buf.readableBytes() > expectedMaxLen) {
|
||||
throw handleOverflow(codec, expectedMaxLen, buf.readableBytes());
|
||||
}
|
||||
@@ -153,17 +158,18 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
||||
}
|
||||
|
||||
private String getExtraConnectionDetail(int packetId) {
|
||||
return "Direction " + direction + " Protocol " + registry.version + " State " + state
|
||||
return "Direction " + direction + " Protocol " + this.version + " State " + state
|
||||
+ " ID 0x" + Integer.toHexString(packetId);
|
||||
}
|
||||
|
||||
public void setProtocolVersion(ProtocolVersion protocolVersion) {
|
||||
this.registry = state.getProtocolRegistry(direction, protocolVersion);
|
||||
this.version = protocolVersion;
|
||||
this.registry = ProtocolStates.lookup(this.state, this.direction).forVersion(protocolVersion);
|
||||
}
|
||||
|
||||
public void setState(StateRegistry state) {
|
||||
this.state = state;
|
||||
this.setProtocolVersion(registry.version);
|
||||
this.registry = ProtocolStates.lookup(this.state, this.direction).forVersion(this.version);
|
||||
}
|
||||
|
||||
public ProtocolUtils.Direction getDirection() {
|
||||
|
||||
@@ -21,8 +21,10 @@ import com.google.common.base.Preconditions;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.PacketCodec;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolStates;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.registry.PacketRegistry;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
@@ -33,8 +35,9 @@ import io.netty.handler.codec.MessageToByteEncoder;
|
||||
public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
||||
|
||||
private final ProtocolUtils.Direction direction;
|
||||
private ProtocolVersion version;
|
||||
private StateRegistry state;
|
||||
private StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
||||
private PacketRegistry registry;
|
||||
|
||||
/**
|
||||
* Creates a new {@code MinecraftEncoder} encoding packets for the specified {@code direction}.
|
||||
@@ -43,8 +46,8 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
||||
*/
|
||||
public MinecraftEncoder(ProtocolUtils.Direction direction) {
|
||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||
this.registry = StateRegistry.HANDSHAKE.getProtocolRegistry(
|
||||
direction, ProtocolVersion.MINIMUM_VERSION);
|
||||
this.version = ProtocolVersion.MINIMUM_VERSION;
|
||||
this.registry = ProtocolStates.handshake(direction).forVersion(ProtocolVersion.MINIMUM_VERSION);
|
||||
this.state = StateRegistry.HANDSHAKE;
|
||||
}
|
||||
|
||||
@@ -52,13 +55,14 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void encode(ChannelHandlerContext ctx, MinecraftPacket msg, ByteBuf out) {
|
||||
PacketCodec<MinecraftPacket> codec = (PacketCodec<MinecraftPacket>) this.registry.getCodec(msg.getClass());
|
||||
System.out.println(msg);
|
||||
if (codec == null) {
|
||||
throw new IllegalArgumentException("No codec found for packet: " + msg.getClass());
|
||||
}
|
||||
|
||||
int packetId = this.registry.getPacketId(msg);
|
||||
ProtocolUtils.writeVarInt(out, packetId);
|
||||
codec.encode(msg, out, direction, registry.version);
|
||||
codec.encode(msg, out, direction, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,7 +75,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
||||
|
||||
int hint = -1;
|
||||
if (codec != null) {
|
||||
hint = codec.encodeSizeHint(msg, direction, registry.version);
|
||||
hint = codec.encodeSizeHint(msg, direction, version);
|
||||
}
|
||||
|
||||
if (hint < 0) {
|
||||
@@ -84,12 +88,13 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
||||
}
|
||||
|
||||
public void setProtocolVersion(final ProtocolVersion protocolVersion) {
|
||||
this.registry = state.getProtocolRegistry(direction, protocolVersion);
|
||||
this.version = protocolVersion;
|
||||
this.registry = ProtocolStates.lookup(this.state, this.direction).forVersion(protocolVersion);
|
||||
}
|
||||
|
||||
public void setState(StateRegistry state) {
|
||||
this.state = state;
|
||||
this.setProtocolVersion(registry.version);
|
||||
this.registry = ProtocolStates.lookup(state, this.direction).forVersion(version);
|
||||
}
|
||||
|
||||
public ProtocolUtils.Direction getDirection() {
|
||||
|
||||
@@ -21,8 +21,10 @@ import static io.netty.util.ByteProcessor.FIND_NON_NUL;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.PacketCodec;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolStates;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.registry.PacketRegistry;
|
||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -50,7 +52,7 @@ public class MinecraftVarintFrameDecoder extends ByteToMessageDecoder {
|
||||
new QuietDecoderException("Unknown packet");
|
||||
|
||||
private final ProtocolUtils.Direction direction;
|
||||
private final StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
||||
private final PacketRegistry registry;
|
||||
private StateRegistry state;
|
||||
|
||||
/**
|
||||
@@ -60,8 +62,7 @@ public class MinecraftVarintFrameDecoder extends ByteToMessageDecoder {
|
||||
*/
|
||||
public MinecraftVarintFrameDecoder(ProtocolUtils.Direction direction) {
|
||||
this.direction = direction;
|
||||
this.registry = StateRegistry.HANDSHAKE.getProtocolRegistry(
|
||||
direction, ProtocolVersion.MINIMUM_VERSION);
|
||||
this.registry = ProtocolStates.handshake(direction).forVersion(ProtocolVersion.MINIMUM_VERSION);
|
||||
this.state = StateRegistry.HANDSHAKE;
|
||||
}
|
||||
|
||||
@@ -110,9 +111,6 @@ public class MinecraftVarintFrameDecoder extends ByteToMessageDecoder {
|
||||
}
|
||||
|
||||
private boolean validateServerboundHandshakePacket(ByteBuf in, int length) throws Exception {
|
||||
StateRegistry.PacketRegistry.ProtocolRegistry registry =
|
||||
state.getProtocolRegistry(direction, ProtocolVersion.MINIMUM_VERSION);
|
||||
|
||||
final int index = in.readerIndex();
|
||||
final int packetId = readRawVarInt21(in);
|
||||
// Index hasn't changed, we've read nothing
|
||||
@@ -130,8 +128,8 @@ public class MinecraftVarintFrameDecoder extends ByteToMessageDecoder {
|
||||
|
||||
// We 'technically' have the incoming bytes of a payload here, and so, these can actually parse
|
||||
// the packet if needed, so, we'll take advantage of the existing methods
|
||||
int expectedMinLen = codec.decodeExpectedMinLength(in, direction, registry.version);
|
||||
int expectedMaxLen = codec.decodeExpectedMaxLength(in, direction, registry.version);
|
||||
int expectedMinLen = codec.decodeExpectedMinLength(in, direction, ProtocolVersion.MINIMUM_VERSION);
|
||||
int expectedMaxLen = codec.decodeExpectedMaxLength(in, direction, ProtocolVersion.MINIMUM_VERSION);
|
||||
if (expectedMaxLen != -1 && payloadLength > expectedMaxLen) {
|
||||
throw handleOverflow(expectedMaxLen, in.readableBytes());
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@ package com.velocitypowered.proxy.protocol.netty;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolStates;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.registry.PacketRegistry;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
@@ -41,7 +42,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class PlayPacketQueueInboundHandler extends ChannelDuplexHandler {
|
||||
|
||||
private final StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
||||
private final PacketRegistry registry;
|
||||
private final Queue<Object> queue = new ArrayDeque<>();
|
||||
|
||||
/**
|
||||
@@ -50,7 +51,7 @@ public class PlayPacketQueueInboundHandler extends ChannelDuplexHandler {
|
||||
* @param version the protocol version
|
||||
*/
|
||||
public PlayPacketQueueInboundHandler(ProtocolVersion version, ProtocolUtils.Direction direction) {
|
||||
this.registry = StateRegistry.CONFIG.getProtocolRegistry(direction, version);
|
||||
this.registry = ProtocolStates.configuration(direction).forVersion(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,7 +59,7 @@ public class PlayPacketQueueInboundHandler extends ChannelDuplexHandler {
|
||||
if (msg instanceof final MinecraftPacket packet) {
|
||||
// If the packet exists in the CONFIG state, we want to always
|
||||
// ensure that it gets handled by the current handler
|
||||
if (this.registry.containsPacket(packet)) {
|
||||
if (this.registry.canDecodePacket(packet)) {
|
||||
ctx.fireChannelRead(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@ package com.velocitypowered.proxy.protocol.netty;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolStates;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.registry.PacketRegistry;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
@@ -42,7 +43,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class PlayPacketQueueOutboundHandler extends ChannelDuplexHandler {
|
||||
|
||||
private final StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
||||
private final PacketRegistry registry;
|
||||
private final Queue<MinecraftPacket> queue = new ArrayDeque<>();
|
||||
|
||||
/**
|
||||
@@ -51,7 +52,7 @@ public class PlayPacketQueueOutboundHandler extends ChannelDuplexHandler {
|
||||
* @param version the protocol version
|
||||
*/
|
||||
public PlayPacketQueueOutboundHandler(ProtocolVersion version, ProtocolUtils.Direction direction) {
|
||||
this.registry = StateRegistry.CONFIG.getProtocolRegistry(direction, version);
|
||||
this.registry = ProtocolStates.configuration(direction).forVersion(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -63,7 +64,7 @@ public class PlayPacketQueueOutboundHandler extends ChannelDuplexHandler {
|
||||
|
||||
// If the packet exists in the CONFIG state, we want to always
|
||||
// ensure that it gets sent out to the client
|
||||
if (this.registry.containsPacket(packet)) {
|
||||
if (this.registry.canDecodePacket(packet)) {
|
||||
ctx.write(msg, promise);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -86,6 +86,8 @@ public final class AvailableCommandsPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<AvailableCommandsPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public AvailableCommandsPacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -122,6 +122,8 @@ public record BossBarPacket(UUID uuid, int action, @Nullable ComponentHolder nam
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<BossBarPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public BossBarPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -36,10 +36,12 @@ public final class BundleDelimiterPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<BundleDelimiterPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public BundleDelimiterPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
return INSTANCE;
|
||||
return BundleDelimiterPacket.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -141,6 +141,8 @@ public final class ClientSettingsPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ClientSettingsPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ClientSettingsPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -38,6 +38,8 @@ public record ClientboundCookieRequestPacket(Key key) implements MinecraftPacket
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ClientboundCookieRequestPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ClientboundCookieRequestPacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -37,6 +37,8 @@ public record ClientboundSoundEntityPacket(Sound sound, @Nullable Float fixedRan
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ClientboundSoundEntityPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ClientboundSoundEntityPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -42,6 +42,8 @@ public record ClientboundStopSoundPacket(@Nullable Sound.Source source,
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ClientboundStopSoundPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ClientboundStopSoundPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -34,6 +34,8 @@ public record ClientboundStoreCookiePacket(Key key, byte[] payload) implements M
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ClientboundStoreCookiePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ClientboundStoreCookiePacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -37,10 +37,12 @@ public final class DialogClearPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<DialogClearPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public DialogClearPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
return INSTANCE;
|
||||
return DialogClearPacket.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -79,6 +79,8 @@ public final class EncryptionRequestPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<EncryptionRequestPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public EncryptionRequestPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -85,6 +85,8 @@ public final class EncryptionResponsePacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<EncryptionResponsePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public EncryptionResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -104,6 +104,8 @@ public final class HandshakePacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<HandshakePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public HandshakePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion ignored) {
|
||||
|
||||
@@ -52,6 +52,8 @@ public record HeaderAndFooterPacket(ComponentHolder header,
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<HeaderAndFooterPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public HeaderAndFooterPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -196,6 +196,8 @@ public final class JoinGamePacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<JoinGamePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public JoinGamePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -43,6 +43,8 @@ public record KeepAlivePacket(long randomId) implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<KeepAlivePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public KeepAlivePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -37,6 +37,8 @@ public final class LegacyHandshakePacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<LegacyHandshakePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public LegacyHandshakePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -64,6 +64,8 @@ public final class LegacyPingPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<LegacyPingPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public LegacyPingPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -64,6 +64,8 @@ public final class LegacyPlayerListItemPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<LegacyPlayerListItemPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public LegacyPlayerListItemPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -37,10 +37,12 @@ public final class LoginAcknowledgedPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<LoginAcknowledgedPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public LoginAcknowledgedPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
return INSTANCE;
|
||||
return LoginAcknowledgedPacket.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -61,6 +61,8 @@ public final class LoginPluginMessagePacket extends DefaultByteBufHolder impleme
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<LoginPluginMessagePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public LoginPluginMessagePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -70,6 +70,8 @@ public final class LoginPluginResponsePacket extends DefaultByteBufHolder
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<LoginPluginResponsePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public LoginPluginResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -32,6 +32,8 @@ public record PingIdentifyPacket(int id) implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<PingIdentifyPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public PingIdentifyPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -94,6 +94,8 @@ public final class PluginMessagePacket extends DefaultByteBufHolder implements M
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<PluginMessagePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public PluginMessagePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -39,6 +39,8 @@ public record RemovePlayerInfoPacket(Collection<UUID> profilesToRemove) implemen
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<RemovePlayerInfoPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public RemovePlayerInfoPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -39,6 +39,8 @@ public record RemoveResourcePackPacket(@Nullable UUID id) implements MinecraftPa
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<RemoveResourcePackPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public RemoveResourcePackPacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -103,6 +103,8 @@ public final class ResourcePackRequestPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ResourcePackRequestPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ResourcePackRequestPacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -49,6 +49,8 @@ public record ResourcePackResponsePacket(UUID id, String hash,
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ResourcePackResponsePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ResourcePackResponsePacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -151,6 +151,8 @@ public final class RespawnPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<RespawnPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public RespawnPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -61,6 +61,8 @@ public final class ServerDataPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ServerDataPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ServerDataPacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -83,6 +83,8 @@ public final class ServerLoginPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ServerLoginPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ServerLoginPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -71,6 +71,8 @@ public final class ServerLoginSuccessPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ServerLoginSuccessPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ServerLoginSuccessPacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -44,6 +44,8 @@ public record ServerboundCookieResponsePacket(Key key,
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ServerboundCookieResponsePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ServerboundCookieResponsePacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -79,6 +79,8 @@ public class ServerboundCustomClickActionPacket extends DefaultByteBufHolder
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ServerboundCustomClickActionPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ServerboundCustomClickActionPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -43,6 +43,8 @@ public record SetCompressionPacket(int threshold) implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<SetCompressionPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public SetCompressionPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -33,6 +33,8 @@ public record StatusPingPacket(long randomId) implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<StatusPingPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public StatusPingPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -43,10 +43,12 @@ public final class StatusRequestPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<StatusRequestPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public StatusRequestPacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
return INSTANCE;
|
||||
return StatusRequestPacket.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -57,6 +57,8 @@ public final class StatusResponsePacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<StatusResponsePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public StatusResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -89,6 +89,8 @@ public final class TabCompleteRequestPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<TabCompleteRequestPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public TabCompleteRequestPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -97,6 +97,8 @@ public final class TabCompleteResponsePacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<TabCompleteResponsePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public TabCompleteResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -50,6 +50,8 @@ public record TransferPacket(String host, int port) implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<TransferPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public TransferPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -64,6 +64,8 @@ public final class UpsertPlayerInfoPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<UpsertPlayerInfoPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public UpsertPlayerInfoPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -39,6 +39,8 @@ public record ChatAcknowledgementPacket(int offset) implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ChatAcknowledgementPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ChatAcknowledgementPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -58,6 +58,8 @@ public final class PlayerChatCompletionPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<PlayerChatCompletionPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public PlayerChatCompletionPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -60,6 +60,8 @@ public final class SystemChatPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<SystemChatPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public SystemChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -81,6 +81,8 @@ public final class KeyedPlayerChatPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<KeyedPlayerChatPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public KeyedPlayerChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -95,6 +95,8 @@ public final class KeyedPlayerCommandPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<KeyedPlayerCommandPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public KeyedPlayerCommandPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -45,6 +45,8 @@ public record LegacyChatPacket(String message, byte type, @Nullable UUID sender)
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<LegacyChatPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public LegacyChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -85,6 +85,8 @@ public class SessionPlayerChatPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<SessionPlayerChatPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public SessionPlayerChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -89,6 +89,8 @@ public class SessionPlayerCommandPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<SessionPlayerCommandPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public SessionPlayerCommandPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -56,6 +56,8 @@ public final class UnsignedPlayerCommandPacket extends SessionPlayerCommandPacke
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<UnsignedPlayerCommandPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public UnsignedPlayerCommandPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -41,6 +41,8 @@ public record ActiveFeaturesPacket(Key[] activeFeatures) implements MinecraftPac
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ActiveFeaturesPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ActiveFeaturesPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -28,16 +28,14 @@ import java.util.Map;
|
||||
|
||||
public record ClientboundCustomReportDetailsPacket(Map<String, String> details) implements MinecraftPacket {
|
||||
|
||||
public ClientboundCustomReportDetailsPacket() {
|
||||
this(Map.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
return handler.handle(this);
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ClientboundCustomReportDetailsPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ClientboundCustomReportDetailsPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -62,6 +62,8 @@ public record ClientboundServerLinksPacket(List<ServerLink> serverLinks) impleme
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<ClientboundServerLinksPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public ClientboundServerLinksPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion version) {
|
||||
|
||||
@@ -37,10 +37,12 @@ public final class CodeOfConductAcceptPacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<CodeOfConductAcceptPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public CodeOfConductAcceptPacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
return INSTANCE;
|
||||
return CodeOfConductAcceptPacket.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -77,6 +77,8 @@ public class CodeOfConductPacket extends DefaultByteBufHolder implements Minecra
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<CodeOfConductPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public CodeOfConductPacket decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
||||
return new CodeOfConductPacket(buf.readRetainedSlice(buf.readableBytes()));
|
||||
|
||||
@@ -36,10 +36,12 @@ public final class FinishedUpdatePacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<FinishedUpdatePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public FinishedUpdatePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
return INSTANCE;
|
||||
return FinishedUpdatePacket.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -49,6 +49,8 @@ public record KnownPacksPacket(KnownPack[] packs) implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<KnownPacksPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
private static final int MAX_LENGTH_PACKS = Integer.getInteger("velocity.max-known-packs", 64);
|
||||
private static final QuietDecoderException TOO_MANY_PACKS =
|
||||
new QuietDecoderException("too many known packs");
|
||||
|
||||
@@ -42,6 +42,8 @@ public final class RegistrySyncPacket extends DefaultByteBufHolder implements Mi
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<RegistrySyncPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public RegistrySyncPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -36,10 +36,12 @@ public final class StartUpdatePacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<StartUpdatePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public StartUpdatePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
return INSTANCE;
|
||||
return StartUpdatePacket.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -46,6 +46,8 @@ public final class TagsUpdatePacket implements MinecraftPacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<TagsUpdatePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public TagsUpdatePacket decode(ByteBuf buf, Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -78,6 +78,8 @@ public final class LegacyTitlePacket extends GenericTitlePacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<LegacyTitlePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public LegacyTitlePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -51,6 +51,8 @@ public final class TitleActionbarPacket extends GenericTitlePacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<TitleActionbarPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public TitleActionbarPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -49,6 +49,8 @@ public final class TitleClearPacket extends GenericTitlePacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<TitleClearPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public TitleClearPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -51,6 +51,8 @@ public final class TitleSubtitlePacket extends GenericTitlePacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<TitleSubtitlePacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public TitleSubtitlePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -51,6 +51,8 @@ public final class TitleTextPacket extends GenericTitlePacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<TitleTextPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public TitleTextPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -66,6 +66,8 @@ public final class TitleTimesPacket extends GenericTitlePacket {
|
||||
}
|
||||
|
||||
public static class Codec implements PacketCodec<TitleTimesPacket> {
|
||||
public static final Codec INSTANCE = new Codec();
|
||||
|
||||
@Override
|
||||
public TitleTimesPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||
ProtocolVersion protocolVersion) {
|
||||
|
||||
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Velocity Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.proxy.protocol.registry;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.PacketCodec;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
|
||||
import io.netty.util.collection.IntObjectHashMap;
|
||||
import io.netty.util.collection.IntObjectMap;
|
||||
import it.unimi.dsi.fastutil.Hash.Strategy;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* A multi-version packet registry that supports different packet ID mappings across protocol
|
||||
* versions. This implementation optimizes memory usage by reusing mapping data structures across
|
||||
* versions when the mappings are identical.
|
||||
*/
|
||||
public class MultiVersionPacketRegistry implements ProtocolToPacketRegistry {
|
||||
|
||||
private final Map<ProtocolVersion, VersionMapping> versionMappings;
|
||||
|
||||
private MultiVersionPacketRegistry(
|
||||
Map<ProtocolVersion, VersionMapping> versionMappings) {
|
||||
this.versionMappings = versionMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketRegistry forVersion(ProtocolVersion version) {
|
||||
VersionMapping mapping = this.versionMappings.get(version);
|
||||
if (mapping == null) {
|
||||
throw new IllegalArgumentException(String.format("Invalid version %s", version));
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds the packet mappings for a specific protocol version or a range of versions.
|
||||
* Instances are shared across versions when the mappings are identical.
|
||||
*/
|
||||
private static class VersionMapping implements PacketRegistry {
|
||||
|
||||
final IntObjectMap<PacketCodec<? extends MinecraftPacket>> packetIdToCodec;
|
||||
final Map<Class<? extends MinecraftPacket>, PacketCodec<? extends MinecraftPacket>>
|
||||
packetClassToCodec;
|
||||
final Object2IntMap<Class<? extends MinecraftPacket>> packetClassToId;
|
||||
final Direction direction;
|
||||
final ProtocolVersion version;
|
||||
|
||||
VersionMapping(Direction direction, ProtocolVersion version) {
|
||||
this.direction = direction;
|
||||
this.version = version;
|
||||
this.packetIdToCodec = new IntObjectHashMap<>(16, 0.5f);
|
||||
this.packetClassToCodec = new HashMap<>(16, 0.5f);
|
||||
this.packetClassToId = new Object2IntOpenHashMap<>(16, 0.5f);
|
||||
this.packetClassToId.defaultReturnValue(Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
void register(int id, Class<? extends MinecraftPacket> packet,
|
||||
PacketCodec<? extends MinecraftPacket> codec, boolean encodeOnly) {
|
||||
if (!encodeOnly) {
|
||||
this.packetIdToCodec.put(id, codec);
|
||||
}
|
||||
this.packetClassToCodec.put(packet, codec);
|
||||
this.packetClassToId.put(packet, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
VersionMapping that = (VersionMapping) o;
|
||||
return Objects.equals(packetIdToCodec, that.packetIdToCodec)
|
||||
&& Objects.equals(packetClassToCodec, that.packetClassToCodec)
|
||||
&& Objects.equals(packetClassToId, that.packetClassToId)
|
||||
&& Objects.equals(direction, that.direction)
|
||||
&& Objects.equals(version, that.version);
|
||||
}
|
||||
|
||||
public boolean equalsNonStrict(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
VersionMapping that = (VersionMapping) o;
|
||||
return Objects.equals(packetIdToCodec, that.packetIdToCodec)
|
||||
&& Objects.equals(packetClassToCodec, that.packetClassToCodec)
|
||||
&& Objects.equals(packetClassToId, that.packetClassToId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(packetIdToCodec, packetClassToCodec, packetClassToId, direction, version);
|
||||
}
|
||||
|
||||
public int hashCodeNonStrict() {
|
||||
return Objects.hash(packetIdToCodec, packetClassToCodec, packetClassToId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PacketCodec<? extends MinecraftPacket> getCodec(int id) {
|
||||
return packetIdToCodec.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends MinecraftPacket> @Nullable PacketCodec<T> getCodec(Class<T> packetClass) {
|
||||
return (PacketCodec<T>) packetClassToCodec.get(packetClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPacketId(MinecraftPacket packet) {
|
||||
final int id = packetClassToId.getInt(packet.getClass());
|
||||
if (id == Integer.MIN_VALUE) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Unable to find id for packet of type %s in %s protocol %s",
|
||||
packet.getClass().getName(), direction, version
|
||||
));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDecodePacket(MinecraftPacket packet) {
|
||||
return packetClassToId.containsKey(packet.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new builder for constructing a multi-version packet registry.
|
||||
*
|
||||
* @param direction the packet direction (clientbound or serverbound)
|
||||
* @return a new builder instance
|
||||
*/
|
||||
public static Builder builder(Direction direction) {
|
||||
return new Builder(direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for constructing a MultiVersionPacketRegistry with optimized memory usage.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private final Direction direction;
|
||||
private final Map<ProtocolVersion, VersionMapping> workingMappings =
|
||||
new EnumMap<>(ProtocolVersion.class);
|
||||
|
||||
private Builder(Direction direction) {
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a packet for a specific protocol version with a given ID.
|
||||
*
|
||||
* @param packetClass the packet class
|
||||
* @param codec the packet codec
|
||||
* @param version the protocol version
|
||||
* @param packetId the packet ID
|
||||
* @param <T> the packet type
|
||||
* @return this builder
|
||||
*/
|
||||
public <T extends MinecraftPacket> Builder register(
|
||||
Class<T> packetClass,
|
||||
PacketCodec<T> codec,
|
||||
ProtocolVersion version,
|
||||
int packetId) {
|
||||
return register(packetClass, codec, version, null, packetId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a packet for a range of protocol versions with a given ID.
|
||||
*
|
||||
* @param packetClass the packet class
|
||||
* @param codec the packet codec
|
||||
* @param startVersion the starting protocol version (inclusive)
|
||||
* @param endVersion the ending protocol version (inclusive), or null for all future versions
|
||||
* @param packetId the packet ID
|
||||
* @param encodeOnly if true, the packet will only be registered for encoding, not decoding
|
||||
* @param <T> the packet type
|
||||
* @return this builder
|
||||
*/
|
||||
public <T extends MinecraftPacket> Builder register(
|
||||
Class<T> packetClass,
|
||||
PacketCodec<T> codec,
|
||||
ProtocolVersion startVersion,
|
||||
@Nullable ProtocolVersion endVersion,
|
||||
int packetId,
|
||||
boolean encodeOnly) {
|
||||
|
||||
ProtocolVersion end = endVersion != null ? endVersion : ProtocolVersion.MAXIMUM_VERSION;
|
||||
|
||||
// Validate version range
|
||||
if (startVersion.greaterThan(end)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Start version %s is greater than end version %s", startVersion, end
|
||||
));
|
||||
}
|
||||
|
||||
// Register for all versions in the range
|
||||
for (ProtocolVersion version : ProtocolVersion.values()) {
|
||||
if (version.isLegacy() || version.isUnknown()) {
|
||||
continue;
|
||||
}
|
||||
if (version.noLessThan(startVersion) && version.noGreaterThan(end)) {
|
||||
VersionMapping versionMapping = workingMappings.computeIfAbsent(version, v -> new VersionMapping(direction, version));
|
||||
if (versionMapping.packetClassToCodec.containsKey(packetClass)) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Packet %s already registered for version %s", packetClass.getName(), version
|
||||
));
|
||||
}
|
||||
versionMapping.register(packetId, packetClass, codec, encodeOnly);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a packet for multiple version ranges.
|
||||
*
|
||||
* @param packetClass the packet class
|
||||
* @param codec the packet codec
|
||||
* @param ranges the version ranges to register
|
||||
* @param <T> the packet type
|
||||
* @return this builder
|
||||
*/
|
||||
public <T extends MinecraftPacket> Builder register(
|
||||
Class<T> packetClass,
|
||||
PacketCodec<T> codec,
|
||||
VersionRange... ranges) {
|
||||
if (ranges.length == 0) {
|
||||
throw new IllegalArgumentException("At least one version range must be provided");
|
||||
}
|
||||
for (VersionRange range : ranges) {
|
||||
register(packetClass, codec, range.start, range.end, range.packetId, range.encodeOnly);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the multi-version packet registry, optimizing memory by reusing identical mappings
|
||||
* across versions.
|
||||
*
|
||||
* @return the constructed registry
|
||||
*/
|
||||
public MultiVersionPacketRegistry build() {
|
||||
// Optimize by reusing identical mappings across versions
|
||||
Map<ProtocolVersion, VersionMapping> optimized = new EnumMap<>(ProtocolVersion.class);
|
||||
Map<VersionMapping, VersionMapping> deduplicationMap = new Object2ObjectOpenCustomHashMap<>(
|
||||
new Strategy<>() {
|
||||
@Override
|
||||
public int hashCode(VersionMapping o) {
|
||||
return o.hashCodeNonStrict();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(VersionMapping a, VersionMapping b) {
|
||||
return a.equalsNonStrict(b);
|
||||
}
|
||||
});
|
||||
|
||||
for (Map.Entry<ProtocolVersion, VersionMapping> entry : workingMappings.entrySet()) {
|
||||
VersionMapping mapping = entry.getValue();
|
||||
VersionMapping canonical = deduplicationMap.get(mapping);
|
||||
if (canonical == null) {
|
||||
// First time seeing this mapping, use it as the canonical version
|
||||
deduplicationMap.put(mapping, mapping);
|
||||
canonical = mapping;
|
||||
}
|
||||
// Reuse the canonical mapping
|
||||
optimized.put(entry.getKey(), canonical);
|
||||
}
|
||||
|
||||
return new MultiVersionPacketRegistry(Collections.unmodifiableMap(optimized));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a version range for packet registration.
|
||||
*/
|
||||
public static class VersionRange {
|
||||
|
||||
final ProtocolVersion start;
|
||||
final @Nullable ProtocolVersion end;
|
||||
final int packetId;
|
||||
final boolean encodeOnly;
|
||||
|
||||
private VersionRange(
|
||||
ProtocolVersion start,
|
||||
@Nullable ProtocolVersion end,
|
||||
int packetId,
|
||||
boolean encodeOnly) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.packetId = packetId;
|
||||
this.encodeOnly = encodeOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a version range starting from the specified version and continuing to all future
|
||||
* versions.
|
||||
*
|
||||
* @param start the starting version
|
||||
* @param packetId the packet ID
|
||||
* @return a new version range
|
||||
*/
|
||||
public static VersionRange of(ProtocolVersion start, int packetId) {
|
||||
return new VersionRange(start, null, packetId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a version range from start to end (inclusive).
|
||||
*
|
||||
* @param start the starting version
|
||||
* @param end the ending version
|
||||
* @param packetId the packet ID
|
||||
* @return a new version range
|
||||
*/
|
||||
public static VersionRange of(ProtocolVersion start, ProtocolVersion end, int packetId) {
|
||||
return new VersionRange(start, end, packetId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an encode-only version range starting from the specified version.
|
||||
*
|
||||
* @param start the starting version
|
||||
* @param packetId the packet ID
|
||||
* @return a new version range
|
||||
*/
|
||||
public static VersionRange encodeOnly(ProtocolVersion start, int packetId) {
|
||||
return new VersionRange(start, null, packetId, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an encode-only version range from start to end (inclusive).
|
||||
*
|
||||
* @param start the starting version
|
||||
* @param end the ending version
|
||||
* @param packetId the packet ID
|
||||
* @return a new version range
|
||||
*/
|
||||
public static VersionRange encodeOnly(
|
||||
ProtocolVersion start, ProtocolVersion end, int packetId) {
|
||||
return new VersionRange(start, end, packetId, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Velocity Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.proxy.protocol.registry;
|
||||
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.PacketCodec;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Interface for retrieving packet codecs and IDs for a specific protocol version.
|
||||
*/
|
||||
public interface PacketRegistry {
|
||||
@Nullable
|
||||
PacketCodec<? extends MinecraftPacket> getCodec(final int id);
|
||||
|
||||
<T extends MinecraftPacket> @Nullable PacketCodec<T> getCodec(
|
||||
final Class<T> packetClass);
|
||||
|
||||
int getPacketId(final MinecraftPacket packet);
|
||||
|
||||
boolean canDecodePacket(MinecraftPacket packet);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Velocity Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.proxy.protocol.registry;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
|
||||
/**
|
||||
* Registry mapping protocol versions to their packet registries.
|
||||
*/
|
||||
public interface ProtocolToPacketRegistry {
|
||||
PacketRegistry forVersion(ProtocolVersion version);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Velocity Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.proxy.protocol.registry;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.PacketCodec;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
|
||||
import io.netty.util.collection.IntObjectHashMap;
|
||||
import io.netty.util.collection.IntObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Extremely simple packet registry implementation that assumes every protocol version is
|
||||
* the same.
|
||||
*/
|
||||
public class SimplePacketRegistry implements PacketRegistry, ProtocolToPacketRegistry {
|
||||
private final IntObjectMap<PacketCodec<? extends MinecraftPacket>> packetIdToCodec =
|
||||
new IntObjectHashMap<>(16, 0.5f);
|
||||
private final Map<Class<? extends MinecraftPacket>, PacketCodec<? extends MinecraftPacket>> packetClassToCodec =
|
||||
new HashMap<>(16, 0.5f);
|
||||
private final Object2IntMap<Class<? extends MinecraftPacket>> packetClassToId =
|
||||
new Object2IntOpenHashMap<>(16, 0.5f);
|
||||
private final Direction direction;
|
||||
|
||||
public SimplePacketRegistry(Direction direction) {
|
||||
this.direction = direction;
|
||||
this.packetClassToId.defaultReturnValue(Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a packet for this protocol version.
|
||||
*
|
||||
* @param id the packet ID
|
||||
* @param packet the packet class
|
||||
* @param codec the packet codec
|
||||
*/
|
||||
public void register(int id, Class<? extends MinecraftPacket> packet, PacketCodec<? extends MinecraftPacket> codec) {
|
||||
this.packetIdToCodec.put(id, codec);
|
||||
this.packetClassToCodec.put(packet, codec);
|
||||
this.packetClassToId.put(packet, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PacketCodec<? extends MinecraftPacket> getCodec(int id) {
|
||||
return this.packetIdToCodec.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable <T extends MinecraftPacket> PacketCodec<T> getCodec(Class<T> packetClass) {
|
||||
return (PacketCodec<T>) this.packetClassToCodec.get(packetClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPacketId(MinecraftPacket packet) {
|
||||
final int id = this.packetClassToId.getInt(packet.getClass());
|
||||
if (id == Integer.MIN_VALUE) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Unable to find id for packet of type %s in %s phase %s",
|
||||
packet.getClass().getName(), direction, this
|
||||
));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDecodePacket(MinecraftPacket packet) {
|
||||
return packetClassToId.containsKey(packet.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketRegistry forVersion(ProtocolVersion version) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
package com.velocitypowered.proxy.protocol;
|
||||
|
||||
import static com.google.common.collect.Iterables.getLast;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MAXIMUM_VERSION;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_11;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12_1;
|
||||
@@ -25,136 +26,414 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12_2;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14_2;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14_4;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_15;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_2;
|
||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
||||
import com.velocitypowered.proxy.protocol.registry.MultiVersionPacketRegistry;
|
||||
import com.velocitypowered.proxy.protocol.registry.MultiVersionPacketRegistry.VersionRange;
|
||||
import com.velocitypowered.proxy.protocol.registry.SimplePacketRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class PacketRegistryTest {
|
||||
|
||||
private StateRegistry.PacketRegistry setupRegistry() {
|
||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
|
||||
ProtocolUtils.Direction.CLIENTBOUND, StateRegistry.PLAY);
|
||||
registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_8, null, false),
|
||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12, null, false),
|
||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_15, MINECRAFT_1_16, false));
|
||||
return registry;
|
||||
/**
|
||||
* Sets up a multi-version registry with HandshakePacket mapped to different IDs across version
|
||||
* ranges.
|
||||
*/
|
||||
private MultiVersionPacketRegistry setupRegistry() {
|
||||
return MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_8, MINECRAFT_1_11, 0x01),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_14_4, 0x00),
|
||||
VersionRange.of(MINECRAFT_1_15, MAXIMUM_VERSION, 0x00))
|
||||
.build();
|
||||
}
|
||||
|
||||
// ==================== Basic Functionality Tests ====================
|
||||
|
||||
@Test
|
||||
void packetRegistryWorks() {
|
||||
StateRegistry.PacketRegistry registry = setupRegistry();
|
||||
PacketCodec<?> packet = registry.getProtocolRegistry(MINECRAFT_1_12).getCodec(0);
|
||||
MultiVersionPacketRegistry registry = setupRegistry();
|
||||
PacketCodec<?> packet = registry.forVersion(MINECRAFT_1_12).getCodec(0);
|
||||
assertNotNull(packet, "Packet was not found in registry");
|
||||
assertEquals(HandshakePacket.Codec.class, packet.getClass(), "Registry returned wrong class");
|
||||
|
||||
assertEquals(0, registry.getProtocolRegistry(MINECRAFT_1_12).getPacketId(new HandshakePacket()),
|
||||
assertEquals(0, registry.forVersion(MINECRAFT_1_12).getPacketId(new HandshakePacket()),
|
||||
"Registry did not return the correct packet ID");
|
||||
}
|
||||
|
||||
@Test
|
||||
void packetRegistryLinkingWorks() {
|
||||
StateRegistry.PacketRegistry registry = setupRegistry();
|
||||
PacketCodec<?> packet = registry.getProtocolRegistry(MINECRAFT_1_12_1).getCodec(0);
|
||||
MultiVersionPacketRegistry registry = setupRegistry();
|
||||
PacketCodec<?> packet = registry.forVersion(MINECRAFT_1_12_1).getCodec(0);
|
||||
assertNotNull(packet, "Packet was not found in registry");
|
||||
assertEquals(HandshakePacket.Codec.class, packet.getClass(), "Registry returned wrong class");
|
||||
HandshakePacket handshakePacket = new HandshakePacket();
|
||||
assertEquals(0, registry.getProtocolRegistry(MINECRAFT_1_12_1).getPacketId(handshakePacket),
|
||||
assertEquals(0, registry.forVersion(MINECRAFT_1_12_1).getPacketId(handshakePacket),
|
||||
"Registry did not return the correct packet ID");
|
||||
assertEquals(0, registry.getProtocolRegistry(MINECRAFT_1_14_2).getPacketId(handshakePacket),
|
||||
assertEquals(0, registry.forVersion(MINECRAFT_1_14_2).getPacketId(handshakePacket),
|
||||
"Registry did not return the correct packet ID");
|
||||
assertEquals(1, registry.getProtocolRegistry(MINECRAFT_1_11).getPacketId(handshakePacket),
|
||||
assertEquals(1, registry.forVersion(MINECRAFT_1_11).getPacketId(handshakePacket),
|
||||
"Registry did not return the correct packet ID");
|
||||
assertNull(registry.getProtocolRegistry(MINECRAFT_1_14_2).getCodec(0x01),
|
||||
assertNull(registry.forVersion(MINECRAFT_1_14_2).getCodec(0x01),
|
||||
"Registry should return a null");
|
||||
assertNull(registry.getProtocolRegistry(MINECRAFT_1_16_2).getCodec(0),
|
||||
"Registry should return null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void failOnNoMappings() {
|
||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
|
||||
ProtocolUtils.Direction.CLIENTBOUND, StateRegistry.PLAY);
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> registry.register(HandshakePacket.class, new HandshakePacket.Codec()));
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> registry.getProtocolRegistry(ProtocolVersion.UNKNOWN)
|
||||
.getPacketId(new HandshakePacket()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void failOnWrongOrder() {
|
||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
|
||||
ProtocolUtils.Direction.CLIENTBOUND, StateRegistry.PLAY);
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, null, false),
|
||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_8, null, false)));
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, null, false),
|
||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, null, false)));
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, MINECRAFT_1_8, false)));
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_8, MINECRAFT_1_14, false),
|
||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_16, null, false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void failOnDuplicate() {
|
||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
|
||||
ProtocolUtils.Direction.CLIENTBOUND, StateRegistry.PLAY);
|
||||
registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_8, null, false));
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12, null, false)));
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> registry.register(StatusPingPacket.class, new StatusPingPacket.Codec(),
|
||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_13, null, false)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotFailWhenRegisterLatestProtocolVersion() {
|
||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
|
||||
ProtocolUtils.Direction.CLIENTBOUND, StateRegistry.PLAY);
|
||||
assertDoesNotThrow(() -> registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_8, null, false),
|
||||
new StateRegistry.PacketMapping(0x01, getLast(ProtocolVersion.SUPPORTED_VERSIONS),
|
||||
null, false)));
|
||||
// 1.16_2 is >= 1.15, so it should have codec for 0x00 from the last range
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_16_2).getCodec(0),
|
||||
"1.16_2 should have codec for 0x00 from 1.15+ range");
|
||||
}
|
||||
|
||||
@Test
|
||||
void registrySuppliesCorrectPacketsByProtocol() {
|
||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
|
||||
ProtocolUtils.Direction.CLIENTBOUND, StateRegistry.PLAY);
|
||||
registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12, null, false),
|
||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12_1, null, false),
|
||||
new StateRegistry.PacketMapping(0x02, MINECRAFT_1_13, null, false));
|
||||
MultiVersionPacketRegistry registry = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_12, 0x00),
|
||||
VersionRange.of(MINECRAFT_1_12_1, MINECRAFT_1_12_2, 0x01),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_14_4, 0x02))
|
||||
.build();
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_12).getCodec(0x00));
|
||||
assertEquals(HandshakePacket.Codec.class,
|
||||
registry.getProtocolRegistry(MINECRAFT_1_12).getCodec(0x00).getClass());
|
||||
registry.forVersion(MINECRAFT_1_12).getCodec(0x00).getClass());
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_12_1).getCodec(0x01));
|
||||
assertEquals(HandshakePacket.Codec.class,
|
||||
registry.getProtocolRegistry(MINECRAFT_1_12_1).getCodec(0x01).getClass());
|
||||
registry.forVersion(MINECRAFT_1_12_1).getCodec(0x01).getClass());
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_12_2).getCodec(0x01));
|
||||
assertEquals(HandshakePacket.Codec.class,
|
||||
registry.getProtocolRegistry(MINECRAFT_1_12_2).getCodec(0x01).getClass());
|
||||
registry.forVersion(MINECRAFT_1_12_2).getCodec(0x01).getClass());
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_13).getCodec(0x02));
|
||||
assertEquals(HandshakePacket.Codec.class,
|
||||
registry.getProtocolRegistry(MINECRAFT_1_13).getCodec(0x02).getClass());
|
||||
registry.forVersion(MINECRAFT_1_13).getCodec(0x02).getClass());
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_14_2).getCodec(0x02));
|
||||
assertEquals(HandshakePacket.Codec.class,
|
||||
registry.getProtocolRegistry(MINECRAFT_1_14_2).getCodec(0x02).getClass());
|
||||
registry.forVersion(MINECRAFT_1_14_2).getCodec(0x02).getClass());
|
||||
}
|
||||
|
||||
// ==================== Error Handling Tests ====================
|
||||
|
||||
@Test
|
||||
void failOnNoMappings() {
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.build()
|
||||
.forVersion(ProtocolVersion.UNKNOWN));
|
||||
}
|
||||
|
||||
@Test
|
||||
void failOnWrongVersionOrder() {
|
||||
// End version before start version
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_13, 0x01),
|
||||
VersionRange.of(MINECRAFT_1_8, 0x00))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void failOnInvalidRangeStartGreaterThanEnd() {
|
||||
// Single VersionRange with start > end
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_8, 0x01))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void failOnDuplicateVersionRanges() {
|
||||
// Two ranges covering the same version
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_13, 0x01),
|
||||
VersionRange.of(MINECRAFT_1_13, 0x01))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void failOnOverlappingVersionRanges() {
|
||||
// Same packet registered twice with overlapping versions should fail
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_8, MINECRAFT_1_14, 0x01))
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_16, 0x00))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void failOnDuplicatePacketClass() {
|
||||
// Same packet class registered twice for overlapping versions
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_8, MINECRAFT_1_14, 0x00))
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_12, 0x01))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void allowDifferentPacketsWithSameIdInDifferentVersions() {
|
||||
// Different packets can have the same ID in different version ranges
|
||||
assertDoesNotThrow(
|
||||
() -> MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_8, MINECRAFT_1_12, 0x00))
|
||||
.register(StatusPingPacket.class, new StatusPingPacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_13, MAXIMUM_VERSION, 0x00))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void failOnInvalidPacketIdLookup() {
|
||||
MultiVersionPacketRegistry registry = setupRegistry();
|
||||
// Try to get packet ID for a packet type that doesn't exist in the registry
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> registry.forVersion(MINECRAFT_1_12).getPacketId(new StatusPingPacket(0L)));
|
||||
}
|
||||
|
||||
// ==================== Edge Cases and Boundaries ====================
|
||||
|
||||
@Test
|
||||
void shouldNotFailWhenRegisterLatestProtocolVersion() {
|
||||
assertDoesNotThrow(() -> MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_8, MINECRAFT_1_14_4, 0x00),
|
||||
VersionRange.of(getLast(ProtocolVersion.SUPPORTED_VERSIONS), 0x01))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
void versionBoundaryTransition() {
|
||||
// Test that version boundaries are handled correctly
|
||||
MultiVersionPacketRegistry registry = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_12, 0x00),
|
||||
VersionRange.of(MINECRAFT_1_13, MAXIMUM_VERSION, 0x01))
|
||||
.build();
|
||||
|
||||
// 1.12 should have ID 0x00
|
||||
assertEquals(0x00, registry.forVersion(MINECRAFT_1_12).getPacketId(new HandshakePacket()));
|
||||
// 1.13 should have ID 0x01
|
||||
assertEquals(0x01, registry.forVersion(MINECRAFT_1_13).getPacketId(new HandshakePacket()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void multiplePacketsInSingleRegistry() {
|
||||
// Test registry with multiple packet types
|
||||
MultiVersionPacketRegistry registry = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_12, 0x00))
|
||||
.register(StatusPingPacket.class, new StatusPingPacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_12, 0x01))
|
||||
.build();
|
||||
|
||||
assertEquals(0x00, registry.forVersion(MINECRAFT_1_12).getPacketId(new HandshakePacket()));
|
||||
assertEquals(0x01, registry.forVersion(MINECRAFT_1_12).getPacketId(new StatusPingPacket(0L)));
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_12).getCodec(0x00));
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_12).getCodec(0x01));
|
||||
}
|
||||
|
||||
// ==================== Encode-Only Tests ====================
|
||||
|
||||
@Test
|
||||
void encodeOnlyPacketsCanBeEncoded() {
|
||||
// Encode-only packets should be decodable by class but not by ID
|
||||
MultiVersionPacketRegistry registry = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_12, 0x00))
|
||||
.build();
|
||||
|
||||
// Should be able to get codec by class
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_12).getCodec(HandshakePacket.class));
|
||||
// Should NOT be able to get codec by ID
|
||||
assertNull(registry.forVersion(MINECRAFT_1_12).getCodec(0x00));
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeOnlyPacketMultipleVersions() {
|
||||
MultiVersionPacketRegistry registry = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_8, MINECRAFT_1_12, 0x00),
|
||||
VersionRange.of(MINECRAFT_1_13, 0x01))
|
||||
.build();
|
||||
|
||||
// 1.8-1.12 should be encode-only (no decode by ID)
|
||||
assertNull(registry.forVersion(MINECRAFT_1_12).getCodec(0x00));
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_12).getCodec(HandshakePacket.class));
|
||||
|
||||
// 1.13+ should be decodable by ID
|
||||
assertNotNull(registry.forVersion(MINECRAFT_1_13).getCodec(0x01));
|
||||
}
|
||||
|
||||
// ==================== Codec Retrieval Tests ====================
|
||||
|
||||
@Test
|
||||
void getCodecByClassWorks() {
|
||||
MultiVersionPacketRegistry registry = setupRegistry();
|
||||
PacketCodec<HandshakePacket> codec = registry.forVersion(MINECRAFT_1_12)
|
||||
.getCodec(HandshakePacket.class);
|
||||
assertNotNull(codec, "Should be able to retrieve codec by class");
|
||||
assertEquals(HandshakePacket.Codec.class, codec.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCodecByClassReturnsNullForUnregisteredPacket() {
|
||||
MultiVersionPacketRegistry registry = setupRegistry();
|
||||
PacketCodec<StatusPingPacket> codec = registry.forVersion(MINECRAFT_1_12)
|
||||
.getCodec(StatusPingPacket.class);
|
||||
assertNull(codec, "Should return null for unregistered packet class");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCodecByIdReturnsNullForInvalidId() {
|
||||
MultiVersionPacketRegistry registry = setupRegistry();
|
||||
PacketCodec<?> codec = registry.forVersion(MINECRAFT_1_12).getCodec(0xFF);
|
||||
assertNull(codec, "Should return null for invalid packet ID");
|
||||
}
|
||||
|
||||
// ==================== CanDecodePacket Tests ====================
|
||||
|
||||
@Test
|
||||
void canDecodePacketReturnsTrue() {
|
||||
MultiVersionPacketRegistry registry = setupRegistry();
|
||||
assertTrue(registry.forVersion(MINECRAFT_1_12).canDecodePacket(new HandshakePacket()),
|
||||
"Should be able to decode HandshakePacket in 1.12");
|
||||
}
|
||||
|
||||
@Test
|
||||
void canDecodePacketReturnsFalse() {
|
||||
MultiVersionPacketRegistry registry = setupRegistry();
|
||||
assertFalse(registry.forVersion(MINECRAFT_1_12).canDecodePacket(new StatusPingPacket(0L)),
|
||||
"Should not be able to decode StatusPingPacket in 1.12");
|
||||
}
|
||||
|
||||
@Test
|
||||
void encodeOnlyPacketCanBeIdentified() {
|
||||
MultiVersionPacketRegistry registry = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.encodeOnly(MINECRAFT_1_12, 0x00))
|
||||
.build();
|
||||
|
||||
// Encode-only packets can still be identified by class for encoding purposes
|
||||
assertTrue(registry.forVersion(MINECRAFT_1_12).canDecodePacket(new HandshakePacket()),
|
||||
"Encode-only packets can be identified for encoding");
|
||||
// But cannot be decoded by ID (not in packetIdToCodec)
|
||||
assertNull(registry.forVersion(MINECRAFT_1_12).getCodec(0x00),
|
||||
"Encode-only packets cannot be decoded from ID");
|
||||
}
|
||||
|
||||
// ==================== SimplePacketRegistry Tests ====================
|
||||
|
||||
@Test
|
||||
void simplePacketRegistryWorks() {
|
||||
SimplePacketRegistry registry = new SimplePacketRegistry(ProtocolUtils.Direction.CLIENTBOUND);
|
||||
registry.register(0x00, HandshakePacket.class, new HandshakePacket.Codec());
|
||||
|
||||
PacketCodec<?> codec = registry.getCodec(0x00);
|
||||
assertNotNull(codec, "Should retrieve codec by ID");
|
||||
assertEquals(HandshakePacket.Codec.class, codec.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
void simplePacketRegistryCodecByClass() {
|
||||
SimplePacketRegistry registry = new SimplePacketRegistry(ProtocolUtils.Direction.CLIENTBOUND);
|
||||
registry.register(0x00, HandshakePacket.class, new HandshakePacket.Codec());
|
||||
|
||||
PacketCodec<HandshakePacket> codec = registry.getCodec(HandshakePacket.class);
|
||||
assertNotNull(codec, "Should retrieve codec by class");
|
||||
assertEquals(HandshakePacket.Codec.class, codec.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
void simplePacketRegistryGetPacketId() {
|
||||
SimplePacketRegistry registry = new SimplePacketRegistry(ProtocolUtils.Direction.CLIENTBOUND);
|
||||
registry.register(0x42, HandshakePacket.class, new HandshakePacket.Codec());
|
||||
|
||||
int id = registry.getPacketId(new HandshakePacket());
|
||||
assertEquals(0x42, id, "Should return correct packet ID");
|
||||
}
|
||||
|
||||
@Test
|
||||
void simplePacketRegistryFailsOnUnregisteredPacket() {
|
||||
SimplePacketRegistry registry = new SimplePacketRegistry(ProtocolUtils.Direction.CLIENTBOUND);
|
||||
registry.register(0x00, HandshakePacket.class, new HandshakePacket.Codec());
|
||||
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> registry.getPacketId(new StatusPingPacket(0L)),
|
||||
"Should fail when packet is not registered");
|
||||
}
|
||||
|
||||
@Test
|
||||
void simplePacketRegistryCanDecodePacket() {
|
||||
SimplePacketRegistry registry = new SimplePacketRegistry(ProtocolUtils.Direction.CLIENTBOUND);
|
||||
registry.register(0x00, HandshakePacket.class, new HandshakePacket.Codec());
|
||||
|
||||
assertTrue(registry.canDecodePacket(new HandshakePacket()),
|
||||
"Should be able to decode registered packet");
|
||||
assertFalse(registry.canDecodePacket(new StatusPingPacket(0L)),
|
||||
"Should not be able to decode unregistered packet");
|
||||
}
|
||||
|
||||
// ==================== Direction Tests ====================
|
||||
|
||||
@Test
|
||||
void registriesWithDifferentDirections() {
|
||||
// CLIENTBOUND registry
|
||||
MultiVersionPacketRegistry clientbound = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_12, 0x00))
|
||||
.build();
|
||||
|
||||
// SERVERBOUND registry with different ID
|
||||
MultiVersionPacketRegistry serverbound = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.SERVERBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_12, 0x01))
|
||||
.build();
|
||||
|
||||
assertEquals(0x00, clientbound.forVersion(MINECRAFT_1_12).getPacketId(new HandshakePacket()));
|
||||
assertEquals(0x01, serverbound.forVersion(MINECRAFT_1_12).getPacketId(new HandshakePacket()));
|
||||
}
|
||||
|
||||
// ==================== Wide Version Range Tests ====================
|
||||
|
||||
@Test
|
||||
void wideVersionRangeSpanningManyVersions() {
|
||||
// Register packet across many versions with same ID
|
||||
MultiVersionPacketRegistry registry = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_8, MAXIMUM_VERSION, 0x00))
|
||||
.build();
|
||||
|
||||
// Should work for all supported versions in range
|
||||
assertEquals(0x00, registry.forVersion(MINECRAFT_1_8).getPacketId(new HandshakePacket()));
|
||||
assertEquals(0x00, registry.forVersion(MINECRAFT_1_12).getPacketId(new HandshakePacket()));
|
||||
assertEquals(0x00, registry.forVersion(MINECRAFT_1_16_2).getPacketId(new HandshakePacket()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullEndVersionRangeHandling() {
|
||||
// Test with null end version (should extend to MAXIMUM_VERSION)
|
||||
MultiVersionPacketRegistry registry = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||
VersionRange.of(MINECRAFT_1_15, 0x00))
|
||||
.build();
|
||||
|
||||
assertEquals(0x00, registry.forVersion(MINECRAFT_1_15).getPacketId(new HandshakePacket()));
|
||||
assertEquals(0x00, registry.forVersion(MINECRAFT_1_16_2).getPacketId(new HandshakePacket()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user