diff --git a/api/src/main/java/net/md_5/bungee/api/event/ClientConnectEvent.java b/api/src/main/java/net/md_5/bungee/api/event/ClientConnectEvent.java new file mode 100644 index 00000000..50ce034c --- /dev/null +++ b/api/src/main/java/net/md_5/bungee/api/event/ClientConnectEvent.java @@ -0,0 +1,35 @@ +package net.md_5.bungee.api.event; + +import java.net.SocketAddress; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import net.md_5.bungee.api.config.ListenerInfo; +import net.md_5.bungee.api.plugin.Cancellable; +import net.md_5.bungee.api.plugin.Event; + +/** + * Event called to represent an initial client connection. + *
+ * Note: This event is called at an early stage of every connection, handling + * should be fast. + */ +@Data +@ToString(callSuper = false) +@EqualsAndHashCode(callSuper = false) +public class ClientConnectEvent extends Event implements Cancellable +{ + + /** + * Cancelled state. + */ + private boolean cancelled; + /** + * Remote address of connection. + */ + private final SocketAddress socketAddress; + /** + * Listener that accepted the connection. + */ + private final ListenerInfo listener; +} diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java index 44e28846..afc2c12a 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java @@ -36,6 +36,7 @@ import net.md_5.bungee.UserConnection; import net.md_5.bungee.Util; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ListenerInfo; +import net.md_5.bungee.api.event.ClientConnectEvent; import net.md_5.bungee.connection.InitialHandler; import net.md_5.bungee.protocol.KickStringWriter; import net.md_5.bungee.protocol.LegacyDecoder; @@ -56,7 +57,9 @@ public class PipelineUtils @Override protected void initChannel(Channel ch) throws Exception { - if ( BungeeCord.getInstance().getConnectionThrottle() != null && BungeeCord.getInstance().getConnectionThrottle().throttle( ch.remoteAddress() ) ) + SocketAddress remoteAddress = ( ch.remoteAddress() == null ) ? ch.parent().localAddress() : ch.remoteAddress(); + + if ( BungeeCord.getInstance().getConnectionThrottle() != null && BungeeCord.getInstance().getConnectionThrottle().throttle( remoteAddress ) ) { ch.close(); return; @@ -64,6 +67,12 @@ public class PipelineUtils ListenerInfo listener = ch.attr( LISTENER ).get(); + if ( BungeeCord.getInstance().getPluginManager().callEvent( new ClientConnectEvent( remoteAddress, listener ) ).isCancelled() ) + { + ch.close(); + return; + } + BASE.initChannel( ch ); ch.pipeline().addBefore( FRAME_DECODER, LEGACY_DECODER, new LegacyDecoder() ); ch.pipeline().addAfter( FRAME_DECODER, PACKET_DECODER, new MinecraftDecoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );