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.google.common.base.Preconditions;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolStates;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
|
import com.velocitypowered.proxy.protocol.registry.PacketRegistry;
|
||||||
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
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.");
|
+ "information, launch Velocity with -Dvelocity.packet-decode-logging=true to see more.");
|
||||||
|
|
||||||
private final ProtocolUtils.Direction direction;
|
private final ProtocolUtils.Direction direction;
|
||||||
|
private ProtocolVersion version;
|
||||||
private StateRegistry state;
|
private StateRegistry state;
|
||||||
private StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
private PacketRegistry registry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@code MinecraftDecoder} decoding packets from the specified {@code direction}.
|
* 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) {
|
public MinecraftDecoder(ProtocolUtils.Direction direction) {
|
||||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||||
this.registry = StateRegistry.HANDSHAKE.getProtocolRegistry(
|
this.version = ProtocolVersion.MINIMUM_VERSION;
|
||||||
direction, ProtocolVersion.MINIMUM_VERSION);
|
this.registry = ProtocolStates.handshake(direction).forVersion(ProtocolVersion.MINIMUM_VERSION);
|
||||||
this.state = StateRegistry.HANDSHAKE;
|
this.state = StateRegistry.HANDSHAKE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,11 +85,13 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
MinecraftPacket packet;
|
MinecraftPacket packet;
|
||||||
try {
|
try {
|
||||||
packet = codec.decode(buf, direction, registry.version);
|
packet = codec.decode(buf, direction, this.version);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw handleDecodeFailure(e, codec, packetId);
|
throw handleDecodeFailure(e, codec, packetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.out.println(packet);
|
||||||
|
|
||||||
if (buf.isReadable()) {
|
if (buf.isReadable()) {
|
||||||
throw handleOverflow(packet, buf.readerIndex(), buf.writerIndex());
|
throw handleOverflow(packet, buf.readerIndex(), buf.writerIndex());
|
||||||
}
|
}
|
||||||
@@ -100,8 +105,8 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
|||||||
private void doLengthSanityChecks(ByteBuf buf,
|
private void doLengthSanityChecks(ByteBuf buf,
|
||||||
com.velocitypowered.proxy.protocol.PacketCodec<? extends MinecraftPacket> codec)
|
com.velocitypowered.proxy.protocol.PacketCodec<? extends MinecraftPacket> codec)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
int expectedMinLen = codec.decodeExpectedMinLength(buf, direction, registry.version);
|
int expectedMinLen = codec.decodeExpectedMinLength(buf, direction, this.version);
|
||||||
int expectedMaxLen = codec.decodeExpectedMaxLength(buf, direction, registry.version);
|
int expectedMaxLen = codec.decodeExpectedMaxLength(buf, direction, this.version);
|
||||||
if (expectedMaxLen != -1 && buf.readableBytes() > expectedMaxLen) {
|
if (expectedMaxLen != -1 && buf.readableBytes() > expectedMaxLen) {
|
||||||
throw handleOverflow(codec, expectedMaxLen, buf.readableBytes());
|
throw handleOverflow(codec, expectedMaxLen, buf.readableBytes());
|
||||||
}
|
}
|
||||||
@@ -153,17 +158,18 @@ public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getExtraConnectionDetail(int packetId) {
|
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);
|
+ " ID 0x" + Integer.toHexString(packetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProtocolVersion(ProtocolVersion protocolVersion) {
|
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) {
|
public void setState(StateRegistry state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.setProtocolVersion(registry.version);
|
this.registry = ProtocolStates.lookup(this.state, this.direction).forVersion(this.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProtocolUtils.Direction getDirection() {
|
public ProtocolUtils.Direction getDirection() {
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ import com.google.common.base.Preconditions;
|
|||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
import com.velocitypowered.proxy.protocol.PacketCodec;
|
import com.velocitypowered.proxy.protocol.PacketCodec;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolStates;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
|
import com.velocitypowered.proxy.protocol.registry.PacketRegistry;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.MessageToByteEncoder;
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
@@ -33,8 +35,9 @@ import io.netty.handler.codec.MessageToByteEncoder;
|
|||||||
public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
||||||
|
|
||||||
private final ProtocolUtils.Direction direction;
|
private final ProtocolUtils.Direction direction;
|
||||||
|
private ProtocolVersion version;
|
||||||
private StateRegistry state;
|
private StateRegistry state;
|
||||||
private StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
private PacketRegistry registry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@code MinecraftEncoder} encoding packets for the specified {@code direction}.
|
* 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) {
|
public MinecraftEncoder(ProtocolUtils.Direction direction) {
|
||||||
this.direction = Preconditions.checkNotNull(direction, "direction");
|
this.direction = Preconditions.checkNotNull(direction, "direction");
|
||||||
this.registry = StateRegistry.HANDSHAKE.getProtocolRegistry(
|
this.version = ProtocolVersion.MINIMUM_VERSION;
|
||||||
direction, ProtocolVersion.MINIMUM_VERSION);
|
this.registry = ProtocolStates.handshake(direction).forVersion(ProtocolVersion.MINIMUM_VERSION);
|
||||||
this.state = StateRegistry.HANDSHAKE;
|
this.state = StateRegistry.HANDSHAKE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,13 +55,14 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected void encode(ChannelHandlerContext ctx, MinecraftPacket msg, ByteBuf out) {
|
protected void encode(ChannelHandlerContext ctx, MinecraftPacket msg, ByteBuf out) {
|
||||||
PacketCodec<MinecraftPacket> codec = (PacketCodec<MinecraftPacket>) this.registry.getCodec(msg.getClass());
|
PacketCodec<MinecraftPacket> codec = (PacketCodec<MinecraftPacket>) this.registry.getCodec(msg.getClass());
|
||||||
|
System.out.println(msg);
|
||||||
if (codec == null) {
|
if (codec == null) {
|
||||||
throw new IllegalArgumentException("No codec found for packet: " + msg.getClass());
|
throw new IllegalArgumentException("No codec found for packet: " + msg.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
int packetId = this.registry.getPacketId(msg);
|
int packetId = this.registry.getPacketId(msg);
|
||||||
ProtocolUtils.writeVarInt(out, packetId);
|
ProtocolUtils.writeVarInt(out, packetId);
|
||||||
codec.encode(msg, out, direction, registry.version);
|
codec.encode(msg, out, direction, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -71,7 +75,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
|||||||
|
|
||||||
int hint = -1;
|
int hint = -1;
|
||||||
if (codec != null) {
|
if (codec != null) {
|
||||||
hint = codec.encodeSizeHint(msg, direction, registry.version);
|
hint = codec.encodeSizeHint(msg, direction, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hint < 0) {
|
if (hint < 0) {
|
||||||
@@ -84,12 +88,13 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setProtocolVersion(final ProtocolVersion protocolVersion) {
|
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) {
|
public void setState(StateRegistry state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.setProtocolVersion(registry.version);
|
this.registry = ProtocolStates.lookup(state, this.direction).forVersion(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProtocolUtils.Direction getDirection() {
|
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.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.protocol.PacketCodec;
|
import com.velocitypowered.proxy.protocol.PacketCodec;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolStates;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
|
import com.velocitypowered.proxy.protocol.registry.PacketRegistry;
|
||||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||||
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
@@ -50,7 +52,7 @@ public class MinecraftVarintFrameDecoder extends ByteToMessageDecoder {
|
|||||||
new QuietDecoderException("Unknown packet");
|
new QuietDecoderException("Unknown packet");
|
||||||
|
|
||||||
private final ProtocolUtils.Direction direction;
|
private final ProtocolUtils.Direction direction;
|
||||||
private final StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
private final PacketRegistry registry;
|
||||||
private StateRegistry state;
|
private StateRegistry state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,8 +62,7 @@ public class MinecraftVarintFrameDecoder extends ByteToMessageDecoder {
|
|||||||
*/
|
*/
|
||||||
public MinecraftVarintFrameDecoder(ProtocolUtils.Direction direction) {
|
public MinecraftVarintFrameDecoder(ProtocolUtils.Direction direction) {
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
this.registry = StateRegistry.HANDSHAKE.getProtocolRegistry(
|
this.registry = ProtocolStates.handshake(direction).forVersion(ProtocolVersion.MINIMUM_VERSION);
|
||||||
direction, ProtocolVersion.MINIMUM_VERSION);
|
|
||||||
this.state = StateRegistry.HANDSHAKE;
|
this.state = StateRegistry.HANDSHAKE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,9 +111,6 @@ public class MinecraftVarintFrameDecoder extends ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateServerboundHandshakePacket(ByteBuf in, int length) throws Exception {
|
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 index = in.readerIndex();
|
||||||
final int packetId = readRawVarInt21(in);
|
final int packetId = readRawVarInt21(in);
|
||||||
// Index hasn't changed, we've read nothing
|
// 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
|
// 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
|
// the packet if needed, so, we'll take advantage of the existing methods
|
||||||
int expectedMinLen = codec.decodeExpectedMinLength(in, direction, registry.version);
|
int expectedMinLen = codec.decodeExpectedMinLength(in, direction, ProtocolVersion.MINIMUM_VERSION);
|
||||||
int expectedMaxLen = codec.decodeExpectedMaxLength(in, direction, registry.version);
|
int expectedMaxLen = codec.decodeExpectedMaxLength(in, direction, ProtocolVersion.MINIMUM_VERSION);
|
||||||
if (expectedMaxLen != -1 && payloadLength > expectedMaxLen) {
|
if (expectedMaxLen != -1 && payloadLength > expectedMaxLen) {
|
||||||
throw handleOverflow(expectedMaxLen, in.readableBytes());
|
throw handleOverflow(expectedMaxLen, in.readableBytes());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ package com.velocitypowered.proxy.protocol.netty;
|
|||||||
|
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolStates;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
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.ChannelDuplexHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
@@ -41,7 +42,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
*/
|
*/
|
||||||
public class PlayPacketQueueInboundHandler extends ChannelDuplexHandler {
|
public class PlayPacketQueueInboundHandler extends ChannelDuplexHandler {
|
||||||
|
|
||||||
private final StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
private final PacketRegistry registry;
|
||||||
private final Queue<Object> queue = new ArrayDeque<>();
|
private final Queue<Object> queue = new ArrayDeque<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +51,7 @@ public class PlayPacketQueueInboundHandler extends ChannelDuplexHandler {
|
|||||||
* @param version the protocol version
|
* @param version the protocol version
|
||||||
*/
|
*/
|
||||||
public PlayPacketQueueInboundHandler(ProtocolVersion version, ProtocolUtils.Direction direction) {
|
public PlayPacketQueueInboundHandler(ProtocolVersion version, ProtocolUtils.Direction direction) {
|
||||||
this.registry = StateRegistry.CONFIG.getProtocolRegistry(direction, version);
|
this.registry = ProtocolStates.configuration(direction).forVersion(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,7 +59,7 @@ public class PlayPacketQueueInboundHandler extends ChannelDuplexHandler {
|
|||||||
if (msg instanceof final MinecraftPacket packet) {
|
if (msg instanceof final MinecraftPacket packet) {
|
||||||
// If the packet exists in the CONFIG state, we want to always
|
// If the packet exists in the CONFIG state, we want to always
|
||||||
// ensure that it gets handled by the current handler
|
// ensure that it gets handled by the current handler
|
||||||
if (this.registry.containsPacket(packet)) {
|
if (this.registry.canDecodePacket(packet)) {
|
||||||
ctx.fireChannelRead(msg);
|
ctx.fireChannelRead(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ package com.velocitypowered.proxy.protocol.netty;
|
|||||||
|
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolStates;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
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.ChannelDuplexHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
@@ -42,7 +43,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
*/
|
*/
|
||||||
public class PlayPacketQueueOutboundHandler extends ChannelDuplexHandler {
|
public class PlayPacketQueueOutboundHandler extends ChannelDuplexHandler {
|
||||||
|
|
||||||
private final StateRegistry.PacketRegistry.ProtocolRegistry registry;
|
private final PacketRegistry registry;
|
||||||
private final Queue<MinecraftPacket> queue = new ArrayDeque<>();
|
private final Queue<MinecraftPacket> queue = new ArrayDeque<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,7 +52,7 @@ public class PlayPacketQueueOutboundHandler extends ChannelDuplexHandler {
|
|||||||
* @param version the protocol version
|
* @param version the protocol version
|
||||||
*/
|
*/
|
||||||
public PlayPacketQueueOutboundHandler(ProtocolVersion version, ProtocolUtils.Direction direction) {
|
public PlayPacketQueueOutboundHandler(ProtocolVersion version, ProtocolUtils.Direction direction) {
|
||||||
this.registry = StateRegistry.CONFIG.getProtocolRegistry(direction, version);
|
this.registry = ProtocolStates.configuration(direction).forVersion(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -63,7 +64,7 @@ public class PlayPacketQueueOutboundHandler extends ChannelDuplexHandler {
|
|||||||
|
|
||||||
// If the packet exists in the CONFIG state, we want to always
|
// If the packet exists in the CONFIG state, we want to always
|
||||||
// ensure that it gets sent out to the client
|
// ensure that it gets sent out to the client
|
||||||
if (this.registry.containsPacket(packet)) {
|
if (this.registry.canDecodePacket(packet)) {
|
||||||
ctx.write(msg, promise);
|
ctx.write(msg, promise);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ public final class AvailableCommandsPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<AvailableCommandsPacket> {
|
public static class Codec implements PacketCodec<AvailableCommandsPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AvailableCommandsPacket decode(ByteBuf buf, Direction direction,
|
public AvailableCommandsPacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
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 class Codec implements PacketCodec<BossBarPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BossBarPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public BossBarPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -36,10 +36,12 @@ public final class BundleDelimiterPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<BundleDelimiterPacket> {
|
public static class Codec implements PacketCodec<BundleDelimiterPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BundleDelimiterPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public BundleDelimiterPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
return INSTANCE;
|
return BundleDelimiterPacket.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ public final class ClientSettingsPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ClientSettingsPacket> {
|
public static class Codec implements PacketCodec<ClientSettingsPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientSettingsPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public ClientSettingsPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ public record ClientboundCookieRequestPacket(Key key) implements MinecraftPacket
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ClientboundCookieRequestPacket> {
|
public static class Codec implements PacketCodec<ClientboundCookieRequestPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientboundCookieRequestPacket decode(ByteBuf buf, Direction direction,
|
public ClientboundCookieRequestPacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ public record ClientboundSoundEntityPacket(Sound sound, @Nullable Float fixedRan
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ClientboundSoundEntityPacket> {
|
public static class Codec implements PacketCodec<ClientboundSoundEntityPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientboundSoundEntityPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public ClientboundSoundEntityPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ public record ClientboundStopSoundPacket(@Nullable Sound.Source source,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ClientboundStopSoundPacket> {
|
public static class Codec implements PacketCodec<ClientboundStopSoundPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientboundStopSoundPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public ClientboundStopSoundPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ public record ClientboundStoreCookiePacket(Key key, byte[] payload) implements M
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ClientboundStoreCookiePacket> {
|
public static class Codec implements PacketCodec<ClientboundStoreCookiePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientboundStoreCookiePacket decode(ByteBuf buf, Direction direction,
|
public ClientboundStoreCookiePacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -37,10 +37,12 @@ public final class DialogClearPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<DialogClearPacket> {
|
public static class Codec implements PacketCodec<DialogClearPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DialogClearPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public DialogClearPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
return INSTANCE;
|
return DialogClearPacket.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ public final class EncryptionRequestPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<EncryptionRequestPacket> {
|
public static class Codec implements PacketCodec<EncryptionRequestPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EncryptionRequestPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public EncryptionRequestPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ public final class EncryptionResponsePacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<EncryptionResponsePacket> {
|
public static class Codec implements PacketCodec<EncryptionResponsePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EncryptionResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public EncryptionResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -104,6 +104,8 @@ public final class HandshakePacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<HandshakePacket> {
|
public static class Codec implements PacketCodec<HandshakePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HandshakePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public HandshakePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion ignored) {
|
ProtocolVersion ignored) {
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ public record HeaderAndFooterPacket(ComponentHolder header,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<HeaderAndFooterPacket> {
|
public static class Codec implements PacketCodec<HeaderAndFooterPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HeaderAndFooterPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public HeaderAndFooterPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -196,6 +196,8 @@ public final class JoinGamePacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<JoinGamePacket> {
|
public static class Codec implements PacketCodec<JoinGamePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JoinGamePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public JoinGamePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ public record KeepAlivePacket(long randomId) implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<KeepAlivePacket> {
|
public static class Codec implements PacketCodec<KeepAlivePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeepAlivePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public KeepAlivePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ public final class LegacyHandshakePacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<LegacyHandshakePacket> {
|
public static class Codec implements PacketCodec<LegacyHandshakePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LegacyHandshakePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public LegacyHandshakePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ public final class LegacyPingPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<LegacyPingPacket> {
|
public static class Codec implements PacketCodec<LegacyPingPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LegacyPingPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public LegacyPingPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ public final class LegacyPlayerListItemPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<LegacyPlayerListItemPacket> {
|
public static class Codec implements PacketCodec<LegacyPlayerListItemPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LegacyPlayerListItemPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public LegacyPlayerListItemPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -37,10 +37,12 @@ public final class LoginAcknowledgedPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<LoginAcknowledgedPacket> {
|
public static class Codec implements PacketCodec<LoginAcknowledgedPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoginAcknowledgedPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public LoginAcknowledgedPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
return INSTANCE;
|
return LoginAcknowledgedPacket.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ public final class LoginPluginMessagePacket extends DefaultByteBufHolder impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<LoginPluginMessagePacket> {
|
public static class Codec implements PacketCodec<LoginPluginMessagePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoginPluginMessagePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public LoginPluginMessagePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ public final class LoginPluginResponsePacket extends DefaultByteBufHolder
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<LoginPluginResponsePacket> {
|
public static class Codec implements PacketCodec<LoginPluginResponsePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoginPluginResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public LoginPluginResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ public record PingIdentifyPacket(int id) implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<PingIdentifyPacket> {
|
public static class Codec implements PacketCodec<PingIdentifyPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PingIdentifyPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public PingIdentifyPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ public final class PluginMessagePacket extends DefaultByteBufHolder implements M
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<PluginMessagePacket> {
|
public static class Codec implements PacketCodec<PluginMessagePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PluginMessagePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public PluginMessagePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public record RemovePlayerInfoPacket(Collection<UUID> profilesToRemove) implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<RemovePlayerInfoPacket> {
|
public static class Codec implements PacketCodec<RemovePlayerInfoPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RemovePlayerInfoPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public RemovePlayerInfoPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public record RemoveResourcePackPacket(@Nullable UUID id) implements MinecraftPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<RemoveResourcePackPacket> {
|
public static class Codec implements PacketCodec<RemoveResourcePackPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RemoveResourcePackPacket decode(ByteBuf buf, Direction direction,
|
public RemoveResourcePackPacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ public final class ResourcePackRequestPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ResourcePackRequestPacket> {
|
public static class Codec implements PacketCodec<ResourcePackRequestPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourcePackRequestPacket decode(ByteBuf buf, Direction direction,
|
public ResourcePackRequestPacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ public record ResourcePackResponsePacket(UUID id, String hash,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ResourcePackResponsePacket> {
|
public static class Codec implements PacketCodec<ResourcePackResponsePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourcePackResponsePacket decode(ByteBuf buf, Direction direction,
|
public ResourcePackResponsePacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -151,6 +151,8 @@ public final class RespawnPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<RespawnPacket> {
|
public static class Codec implements PacketCodec<RespawnPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RespawnPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public RespawnPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ public final class ServerDataPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ServerDataPacket> {
|
public static class Codec implements PacketCodec<ServerDataPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerDataPacket decode(ByteBuf buf, Direction direction,
|
public ServerDataPacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ public final class ServerLoginPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ServerLoginPacket> {
|
public static class Codec implements PacketCodec<ServerLoginPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerLoginPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public ServerLoginPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ public final class ServerLoginSuccessPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ServerLoginSuccessPacket> {
|
public static class Codec implements PacketCodec<ServerLoginSuccessPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerLoginSuccessPacket decode(ByteBuf buf, Direction direction,
|
public ServerLoginSuccessPacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ public record ServerboundCookieResponsePacket(Key key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ServerboundCookieResponsePacket> {
|
public static class Codec implements PacketCodec<ServerboundCookieResponsePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerboundCookieResponsePacket decode(ByteBuf buf, Direction direction,
|
public ServerboundCookieResponsePacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ public class ServerboundCustomClickActionPacket extends DefaultByteBufHolder
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ServerboundCustomClickActionPacket> {
|
public static class Codec implements PacketCodec<ServerboundCustomClickActionPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerboundCustomClickActionPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public ServerboundCustomClickActionPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ public record SetCompressionPacket(int threshold) implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<SetCompressionPacket> {
|
public static class Codec implements PacketCodec<SetCompressionPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SetCompressionPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public SetCompressionPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public record StatusPingPacket(long randomId) implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<StatusPingPacket> {
|
public static class Codec implements PacketCodec<StatusPingPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatusPingPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public StatusPingPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -43,10 +43,12 @@ public final class StatusRequestPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<StatusRequestPacket> {
|
public static class Codec implements PacketCodec<StatusRequestPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatusRequestPacket decode(ByteBuf buf, Direction direction,
|
public StatusRequestPacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
return INSTANCE;
|
return StatusRequestPacket.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ public final class StatusResponsePacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<StatusResponsePacket> {
|
public static class Codec implements PacketCodec<StatusResponsePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatusResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public StatusResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ public final class TabCompleteRequestPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<TabCompleteRequestPacket> {
|
public static class Codec implements PacketCodec<TabCompleteRequestPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TabCompleteRequestPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public TabCompleteRequestPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ public final class TabCompleteResponsePacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<TabCompleteResponsePacket> {
|
public static class Codec implements PacketCodec<TabCompleteResponsePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TabCompleteResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public TabCompleteResponsePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ public record TransferPacket(String host, int port) implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<TransferPacket> {
|
public static class Codec implements PacketCodec<TransferPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TransferPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public TransferPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ public final class UpsertPlayerInfoPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<UpsertPlayerInfoPacket> {
|
public static class Codec implements PacketCodec<UpsertPlayerInfoPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UpsertPlayerInfoPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public UpsertPlayerInfoPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public record ChatAcknowledgementPacket(int offset) implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ChatAcknowledgementPacket> {
|
public static class Codec implements PacketCodec<ChatAcknowledgementPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChatAcknowledgementPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public ChatAcknowledgementPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ public final class PlayerChatCompletionPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<PlayerChatCompletionPacket> {
|
public static class Codec implements PacketCodec<PlayerChatCompletionPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlayerChatCompletionPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public PlayerChatCompletionPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ public final class SystemChatPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<SystemChatPacket> {
|
public static class Codec implements PacketCodec<SystemChatPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SystemChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public SystemChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ public final class KeyedPlayerChatPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<KeyedPlayerChatPacket> {
|
public static class Codec implements PacketCodec<KeyedPlayerChatPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyedPlayerChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public KeyedPlayerChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ public final class KeyedPlayerCommandPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<KeyedPlayerCommandPacket> {
|
public static class Codec implements PacketCodec<KeyedPlayerCommandPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyedPlayerCommandPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public KeyedPlayerCommandPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
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 class Codec implements PacketCodec<LegacyChatPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LegacyChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public LegacyChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ public class SessionPlayerChatPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<SessionPlayerChatPacket> {
|
public static class Codec implements PacketCodec<SessionPlayerChatPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionPlayerChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public SessionPlayerChatPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ public class SessionPlayerCommandPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<SessionPlayerCommandPacket> {
|
public static class Codec implements PacketCodec<SessionPlayerCommandPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionPlayerCommandPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public SessionPlayerCommandPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ public final class UnsignedPlayerCommandPacket extends SessionPlayerCommandPacke
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<UnsignedPlayerCommandPacket> {
|
public static class Codec implements PacketCodec<UnsignedPlayerCommandPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UnsignedPlayerCommandPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public UnsignedPlayerCommandPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ public record ActiveFeaturesPacket(Key[] activeFeatures) implements MinecraftPac
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ActiveFeaturesPacket> {
|
public static class Codec implements PacketCodec<ActiveFeaturesPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActiveFeaturesPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public ActiveFeaturesPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -28,16 +28,14 @@ import java.util.Map;
|
|||||||
|
|
||||||
public record ClientboundCustomReportDetailsPacket(Map<String, String> details) implements MinecraftPacket {
|
public record ClientboundCustomReportDetailsPacket(Map<String, String> details) implements MinecraftPacket {
|
||||||
|
|
||||||
public ClientboundCustomReportDetailsPacket() {
|
|
||||||
this(Map.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(MinecraftSessionHandler handler) {
|
public boolean handle(MinecraftSessionHandler handler) {
|
||||||
return handler.handle(this);
|
return handler.handle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ClientboundCustomReportDetailsPacket> {
|
public static class Codec implements PacketCodec<ClientboundCustomReportDetailsPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientboundCustomReportDetailsPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public ClientboundCustomReportDetailsPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ public record ClientboundServerLinksPacket(List<ServerLink> serverLinks) impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<ClientboundServerLinksPacket> {
|
public static class Codec implements PacketCodec<ClientboundServerLinksPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientboundServerLinksPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public ClientboundServerLinksPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion version) {
|
ProtocolVersion version) {
|
||||||
|
|||||||
@@ -37,10 +37,12 @@ public final class CodeOfConductAcceptPacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<CodeOfConductAcceptPacket> {
|
public static class Codec implements PacketCodec<CodeOfConductAcceptPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CodeOfConductAcceptPacket decode(ByteBuf buf, Direction direction,
|
public CodeOfConductAcceptPacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
return INSTANCE;
|
return CodeOfConductAcceptPacket.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ public class CodeOfConductPacket extends DefaultByteBufHolder implements Minecra
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<CodeOfConductPacket> {
|
public static class Codec implements PacketCodec<CodeOfConductPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CodeOfConductPacket decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
public CodeOfConductPacket decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
||||||
return new CodeOfConductPacket(buf.readRetainedSlice(buf.readableBytes()));
|
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 class Codec implements PacketCodec<FinishedUpdatePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FinishedUpdatePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public FinishedUpdatePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
return INSTANCE;
|
return FinishedUpdatePacket.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ public record KnownPacksPacket(KnownPack[] packs) implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<KnownPacksPacket> {
|
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 int MAX_LENGTH_PACKS = Integer.getInteger("velocity.max-known-packs", 64);
|
||||||
private static final QuietDecoderException TOO_MANY_PACKS =
|
private static final QuietDecoderException TOO_MANY_PACKS =
|
||||||
new QuietDecoderException("too many known 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 class Codec implements PacketCodec<RegistrySyncPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RegistrySyncPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public RegistrySyncPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -36,10 +36,12 @@ public final class StartUpdatePacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<StartUpdatePacket> {
|
public static class Codec implements PacketCodec<StartUpdatePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StartUpdatePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public StartUpdatePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
return INSTANCE;
|
return StartUpdatePacket.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ public final class TagsUpdatePacket implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<TagsUpdatePacket> {
|
public static class Codec implements PacketCodec<TagsUpdatePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TagsUpdatePacket decode(ByteBuf buf, Direction direction,
|
public TagsUpdatePacket decode(ByteBuf buf, Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ public final class LegacyTitlePacket extends GenericTitlePacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<LegacyTitlePacket> {
|
public static class Codec implements PacketCodec<LegacyTitlePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LegacyTitlePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public LegacyTitlePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ public final class TitleActionbarPacket extends GenericTitlePacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<TitleActionbarPacket> {
|
public static class Codec implements PacketCodec<TitleActionbarPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TitleActionbarPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public TitleActionbarPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ public final class TitleClearPacket extends GenericTitlePacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<TitleClearPacket> {
|
public static class Codec implements PacketCodec<TitleClearPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TitleClearPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public TitleClearPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ public final class TitleSubtitlePacket extends GenericTitlePacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<TitleSubtitlePacket> {
|
public static class Codec implements PacketCodec<TitleSubtitlePacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TitleSubtitlePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public TitleSubtitlePacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ public final class TitleTextPacket extends GenericTitlePacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<TitleTextPacket> {
|
public static class Codec implements PacketCodec<TitleTextPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TitleTextPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public TitleTextPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
ProtocolVersion protocolVersion) {
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ public final class TitleTimesPacket extends GenericTitlePacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Codec implements PacketCodec<TitleTimesPacket> {
|
public static class Codec implements PacketCodec<TitleTimesPacket> {
|
||||||
|
public static final Codec INSTANCE = new Codec();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TitleTimesPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
public TitleTimesPacket decode(ByteBuf buf, ProtocolUtils.Direction direction,
|
||||||
ProtocolVersion protocolVersion) {
|
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;
|
package com.velocitypowered.proxy.protocol;
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.getLast;
|
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_11;
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12;
|
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_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_13;
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14;
|
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_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_15;
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
|
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_2;
|
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_2;
|
||||||
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
|
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.assertDoesNotThrow;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
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.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
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.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
||||||
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
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;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
class PacketRegistryTest {
|
class PacketRegistryTest {
|
||||||
|
|
||||||
private StateRegistry.PacketRegistry setupRegistry() {
|
/**
|
||||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
|
* Sets up a multi-version registry with HandshakePacket mapped to different IDs across version
|
||||||
ProtocolUtils.Direction.CLIENTBOUND, StateRegistry.PLAY);
|
* ranges.
|
||||||
registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
*/
|
||||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_8, null, false),
|
private MultiVersionPacketRegistry setupRegistry() {
|
||||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12, null, false),
|
return MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_15, MINECRAFT_1_16, false));
|
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||||
return registry;
|
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
|
@Test
|
||||||
void packetRegistryWorks() {
|
void packetRegistryWorks() {
|
||||||
StateRegistry.PacketRegistry registry = setupRegistry();
|
MultiVersionPacketRegistry registry = setupRegistry();
|
||||||
PacketCodec<?> packet = registry.getProtocolRegistry(MINECRAFT_1_12).getCodec(0);
|
PacketCodec<?> packet = registry.forVersion(MINECRAFT_1_12).getCodec(0);
|
||||||
assertNotNull(packet, "Packet was not found in registry");
|
assertNotNull(packet, "Packet was not found in registry");
|
||||||
assertEquals(HandshakePacket.Codec.class, packet.getClass(), "Registry returned wrong class");
|
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");
|
"Registry did not return the correct packet ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void packetRegistryLinkingWorks() {
|
void packetRegistryLinkingWorks() {
|
||||||
StateRegistry.PacketRegistry registry = setupRegistry();
|
MultiVersionPacketRegistry registry = setupRegistry();
|
||||||
PacketCodec<?> packet = registry.getProtocolRegistry(MINECRAFT_1_12_1).getCodec(0);
|
PacketCodec<?> packet = registry.forVersion(MINECRAFT_1_12_1).getCodec(0);
|
||||||
assertNotNull(packet, "Packet was not found in registry");
|
assertNotNull(packet, "Packet was not found in registry");
|
||||||
assertEquals(HandshakePacket.Codec.class, packet.getClass(), "Registry returned wrong class");
|
assertEquals(HandshakePacket.Codec.class, packet.getClass(), "Registry returned wrong class");
|
||||||
HandshakePacket handshakePacket = new HandshakePacket();
|
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");
|
"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");
|
"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");
|
"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");
|
"Registry should return a null");
|
||||||
assertNull(registry.getProtocolRegistry(MINECRAFT_1_16_2).getCodec(0),
|
// 1.16_2 is >= 1.15, so it should have codec for 0x00 from the last range
|
||||||
"Registry should return null");
|
assertNotNull(registry.forVersion(MINECRAFT_1_16_2).getCodec(0),
|
||||||
}
|
"1.16_2 should have codec for 0x00 from 1.15+ range");
|
||||||
|
|
||||||
@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)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void registrySuppliesCorrectPacketsByProtocol() {
|
void registrySuppliesCorrectPacketsByProtocol() {
|
||||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
|
MultiVersionPacketRegistry registry = MultiVersionPacketRegistry.builder(ProtocolUtils.Direction.CLIENTBOUND)
|
||||||
ProtocolUtils.Direction.CLIENTBOUND, StateRegistry.PLAY);
|
.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
||||||
registry.register(HandshakePacket.class, new HandshakePacket.Codec(),
|
VersionRange.of(MINECRAFT_1_12, MINECRAFT_1_12, 0x00),
|
||||||
new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12, null, false),
|
VersionRange.of(MINECRAFT_1_12_1, MINECRAFT_1_12_2, 0x01),
|
||||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12_1, null, false),
|
VersionRange.of(MINECRAFT_1_13, MINECRAFT_1_14_4, 0x02))
|
||||||
new StateRegistry.PacketMapping(0x02, MINECRAFT_1_13, null, false));
|
.build();
|
||||||
|
assertNotNull(registry.forVersion(MINECRAFT_1_12).getCodec(0x00));
|
||||||
assertEquals(HandshakePacket.Codec.class,
|
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,
|
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,
|
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,
|
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,
|
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