diff --git a/src/main/java/com/github/steveice10/mc/protocol/MinecraftProtocol.java b/src/main/java/com/github/steveice10/mc/protocol/MinecraftProtocol.java index 21498653..1f076c99 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/MinecraftProtocol.java +++ b/src/main/java/com/github/steveice10/mc/protocol/MinecraftProtocol.java @@ -6,6 +6,8 @@ import com.github.steveice10.mc.protocol.codec.MinecraftCodecHelper; import com.github.steveice10.mc.protocol.codec.PacketCodec; import com.github.steveice10.mc.protocol.codec.PacketStateCodec; import com.github.steveice10.mc.protocol.data.ProtocolState; +import com.github.steveice10.opennbt.NBTIO; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.packetlib.Server; import com.github.steveice10.packetlib.Session; import com.github.steveice10.packetlib.codec.PacketCodecHelper; @@ -19,17 +21,31 @@ import io.netty.buffer.ByteBuf; import lombok.Getter; import lombok.NonNull; import lombok.Setter; +import org.jetbrains.annotations.Nullable; +import java.io.DataInput; +import java.io.DataInputStream; import java.io.IOException; +import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.Key; +import java.util.Objects; import java.util.UUID; +import java.util.zip.GZIPInputStream; /** * Implements the Minecraft protocol. */ public class MinecraftProtocol extends PacketProtocol { + /** + * The network codec sent from the server to the client during {@link ProtocolState#CONFIGURATION}. + * Lazily loaded once when {@link #newServerSession(Server, Session)} is invoked, + * if {@link #isUseDefaultListeners()} is true. + */ + @Nullable + private static CompoundTag DEFAULT_NETWORK_CODEC; + /** * The codec used for the Minecraft protocol. */ @@ -156,7 +172,11 @@ public class MinecraftProtocol extends PacketProtocol { this.setState(ProtocolState.HANDSHAKE); if (this.useDefaultListeners) { - session.addListener(new ServerListener()); + if (DEFAULT_NETWORK_CODEC == null) { + DEFAULT_NETWORK_CODEC = loadNetworkCodec(); + } + + session.addListener(new ServerListener(DEFAULT_NETWORK_CODEC)); } } @@ -231,4 +251,13 @@ public class MinecraftProtocol extends PacketProtocol { public PacketDefinition getClientboundDefinition(int id) { return this.stateCodec.getClientboundDefinition(id); } + + public static CompoundTag loadNetworkCodec() { + try (InputStream inputStream = Objects.requireNonNull(MinecraftProtocol.class.getClassLoader().getResourceAsStream("networkCodec.nbt")) ; + DataInputStream stream = new DataInputStream(new GZIPInputStream(inputStream))) { + return (CompoundTag) NBTIO.readTag((DataInput) stream); + } catch (Exception e) { + throw new AssertionError("Unable to load network codec.", e); + } + } } diff --git a/src/main/java/com/github/steveice10/mc/protocol/ServerListener.java b/src/main/java/com/github/steveice10/mc/protocol/ServerListener.java index 0a0d5bcf..9144830d 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/ServerListener.java +++ b/src/main/java/com/github/steveice10/mc/protocol/ServerListener.java @@ -27,7 +27,6 @@ import com.github.steveice10.mc.protocol.packet.status.clientbound.ClientboundPo import com.github.steveice10.mc.protocol.packet.status.clientbound.ClientboundStatusResponsePacket; import com.github.steveice10.mc.protocol.packet.status.serverbound.ServerboundPingRequestPacket; import com.github.steveice10.mc.protocol.packet.status.serverbound.ServerboundStatusRequestPacket; -import com.github.steveice10.opennbt.NBTIO; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.packetlib.Session; import com.github.steveice10.packetlib.event.session.ConnectedEvent; @@ -37,10 +36,6 @@ import com.github.steveice10.packetlib.packet.Packet; import net.kyori.adventure.text.Component; import javax.crypto.SecretKey; -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; @@ -49,7 +44,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Random; import java.util.UUID; -import java.util.zip.GZIPInputStream; /** * Handles initial login and status requests for servers. @@ -71,13 +65,16 @@ public class ServerListener extends SessionAdapter { } } + private final CompoundTag networkCodec; + private final byte[] challenge = new byte[4]; private String username = ""; private long lastPingTime = 0; private int lastPingId = 0; - public ServerListener() { + public ServerListener(CompoundTag networkCodec) { + this.networkCodec = networkCodec; new Random().nextBytes(this.challenge); } @@ -132,7 +129,7 @@ public class ServerListener extends SessionAdapter { new Thread(new UserAuthTask(session, key)).start(); } else if (packet instanceof ServerboundLoginAcknowledgedPacket) { ((MinecraftProtocol) session.getPacketProtocol()).setState(ProtocolState.CONFIGURATION); - session.send(new ClientboundRegistryDataPacket(loadNetworkCodec())); + session.send(new ClientboundRegistryDataPacket(networkCodec)); session.send(new ClientboundFinishConfigurationPacket()); } } else if (protocol.getState() == ProtocolState.STATUS) { @@ -254,14 +251,4 @@ public class ServerListener extends SessionAdapter { } } } - - public static CompoundTag loadNetworkCodec() { - try (InputStream inputStream = ServerListener.class.getClassLoader().getResourceAsStream("networkCodec.nbt"); - DataInputStream stream = new DataInputStream(new GZIPInputStream(inputStream))) { - return (CompoundTag) NBTIO.readTag((DataInput) stream); - } catch (IOException e) { - e.printStackTrace(); - throw new AssertionError("Unable to load network codec."); - } - } }