diff --git a/src/main/java/com/github/steveice10/mc/protocol/ClientListener.java b/src/main/java/com/github/steveice10/mc/protocol/ClientListener.java index 94c5ea29..48b85d8f 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/ClientListener.java +++ b/src/main/java/com/github/steveice10/mc/protocol/ClientListener.java @@ -86,7 +86,7 @@ public class ClientListener extends SessionAdapter { } else if (packet instanceof ClientboundGameProfilePacket) { protocol.setState(ProtocolState.GAME); } else if (packet instanceof ClientboundLoginDisconnectPacket) { - session.disconnect(((ClientboundLoginDisconnectPacket) packet).getReason().toString()); + session.disconnect(((ClientboundLoginDisconnectPacket) packet).getReason()); } else if (packet instanceof ClientboundLoginCompressionPacket) { session.setCompressionThreshold(((ClientboundLoginCompressionPacket) packet).getThreshold(), false); } @@ -112,7 +112,7 @@ public class ClientListener extends SessionAdapter { if (packet instanceof ClientboundKeepAlivePacket && session.getFlag(MinecraftConstants.AUTOMATIC_KEEP_ALIVE_MANAGEMENT, true)) { session.send(new ServerboundKeepAlivePacket(((ClientboundKeepAlivePacket) packet).getPingId())); } else if (packet instanceof ClientboundDisconnectPacket) { - session.disconnect(((ClientboundDisconnectPacket) packet).getReason().toString()); + session.disconnect(((ClientboundDisconnectPacket) packet).getReason()); } } } diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/ClientboundBundlePacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/ClientboundBundlePacket.java new file mode 100644 index 00000000..7389b000 --- /dev/null +++ b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/ClientboundBundlePacket.java @@ -0,0 +1,20 @@ +package com.github.steveice10.mc.protocol.packet.ingame.clientbound; + +import com.github.steveice10.mc.protocol.codec.MinecraftCodecHelper; +import com.github.steveice10.mc.protocol.codec.MinecraftPacket; +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.io.IOException; +import java.util.List; + +@Data +@AllArgsConstructor +public class ClientboundBundlePacket implements MinecraftPacket { + private final List packets; + + @Override + public void serialize(ByteBuf buf, MinecraftCodecHelper helper) throws IOException { + } +} diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/entity/ClientboundDamageEventPacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/entity/ClientboundDamageEventPacket.java index 82f121dd..d7f80fa8 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/entity/ClientboundDamageEventPacket.java +++ b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/entity/ClientboundDamageEventPacket.java @@ -4,8 +4,12 @@ import com.github.steveice10.mc.protocol.codec.MinecraftCodecHelper; import com.github.steveice10.mc.protocol.codec.MinecraftPacket; import com.nukkitx.math.vector.Vector3d; import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; import org.jetbrains.annotations.Nullable; +@Data +@AllArgsConstructor public class ClientboundDamageEventPacket implements MinecraftPacket { private final int entityId; private final int sourceTypeId; diff --git a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundChunksBiomesPacket.java b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundChunksBiomesPacket.java index f61724b6..eba47102 100644 --- a/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundChunksBiomesPacket.java +++ b/src/main/java/com/github/steveice10/mc/protocol/packet/ingame/clientbound/level/ClientboundChunksBiomesPacket.java @@ -4,10 +4,14 @@ import com.github.steveice10.mc.protocol.codec.MinecraftCodecHelper; import com.github.steveice10.mc.protocol.codec.MinecraftPacket; import com.github.steveice10.mc.protocol.data.game.chunk.ChunkBiomeData; import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; import java.util.ArrayList; import java.util.List; +@Data +@AllArgsConstructor public class ClientboundChunksBiomesPacket implements MinecraftPacket { private final List chunkBiomeData; diff --git a/src/main/java/com/github/steveice10/packetlib/Session.java b/src/main/java/com/github/steveice10/packetlib/Session.java index 1627c455..e1d1163d 100644 --- a/src/main/java/com/github/steveice10/packetlib/Session.java +++ b/src/main/java/com/github/steveice10/packetlib/Session.java @@ -6,6 +6,8 @@ import com.github.steveice10.packetlib.event.session.SessionEvent; import com.github.steveice10.packetlib.event.session.SessionListener; import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.PacketProtocol; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.Nullable; import java.net.SocketAddress; import java.util.List; @@ -246,7 +248,7 @@ public interface Session { * * @param reason Reason for disconnecting. */ - public void disconnect(String reason); + void disconnect(@Nullable String reason); /** * Disconnects the session. @@ -254,5 +256,20 @@ public interface Session { * @param reason Reason for disconnecting. * @param cause Throwable responsible for disconnecting. */ - public void disconnect(String reason, Throwable cause); + void disconnect(@Nullable String reason, Throwable cause); + + /** + * Disconnects the session. + * + * @param reason Reason for disconnecting. + */ + void disconnect(@Nullable Component reason); + + /** + * Disconnects the session. + * + * @param reason Reason for disconnecting. + * @param cause Throwable responsible for disconnecting. + */ + void disconnect(@Nullable Component reason, Throwable cause); } diff --git a/src/main/java/com/github/steveice10/packetlib/event/session/DisconnectedEvent.java b/src/main/java/com/github/steveice10/packetlib/event/session/DisconnectedEvent.java index 463ed042..35aacba9 100644 --- a/src/main/java/com/github/steveice10/packetlib/event/session/DisconnectedEvent.java +++ b/src/main/java/com/github/steveice10/packetlib/event/session/DisconnectedEvent.java @@ -1,24 +1,15 @@ package com.github.steveice10.packetlib.event.session; import com.github.steveice10.packetlib.Session; +import net.kyori.adventure.text.Component; /** * Called when the session is disconnected. */ public class DisconnectedEvent implements SessionEvent { - private Session session; - private String reason; - private Throwable cause; - - /** - * Creates a new DisconnectedEvent instance. - * - * @param session Session being disconnected. - * @param reason Reason for the session to disconnect. - */ - public DisconnectedEvent(Session session, String reason) { - this(session, reason, null); - } + private final Session session; + private final Component reason; + private final Throwable cause; /** * Creates a new DisconnectedEvent instance. @@ -27,7 +18,7 @@ public class DisconnectedEvent implements SessionEvent { * @param reason Reason for the session to disconnect. * @param cause Throwable that caused the disconnect. */ - public DisconnectedEvent(Session session, String reason, Throwable cause) { + public DisconnectedEvent(Session session, Component reason, Throwable cause) { this.session = session; this.reason = reason; this.cause = cause; @@ -47,7 +38,7 @@ public class DisconnectedEvent implements SessionEvent { * * @return The event's reason. */ - public String getReason() { + public Component getReason() { return this.reason; } diff --git a/src/main/java/com/github/steveice10/packetlib/event/session/DisconnectingEvent.java b/src/main/java/com/github/steveice10/packetlib/event/session/DisconnectingEvent.java index 0c9929e4..267959e9 100644 --- a/src/main/java/com/github/steveice10/packetlib/event/session/DisconnectingEvent.java +++ b/src/main/java/com/github/steveice10/packetlib/event/session/DisconnectingEvent.java @@ -1,24 +1,15 @@ package com.github.steveice10.packetlib.event.session; import com.github.steveice10.packetlib.Session; +import net.kyori.adventure.text.Component; /** * Called when the session is about to disconnect. */ public class DisconnectingEvent implements SessionEvent { - private Session session; - private String reason; - private Throwable cause; - - /** - * Creates a new DisconnectingEvent instance. - * - * @param session Session being disconnected. - * @param reason Reason for the session to disconnect. - */ - public DisconnectingEvent(Session session, String reason) { - this(session, reason, null); - } + private final Session session; + private final Component reason; + private final Throwable cause; /** * Creates a new DisconnectingEvent instance. @@ -27,7 +18,7 @@ public class DisconnectingEvent implements SessionEvent { * @param reason Reason for the session to disconnect. * @param cause Throwable that caused the disconnect. */ - public DisconnectingEvent(Session session, String reason, Throwable cause) { + public DisconnectingEvent(Session session, Component reason, Throwable cause) { this.session = session; this.reason = reason; this.cause = cause; @@ -47,7 +38,7 @@ public class DisconnectingEvent implements SessionEvent { * * @return The event's reason. */ - public String getReason() { + public Component getReason() { return this.reason; } diff --git a/src/main/java/com/github/steveice10/packetlib/tcp/TcpBundlerUnpacker.java b/src/main/java/com/github/steveice10/packetlib/tcp/TcpBundlerUnpacker.java new file mode 100644 index 00000000..0a4602b0 --- /dev/null +++ b/src/main/java/com/github/steveice10/packetlib/tcp/TcpBundlerUnpacker.java @@ -0,0 +1,30 @@ +package com.github.steveice10.packetlib.tcp; + +import com.github.steveice10.mc.protocol.codec.MinecraftPacket; +import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundBundlePacket; +import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundDelimiterPacket; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageDecoder; + +import java.util.ArrayList; +import java.util.List; + +public class TcpBundlerUnpacker extends MessageToMessageDecoder { + private List currentPackets; + + @Override + protected void decode(ChannelHandlerContext ctx, MinecraftPacket packet, List out) throws Exception { + if (currentPackets != null) { + if (packet.getClass() == ClientboundDelimiterPacket.class) { + out.add(new ClientboundBundlePacket(currentPackets)); + currentPackets = null; + } else { + currentPackets.add(packet); + } + } else { + if (packet.getClass() == ClientboundDelimiterPacket.class) { + currentPackets = new ArrayList<>(2); + } + } + } +} diff --git a/src/main/java/com/github/steveice10/packetlib/tcp/TcpClientSession.java b/src/main/java/com/github/steveice10/packetlib/tcp/TcpClientSession.java index fee4aa93..37d848a3 100644 --- a/src/main/java/com/github/steveice10/packetlib/tcp/TcpClientSession.java +++ b/src/main/java/com/github/steveice10/packetlib/tcp/TcpClientSession.java @@ -315,5 +315,7 @@ public class TcpClientSession extends TcpSession { DATAGRAM_CHANNEL_CLASS = NioDatagramChannel.class; break; } + + Runtime.getRuntime().addShutdownHook(new Thread(() -> EVENT_LOOP_GROUP.shutdownGracefully())); } } diff --git a/src/main/java/com/github/steveice10/packetlib/tcp/TcpSession.java b/src/main/java/com/github/steveice10/packetlib/tcp/TcpSession.java index 0a9ddf1e..94352489 100644 --- a/src/main/java/com/github/steveice10/packetlib/tcp/TcpSession.java +++ b/src/main/java/com/github/steveice10/packetlib/tcp/TcpSession.java @@ -15,6 +15,7 @@ import io.netty.handler.timeout.ReadTimeoutException; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutException; import io.netty.handler.timeout.WriteTimeoutHandler; +import net.kyori.adventure.text.Component; import javax.annotation.Nullable; import java.net.ConnectException; @@ -258,11 +259,21 @@ public abstract class TcpSession extends SimpleChannelInboundHandler imp @Override public void disconnect(String reason) { + this.disconnect(Component.text(reason)); + } + + @Override + public void disconnect(String reason, Throwable cause) { + this.disconnect(Component.text(reason), cause); + } + + @Override + public void disconnect(Component reason) { this.disconnect(reason, null); } @Override - public void disconnect(final String reason, final Throwable cause) { + public void disconnect(final Component reason, final Throwable cause) { if (this.disconnected) { return; } @@ -273,9 +284,9 @@ public abstract class TcpSession extends SimpleChannelInboundHandler imp this.callEvent(new DisconnectingEvent(this, reason, cause)); this.channel.flush().close().addListener((ChannelFutureListener) future -> callEvent(new DisconnectedEvent(TcpSession.this, - reason != null ? reason : "Connection closed.", cause))); + reason != null ? reason : Component.text("Connection closed."), cause))); } else { - this.callEvent(new DisconnectedEvent(this, reason != null ? reason : "Connection closed.", cause)); + this.callEvent(new DisconnectedEvent(this, reason != null ? reason : Component.text("Connection closed."), cause)); } }