diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitEncodeHandler.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitEncodeHandler.java index 420c4cf06..8a003b1ea 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitEncodeHandler.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitEncodeHandler.java @@ -56,6 +56,7 @@ public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaHand transform(bytebuf); } + @Override public void transform(ByteBuf bytebuf) throws Exception { info.checkOutgoingPacket(); if (!info.shouldTransformPacket()) return; diff --git a/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java b/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java index 1ff17a2bf..dd38bd72b 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java @@ -45,7 +45,7 @@ public class UserConnection { } /** - * Get an object from the storage + * Get an object from the storage. * * @param objectClass The class of the object to get * @param The type of the class you want to get. @@ -57,7 +57,7 @@ public class UserConnection { } /** - * Check if the storage has an object + * Check if the storage has an object. * * @param objectClass The object class to check * @return True if the object is in the storage @@ -67,7 +67,7 @@ public class UserConnection { } /** - * Put an object into the stored objects based on class + * Put an object into the stored objects based on class. * * @param object The object to store. */ @@ -76,7 +76,7 @@ public class UserConnection { } /** - * Clear all the stored objects + * Clear all the stored objects. * Used for bungee when switching servers. */ public void clearStoredObjects() { @@ -84,7 +84,7 @@ public class UserConnection { } /** - * Send a raw packet to the player + * Send a raw packet to the player. * * @param packet The raw packet to send * @param currentThread Should it run in the same thread @@ -99,7 +99,7 @@ public class UserConnection { } /** - * Send a raw packet to the player with returning the future + * Send a raw packet to the player with returning the future. * * @param packet The raw packet to send * @return ChannelFuture of the packet being sent @@ -110,7 +110,7 @@ public class UserConnection { } /** - * Send a raw packet to the player (netty thread) + * Send a raw packet to the player (netty thread). * * @param packet The packet to send */ @@ -119,16 +119,16 @@ public class UserConnection { } /** - * Used for incrementing the number of packets sent to the client + * Used for incrementing the number of packets sent to the client. */ public void incrementSent() { this.sentPackets++; } /** - * Used for incrementing the number of packets received from the client + * Used for incrementing the number of packets received from the client. * - * @return True if the interval has reset + * @return true if the interval has reset and can now be checked for the packets sent */ public boolean incrementReceived() { // handle stats @@ -146,7 +146,14 @@ public class UserConnection { return false; } - public boolean handlePPS() { + /** + * Checks for packet flood with the packets sent in the last second. + * ALWAYS check for {@link #incrementReceived()} before using this method. + * + * @return true if the packet should be cancelled + * @see #incrementReceived() + */ + public boolean exceedsMaxPPS() { ViaVersionConfig conf = Via.getConfig(); // Max PPS Checker if (conf.getMaxPPS() > 0) { @@ -178,28 +185,29 @@ public class UserConnection { } /** - * Disconnect a connection + * Disconnect a connection. * * @param reason The reason to use, not used if player is not active. */ public void disconnect(String reason) { - if (!channel.isOpen()) return; - if (pendingDisconnect) return; + if (!channel.isOpen() || pendingDisconnect) return; + pendingDisconnect = true; - if (get(ProtocolInfo.class).getUuid() != null) { - UUID uuid = get(ProtocolInfo.class).getUuid(); - Via.getPlatform().runSync(() -> { - if (!Via.getPlatform().kickPlayer(uuid, ChatColor.translateAlternateColorCodes('&', reason))) { - channel.close(); // =) - } - }); - } else { - getChannel().close(); // Just disconnect, we don't know what the connection is + UUID uuid = get(ProtocolInfo.class).getUuid(); + if (uuid == null) { + channel.close(); // Just disconnect, we don't know what the connection is + return; } + + Via.getPlatform().runSync(() -> { + if (!Via.getPlatform().kickPlayer(uuid, ChatColor.translateAlternateColorCodes('&', reason))) { + channel.close(); // =) + } + }); } /** - * Sends a raw packet to the server + * Sends a raw packet to the server. * * @param packet Raw packet to be sent * @param currentThread If {@code true} executes immediately, {@code false} submits a task to EventLoop @@ -243,7 +251,7 @@ public class UserConnection { } /** - * Sends a raw packet to the server. It will submit a task to EventLoop + * Sends a raw packet to the server. It will submit a task to EventLoop. * * @param packet Raw packet to be sent */ @@ -251,6 +259,81 @@ public class UserConnection { sendRawPacketToServer(packet, false); } + /** + * Monitors serverbound packets. + * + * @return false if this packet should be cancelled + */ + public boolean checkIncomingPacket() { + // Ignore if pending disconnect + if (pendingDisconnect) return false; + // Increment received + Check PPS + return !incrementReceived() || !exceedsMaxPPS(); + } + + /** + * Monitors clientbound packets. + */ + public void checkOutgoingPacket() { + incrementSent(); + } + + /** + * Checks if packets needs transforming. + * + * @return if packets should be passed through + */ + public boolean shouldTransformPacket() { + return active; + } + + /** + * Transforms the clientbound packet contained in draft ByteBuf. + * + * @param draft ByteBuf with packet id and packet contents + * @param cancelSupplier Function called with original CancelException for generating the Exception used when + * packet is cancelled + * @throws Exception when transforming failed or this packet is cancelled + */ + public void transformOutgoing(ByteBuf draft, Function cancelSupplier) throws Exception { + if (!draft.isReadable()) return; + transform(draft, Direction.OUTGOING, cancelSupplier); + } + + /** + * Transforms the serverbound packet contained in draft ByteBuf. + * + * @param draft ByteBuf with packet id and packet contents + * @param cancelSupplier Function called with original CancelException for generating the Exception used when + * packet is cancelled + * @throws Exception when transforming failed or this packet is cancelled + */ + public void transformIncoming(ByteBuf draft, Function cancelSupplier) throws Exception { + if (!draft.isReadable()) return; + transform(draft, Direction.INCOMING, cancelSupplier); + } + + private void transform(ByteBuf draft, Direction direction, Function cancelSupplier) throws Exception { + int id = Type.VAR_INT.read(draft); + if (id == PacketWrapper.PASSTHROUGH_ID) return; + + PacketWrapper wrapper = new PacketWrapper(id, draft, this); + ProtocolInfo protInfo = get(ProtocolInfo.class); + try { + protInfo.getPipeline().transform(direction, protInfo.getState(), wrapper); + } catch (CancelException ex) { + throw cancelSupplier.apply(ex); + } + + ByteBuf transformed = draft.alloc().buffer(); + try { + wrapper.writeToBuffer(transformed); + draft.clear().writeBytes(transformed); + } finally { + transformed.release(); + } + } + public long getId() { return id; } @@ -345,81 +428,6 @@ public class UserConnection { this.warnings = warnings; } - /** - * Monitors serverbound packets. - * - * @return false if this packet should be cancelled - */ - public boolean checkIncomingPacket() { - // Ignore if pending disconnect - if (pendingDisconnect) return false; - // Increment received + Check PPS - return !incrementReceived() || !handlePPS(); - } - - /** - * Monitors clientbound packets. - */ - public void checkOutgoingPacket() { - incrementSent(); - } - - /** - * Checks if packets needs transforming. - * - * @return if packets should be passed through - */ - public boolean shouldTransformPacket() { - return active; - } - - /** - * Transforms the clientbound packet contained in draft ByteBuf. - * - * @param draft ByteBuf with packet id and packet contents - * @param cancelSupplier Function called with original CancelException for generating the Exception used when - * packet is cancelled - * @throws Exception when transforming failed or this packet is cancelled - */ - public void transformOutgoing(ByteBuf draft, Function cancelSupplier) throws Exception { - if (!draft.isReadable()) return; - transform(draft, Direction.OUTGOING, cancelSupplier); - } - - /** - * Transforms the serverbound packet contained in draft ByteBuf. - * - * @param draft ByteBuf with packet id and packet contents - * @param cancelSupplier Function called with original CancelException for generating the Exception used when - * packet is cancelled - * @throws Exception when transforming failed or this packet is cancelled - */ - public void transformIncoming(ByteBuf draft, Function cancelSupplier) throws Exception { - if (!draft.isReadable()) return; - transform(draft, Direction.INCOMING, cancelSupplier); - } - - private void transform(ByteBuf draft, Direction direction, Function cancelSupplier) throws Exception { - int id = Type.VAR_INT.read(draft); - if (id == PacketWrapper.PASSTHROUGH_ID) return; - - PacketWrapper wrapper = new PacketWrapper(id, draft, this); - ProtocolInfo protInfo = get(ProtocolInfo.class); - try { - protInfo.getPipeline().transform(direction, protInfo.getState(), wrapper); - } catch (CancelException ex) { - throw cancelSupplier.apply(ex); - } - - ByteBuf transformed = draft.alloc().buffer(); - try { - wrapper.writeToBuffer(transformed); - draft.clear().writeBytes(transformed); - } finally { - transformed.release(); - } - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/common/src/main/java/us/myles/ViaVersion/exception/CancelDecoderException.java b/common/src/main/java/us/myles/ViaVersion/exception/CancelDecoderException.java index 145106f6c..024a9fe5b 100644 --- a/common/src/main/java/us/myles/ViaVersion/exception/CancelDecoderException.java +++ b/common/src/main/java/us/myles/ViaVersion/exception/CancelDecoderException.java @@ -4,12 +4,12 @@ import io.netty.handler.codec.DecoderException; import us.myles.ViaVersion.api.Via; /** - * Used for cancelling packets in decode handlers + * Used for cancelling packets in decode handlers. */ public class CancelDecoderException extends DecoderException { public static final CancelDecoderException CACHED = new CancelDecoderException("CACHED") { @Override - public synchronized Throwable fillInStackTrace() { + public Throwable fillInStackTrace() { return this; } }; @@ -31,12 +31,12 @@ public class CancelDecoderException extends DecoderException { } /** - * Returns a cached CancelDecoderException or a new instance when {@link us.myles.ViaVersion.ViaManager}#isDebug() is true + * Returns a cached CancelDecoderException or a new instance when {@link us.myles.ViaVersion.ViaManager#isDebug()} is true. + * * @param cause cause for being used when a new instance is creeated * @return a CancelDecoderException instance */ public static CancelDecoderException generate(Throwable cause) { - if (Via.getManager().isDebug()) return new CancelDecoderException(cause); - return CACHED; + return Via.getManager().isDebug() ? new CancelDecoderException(cause) : CACHED; } } diff --git a/common/src/main/java/us/myles/ViaVersion/exception/CancelEncoderException.java b/common/src/main/java/us/myles/ViaVersion/exception/CancelEncoderException.java index 9e84c0c60..0a5c7354b 100644 --- a/common/src/main/java/us/myles/ViaVersion/exception/CancelEncoderException.java +++ b/common/src/main/java/us/myles/ViaVersion/exception/CancelEncoderException.java @@ -4,12 +4,12 @@ import io.netty.handler.codec.EncoderException; import us.myles.ViaVersion.api.Via; /** - * Used for cancelling packets in encode handlers + * Used for cancelling packets in encode handlers. */ public class CancelEncoderException extends EncoderException { public static final CancelEncoderException CACHED = new CancelEncoderException("CACHED") { @Override - public synchronized Throwable fillInStackTrace() { + public Throwable fillInStackTrace() { return this; } }; @@ -31,12 +31,12 @@ public class CancelEncoderException extends EncoderException { } /** - * Returns a cached CancelEncoderException or a new instance when {@link us.myles.ViaVersion.ViaManager}#isDebug() is true + * Returns a cached CancelEncoderException or a new instance when {@link us.myles.ViaVersion.ViaManager#isDebug()} is true. + * * @param cause cause for being used when a new instance is creeated * @return a CancelEncoderException instance */ public static CancelEncoderException generate(Throwable cause) { - if (Via.getManager().isDebug()) return new CancelEncoderException(cause); - return CACHED; + return Via.getManager().isDebug() ? new CancelEncoderException(cause) : CACHED; } } diff --git a/common/src/main/java/us/myles/ViaVersion/exception/CancelException.java b/common/src/main/java/us/myles/ViaVersion/exception/CancelException.java index ec954478c..2bc5a8c5a 100644 --- a/common/src/main/java/us/myles/ViaVersion/exception/CancelException.java +++ b/common/src/main/java/us/myles/ViaVersion/exception/CancelException.java @@ -3,12 +3,12 @@ package us.myles.ViaVersion.exception; import us.myles.ViaVersion.api.Via; /** - * Used for cancelling packets + * Used for cancelling packets. */ public class CancelException extends Exception { public static final CancelException CACHED = new CancelException("Cached - Enable /viaver debug to not use cached exception") { @Override - public synchronized Throwable fillInStackTrace() { + public Throwable fillInStackTrace() { return this; } }; @@ -33,11 +33,11 @@ public class CancelException extends Exception { } /** - * Returns a cached CancelException or a new instance when {@link us.myles.ViaVersion.ViaManager}#isDebug() is true + * Returns a cached CancelException or a new instance when {@link us.myles.ViaVersion.ViaManager#isDebug()} is true. + * * @return a CancelException instance */ public static CancelException generate() { - if (Via.getManager().isDebug()) return new CancelException(); - return CACHED; + return Via.getManager().isDebug() ? new CancelException() : CACHED; } } diff --git a/common/src/main/java/us/myles/ViaVersion/handlers/ViaHandler.java b/common/src/main/java/us/myles/ViaVersion/handlers/ViaHandler.java index 335d7127c..b7d779351 100644 --- a/common/src/main/java/us/myles/ViaVersion/handlers/ViaHandler.java +++ b/common/src/main/java/us/myles/ViaVersion/handlers/ViaHandler.java @@ -4,8 +4,8 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; public interface ViaHandler { + void transform(ByteBuf bytebuf) throws Exception; void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception; - }