From b6e76f4054e40ebd3ca12ef5b49c8e12471eea91 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 7 Mar 2013 21:04:03 +1100 Subject: [PATCH] Cleanup permissions and disconnect sequences --- .../bungee/api/connection/Connection.java | 10 ++ proxy/pom.xml | 5 + .../net/md_5/bungee/ServerConnection.java | 11 ++ .../java/net/md_5/bungee/UserConnection.java | 162 +++++++++--------- 4 files changed, 104 insertions(+), 84 deletions(-) diff --git a/api/src/main/java/net/md_5/bungee/api/connection/Connection.java b/api/src/main/java/net/md_5/bungee/api/connection/Connection.java index 3962b9a9..ba72a96a 100644 --- a/api/src/main/java/net/md_5/bungee/api/connection/Connection.java +++ b/api/src/main/java/net/md_5/bungee/api/connection/Connection.java @@ -16,4 +16,14 @@ public interface Connection * @return the remote address */ public InetSocketAddress getAddress(); + + /** + * Disconnects this end of the connection for the specified reason. If this + * is an {@link ProxiedPlayer} the respective server connection will be + * closed too. + * + * @param reason the reason shown to the player / sent to the server on + * disconnect + */ + public void disconnect(String reason); } diff --git a/proxy/pom.xml b/proxy/pom.xml index 210fde51..577546fc 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -34,6 +34,11 @@ bungeecord-api ${project.version} + + net.sf.trove4j + trove4j + 3.0.3 + mysql mysql-connector-java diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java index 6e6e0144..1e7929d6 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnection.java @@ -8,6 +8,7 @@ import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.Server; import net.md_5.bungee.packet.Packet1Login; import net.md_5.bungee.packet.PacketFAPluginMessage; +import net.md_5.bungee.packet.PacketFFKick; @RequiredArgsConstructor public class ServerConnection implements Server @@ -25,6 +26,16 @@ public class ServerConnection implements Server ch.write( new PacketFAPluginMessage( channel, data ) ); } + @Override + public synchronized void disconnect(String reason) + { + if ( ch.isActive() ) + { + ch.write( new PacketFFKick( reason ) ); + ch.close(); + } + } + @Override public InetSocketAddress getAddress() { diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index 645e56ea..b2ed95e1 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -1,13 +1,13 @@ package net.md_5.bungee; +import gnu.trove.set.hash.THashSet; +import io.netty.channel.Channel; import java.net.InetSocketAddress; import java.net.Socket; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import lombok.Getter; @@ -20,12 +20,15 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.PlayerDisconnectEvent; import net.md_5.bungee.api.event.ServerConnectEvent; import net.md_5.bungee.connection.DownstreamBridge; +import net.md_5.bungee.connection.UpstreamBridge; import net.md_5.bungee.packet.*; -public final class UserConnection extends GenericConnection implements ProxiedPlayer +public final class UserConnection implements ProxiedPlayer { public final Packet2Handshake handshake; + private final ProxyServer bungee; + private final Channel ch; final Packet1Login forgeLogin; final List loginMessages; public Queue packetQueue = new ConcurrentLinkedQueue<>(); @@ -36,7 +39,6 @@ public final class UserConnection extends GenericConnection implements ProxiedPl // reconnect stuff private int clientEntityId; private int serverEntityId; - private volatile boolean reconnecting; // ping stuff public int trackingPingId; public long pingTime; @@ -44,12 +46,9 @@ public final class UserConnection extends GenericConnection implements ProxiedPl @Setter private int ping = 1000; // Permissions - private final Collection groups = new HashSet<>(); - private final Map permissions = new HashMap<>(); + private final Collection playerGroups = new HashSet<>(); + private final THashSet permissions = new THashSet<>(); private final Object permMutex = new Object(); - // Hack for connect timings - private ServerInfo nextServer; - private volatile boolean clientConnected = true; public UserConnection(Socket socket, PendingConnection pendingConnection, PacketStream stream, Packet2Handshake handshake, Packet1Login forgeLogin, List loginMessages) { @@ -97,86 +96,76 @@ public final class UserConnection extends GenericConnection implements ProxiedPl target = event.getTarget(); // Update in case the event changed target ProxyServer.getInstance().getTabListHandler().onServerChange( this ); - try + + reconnecting = true; + + if ( server != null ) { - reconnecting = true; - - if ( server != null ) - { - stream.write( new Packet9Respawn( (byte) 1, (byte) 0, (byte) 0, (short) 256, "DEFAULT" ) ); - stream.write( new Packet9Respawn( (byte) -1, (byte) 0, (byte) 0, (short) 256, "DEFAULT" ) ); - } - - ServerConnection newServer = ServerConnector.connect( this, target, true ); - if ( server == null ) - { - // Once again, first connection - clientEntityId = newServer.loginPacket.entityId; - serverEntityId = newServer.loginPacket.entityId; - // Set tab list size - Packet1Login s = newServer.loginPacket; - Packet1Login login = new Packet1Login( s.entityId, s.levelType, s.gameMode, (byte) s.dimension, s.difficulty, s.unused, (byte) pendingConnection.getListener().getTabListSize() ); - stream.write( login ); - stream.write( BungeeCord.getInstance().registerChannels() ); - - upBridge = new UpstreamBridge(); - upBridge.start(); - } else - { - try - { - downBridge.interrupt(); - downBridge.join(); - } catch ( InterruptedException ie ) - { - } - - server.disconnect( "Quitting" ); - server.getInfo().removePlayer( this ); - - Packet1Login login = newServer.loginPacket; - serverEntityId = login.entityId; - stream.write( new Packet9Respawn( login.dimension, login.difficulty, login.gameMode, (short) 256, login.levelType ) ); - } - - // Reconnect process has finished, lets get the player moving again - reconnecting = false; - - // Add to new - target.addPlayer( this ); - - // Start the bridges and move on - server = newServer; - downBridge = new DownstreamBridge(); - downBridge.start(); - } catch ( KickException ex ) - { - disconnect( ex.getMessage() ); - } catch ( Exception ex ) - { - disconnect( "Could not connect to server - " + Util.exception( ex ) ); + stream.write( new Packet9Respawn( (byte) 1, (byte) 0, (byte) 0, (short) 256, "DEFAULT" ) ); + stream.write( new Packet9Respawn( (byte) -1, (byte) 0, (byte) 0, (short) 256, "DEFAULT" ) ); } + + ServerConnection newServer = ServerConnector.connect( this, target, true ); + if ( server == null ) + { + // Once again, first connection + clientEntityId = newServer.loginPacket.entityId; + serverEntityId = newServer.loginPacket.entityId; + // Set tab list size + Packet1Login s = newServer.loginPacket; + Packet1Login login = new Packet1Login( s.entityId, s.levelType, s.gameMode, (byte) s.dimension, s.difficulty, s.unused, (byte) pendingConnection.getListener().getTabListSize() ); + stream.write( login ); + stream.write( BungeeCord.getInstance().registerChannels() ); + + upBridge = new UpstreamBridge(); + upBridge.start(); + } else + { + try + { + downBridge.interrupt(); + downBridge.join(); + } catch ( InterruptedException ie ) + { + } + + server.disconnect( "Quitting" ); + server.getInfo().removePlayer( this ); + + Packet1Login login = newServer.loginPacket; + serverEntityId = login.entityId; + stream.write( new Packet9Respawn( login.dimension, login.difficulty, login.gameMode, (short) 256, login.levelType ) ); + } + + // Reconnect process has finished, lets get the player moving again + reconnecting = false; + + // Add to new + target.addPlayer( this ); + + // Start the bridges and move on + server = newServer; } @Override public synchronized void disconnect(String reason) { - if ( clientConnected ) + if ( ch.isActive() ) { PlayerDisconnectEvent event = new PlayerDisconnectEvent( this ); - ProxyServer.getInstance().getPluginManager().callEvent( event ); - ProxyServer.getInstance().getTabListHandler().onDisconnect( this ); - ProxyServer.getInstance().getPlayers().remove( this ); + bungee.getPluginManager().callEvent( event ); + bungee.getTabListHandler().onDisconnect( this ); + bungee.getPlayers().remove( this ); + + ch.write( new PacketFFKick( reason ) ); + ch.close(); - super.disconnect( reason ); if ( server != null ) { server.getInfo().removePlayer( this ); server.disconnect( "Quitting" ); - ProxyServer.getInstance().getReconnectHandler().setServer( this ); + bungee.getReconnectHandler().setServer( this ); } - - clientConnected = false; } } @@ -189,20 +178,20 @@ public final class UserConnection extends GenericConnection implements ProxiedPl @Override public void sendData(String channel, byte[] data) { - server.packetQueue.add( new PacketFAPluginMessage( channel, data ) ); + ch.write( new PacketFAPluginMessage( channel, data ) ); } @Override public InetSocketAddress getAddress() { - return (InetSocketAddress) socket.getRemoteSocketAddress(); + return (InetSocketAddress) ch.remoteAddress(); } @Override @Synchronized("permMutex") public Collection getGroups() { - return Collections.unmodifiableCollection( groups ); + return Collections.unmodifiableCollection( playerGroups ); } @Override @@ -211,8 +200,8 @@ public final class UserConnection extends GenericConnection implements ProxiedPl { for ( String group : groups ) { - this.groups.add( group ); - for ( String permission : ProxyServer.getInstance().getConfigurationAdapter().getPermissions( group ) ) + playerGroups.add( group ); + for ( String permission : bungee.getConfigurationAdapter().getPermissions( group ) ) { setPermission( permission, true ); } @@ -225,8 +214,8 @@ public final class UserConnection extends GenericConnection implements ProxiedPl { for ( String group : groups ) { - this.groups.remove( group ); - for ( String permission : ProxyServer.getInstance().getConfigurationAdapter().getPermissions( group ) ) + playerGroups.remove( group ); + for ( String permission : bungee.getConfigurationAdapter().getPermissions( group ) ) { setPermission( permission, false ); } @@ -237,14 +226,19 @@ public final class UserConnection extends GenericConnection implements ProxiedPl @Synchronized("permMutex") public boolean hasPermission(String permission) { - Boolean val = permissions.get( permission ); - return ( val == null ) ? false : val; + return permissions.contains( permission ); } @Override @Synchronized("permMutex") public void setPermission(String permission, boolean value) { - permissions.put( permission, value ); + if ( value ) + { + permissions.add( permission ); + } else + { + permissions.remove( permission ); + } } }