mirror of
https://github.com/SpigotMC/BungeeCord.git
synced 2024-12-27 11:07:39 +01:00
Complete issue #190 - unthread the login event for maximum efficiency.
This commit is contained in:
parent
a63739277b
commit
93ea108acb
@ -289,17 +289,14 @@ public class PluginManager
|
|||||||
long start = System.nanoTime();
|
long start = System.nanoTime();
|
||||||
eventBus.post( event );
|
eventBus.post( event );
|
||||||
event.postCall();
|
event.postCall();
|
||||||
// TODO: No exceptions!
|
|
||||||
if ( !( event instanceof LoginEvent ) )
|
long elapsed = start - System.nanoTime();
|
||||||
|
if ( elapsed > 250000 )
|
||||||
{
|
{
|
||||||
long elapsed = start - System.nanoTime();
|
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Event {0} took more {1}ns to process!", new Object[]
|
||||||
if ( elapsed > 250000 )
|
|
||||||
{
|
{
|
||||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Event {0} took more {1}ns to process!", new Object[]
|
event, elapsed
|
||||||
{
|
} );
|
||||||
event, elapsed
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.md_5.bungee;
|
package net.md_5.bungee;
|
||||||
|
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
@ -59,7 +60,7 @@ public class EncryptionUtil
|
|||||||
return new SecretKeySpec( secret, "AES" );
|
return new SecretKeySpec( secret, "AES" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Cipher getCipher(int opMode, Key shared) throws InvalidAlgorithmParameterException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException
|
public static Cipher getCipher(int opMode, Key shared) throws GeneralSecurityException
|
||||||
{
|
{
|
||||||
Cipher cip = Cipher.getInstance( "AES/CFB8/NoPadding" );
|
Cipher cip = Cipher.getInstance( "AES/CFB8/NoPadding" );
|
||||||
cip.init( opMode, shared, new IvParameterSpec( shared.getEncoded() ) );
|
cip.init( opMode, shared, new IvParameterSpec( shared.getEncoded() ) );
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package net.md_5.bungee.connection;
|
package net.md_5.bungee.connection;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.ning.http.client.AsyncCompletionHandler;
|
||||||
|
import com.ning.http.client.Response;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -9,6 +11,7 @@ import java.math.BigInteger;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -57,6 +60,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
private PacketFDEncryptionRequest request;
|
private PacketFDEncryptionRequest request;
|
||||||
private List<PacketFAPluginMessage> loginMessages = new ArrayList<>();
|
private List<PacketFAPluginMessage> loginMessages = new ArrayList<>();
|
||||||
private State thisState = State.HANDSHAKE;
|
private State thisState = State.HANDSHAKE;
|
||||||
|
private SecretKey sharedKey;
|
||||||
private boolean disconnected;
|
private boolean disconnected;
|
||||||
|
|
||||||
private enum State
|
private enum State
|
||||||
@ -129,79 +133,75 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
{
|
{
|
||||||
Preconditions.checkState( thisState == State.ENCRYPT, "Not expecting ENCRYPT" );
|
Preconditions.checkState( thisState == State.ENCRYPT, "Not expecting ENCRYPT" );
|
||||||
|
|
||||||
// TODO: This is shit
|
sharedKey = EncryptionUtil.getSecret( encryptResponse, request );
|
||||||
new Thread( "Login Verifier - " + getName() )
|
if ( BungeeCord.getInstance().config.isOnlineMode() )
|
||||||
{
|
{
|
||||||
@Override
|
String encName = URLEncoder.encode( InitialHandler.this.getName(), "UTF-8" );
|
||||||
public void run()
|
|
||||||
|
MessageDigest sha = MessageDigest.getInstance( "SHA-1" );
|
||||||
|
for ( byte[] bit : new byte[][]
|
||||||
{
|
{
|
||||||
try
|
request.serverId.getBytes( "ISO_8859_1" ), sharedKey.getEncoded(), EncryptionUtil.keys.getPublic().getEncoded()
|
||||||
{
|
} )
|
||||||
SecretKey shared = EncryptionUtil.getSecret( encryptResponse, request );
|
{
|
||||||
if ( BungeeCord.getInstance().config.isOnlineMode() )
|
sha.update( bit );
|
||||||
{
|
|
||||||
String reply = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
String encName = URLEncoder.encode( InitialHandler.this.getName(), "UTF-8" );
|
|
||||||
|
|
||||||
MessageDigest sha = MessageDigest.getInstance( "SHA-1" );
|
|
||||||
for ( byte[] bit : new byte[][]
|
|
||||||
{
|
|
||||||
request.serverId.getBytes( "ISO_8859_1" ), shared.getEncoded(), EncryptionUtil.keys.getPublic().getEncoded()
|
|
||||||
} )
|
|
||||||
{
|
|
||||||
sha.update( bit );
|
|
||||||
}
|
|
||||||
|
|
||||||
String encodedHash = URLEncoder.encode( new BigInteger( sha.digest() ).toString( 16 ), "UTF-8" );
|
|
||||||
String authURL = "http://session.minecraft.net/game/checkserver.jsp?user=" + encName + "&serverId=" + encodedHash;
|
|
||||||
|
|
||||||
try ( BufferedReader in = new BufferedReader( new InputStreamReader( new URL( authURL ).openStream() ) ) )
|
|
||||||
{
|
|
||||||
reply = in.readLine();
|
|
||||||
}
|
|
||||||
} catch ( IOException ex )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !"YES".equals( reply ) )
|
|
||||||
{
|
|
||||||
disconnect( "Not authenticated with Minecraft.net" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for multiple connections
|
|
||||||
ProxiedPlayer old = bungee.getPlayer( handshake.username );
|
|
||||||
if ( old != null )
|
|
||||||
{
|
|
||||||
old.disconnect( "You are already connected to the server" );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// fire login event
|
|
||||||
LoginEvent event = new LoginEvent( InitialHandler.this );
|
|
||||||
if ( bungee.getPluginManager().callEvent( event ).isCancelled() )
|
|
||||||
{
|
|
||||||
disconnect( event.getCancelReason() );
|
|
||||||
}
|
|
||||||
if ( disconnected )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cipher encrypt = EncryptionUtil.getCipher( Cipher.ENCRYPT_MODE, shared );
|
|
||||||
Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, shared );
|
|
||||||
ch.write( new PacketFCEncryptionResponse() );
|
|
||||||
ch.pipeline().addBefore( "decoder", "cipher", new CipherCodec( encrypt, decrypt ) );
|
|
||||||
|
|
||||||
thisState = InitialHandler.State.LOGIN;
|
|
||||||
} catch ( Throwable t )
|
|
||||||
{
|
|
||||||
disconnect( "[Report to md_5 / Server Owner] " + Util.exception( t ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.start();
|
|
||||||
|
String encodedHash = URLEncoder.encode( new BigInteger( sha.digest() ).toString( 16 ), "UTF-8" );
|
||||||
|
String authURL = "http://session.minecraft.net/game/checkserver.jsp?user=" + encName + "&serverId=" + encodedHash;
|
||||||
|
bungee.getHttpClient().prepareGet( authURL ).execute( new AsyncCompletionHandler<Response>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Response onCompleted(Response response) throws Exception
|
||||||
|
{
|
||||||
|
if ( "YES".equals( response.getResponseBody() ) )
|
||||||
|
{
|
||||||
|
finish();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
disconnect( "Not authenticated with Minecraft.net" );
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onThrowable(Throwable t)
|
||||||
|
{
|
||||||
|
disconnect( "Error occured while contacting login servers, are they down?" + Util.exception( t ) );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finish() throws GeneralSecurityException
|
||||||
|
{
|
||||||
|
// Check for multiple connections
|
||||||
|
ProxiedPlayer old = bungee.getPlayer( handshake.username );
|
||||||
|
if ( old != null )
|
||||||
|
{
|
||||||
|
old.disconnect( "You are already connected to the server" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fire login event
|
||||||
|
LoginEvent event = new LoginEvent( InitialHandler.this );
|
||||||
|
if ( bungee.getPluginManager().callEvent( event ).isCancelled() )
|
||||||
|
{
|
||||||
|
disconnect( event.getCancelReason() );
|
||||||
|
}
|
||||||
|
if ( disconnected )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cipher encrypt = EncryptionUtil.getCipher( Cipher.ENCRYPT_MODE, sharedKey );
|
||||||
|
Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, sharedKey );
|
||||||
|
ch.write( new PacketFCEncryptionResponse() );
|
||||||
|
ch.pipeline().addBefore( "decoder", "cipher", new CipherCodec( encrypt, decrypt ) );
|
||||||
|
|
||||||
|
thisState = InitialHandler.State.LOGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user