Skip to content
This repository has been archived by the owner on Jul 15, 2022. It is now read-only.

Commit

Permalink
SpigotMC#2447: Add API for fluent server connect requests
Browse files Browse the repository at this point in the history
API allows for more control over callback to see why the callback was performed whilst maintaining backwards compatibility
  • Loading branch information
Mystiflow authored and md-5 committed Jul 30, 2018
1 parent 6fadb42 commit 715ec07
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 7 deletions.
78 changes: 78 additions & 0 deletions api/src/main/java/net/md_5/bungee/api/ServerConnectRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package net.md_5.bungee.api;

import lombok.Builder;
import lombok.Getter;
import lombok.NonNull;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.event.ServerConnectEvent;

/**
* A request to connect a server.
*/
@Getter
@Builder(builderClassName = "Builder")
public class ServerConnectRequest
{

/**
* The result from this callback after request has been executed by proxy.
*/
public enum Result
{

/**
* ServerConnectEvent to the new server was canceled.
*/
EVENT_CANCEL,
/**
* Already connected to target server.
*/
ALREADY_CONNECTED,
/**
* Already connecting to target server.
*/
ALREADY_CONNECTING,
/**
* Successfully connected to server.
*/
SUCCESS,
/**
* Connection failed, error can be accessed from callback method handle.
*/
FAIL
}

/**
* Target server to connect to.
*/
@NonNull
private final ServerInfo target;
/**
* Reason for connecting to server.
*/
@NonNull
private final ServerConnectEvent.Reason reason;
/**
* Callback to execute post request.
*/
private final Callback<Result> callback;
/**
* Timeout in milliseconds for request.
*/
private final int connectTimeout;
/**
* Should the player be attempted to connect to the next server in their
* queue if the initial request fails.
*/
private final boolean retry;

/**
* Class that sets default properties/adds methods to the lombok builder
* generated class.
*/
public static class ServerConnectRequestBuilder
{

private int connectTimeout = 5000; // TODO: Configurable
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ServerConnectRequest;
import net.md_5.bungee.api.SkinConfiguration;
import net.md_5.bungee.api.Title;
import net.md_5.bungee.api.chat.BaseComponent;
Expand Down Expand Up @@ -123,6 +124,15 @@ public enum MainHand
*/
void connect(ServerInfo target, Callback<Boolean> callback, ServerConnectEvent.Reason reason);

/**
* Connects / transfers this user to the specified connection, gracefully
* closing the current one. Depending on the implementation, this method
* might return before the user has been connected.
*
* @param request request to connect with
*/
void connect(ServerConnectRequest request);

/**
* Gets the server this player is connected to.
*
Expand Down
38 changes: 31 additions & 7 deletions proxy/src/main/java/net/md_5/bungee/UserConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.ServerConnectRequest;
import net.md_5.bungee.api.SkinConfiguration;
import net.md_5.bungee.api.Title;
import net.md_5.bungee.api.chat.BaseComponent;
Expand Down Expand Up @@ -253,12 +254,35 @@ public void connect(ServerInfo info, final Callback<Boolean> callback, final boo
{
Preconditions.checkNotNull( info, "info" );

ServerConnectEvent event = new ServerConnectEvent( this, info, reason );
ServerConnectRequest.Builder builder = ServerConnectRequest.builder().retry( retry ).reason( reason ).target( info );
if ( callback != null )
{
// Convert the Callback<Boolean> to be compatible with Callback<Result> from ServerConnectRequest.
builder.callback( new Callback<ServerConnectRequest.Result>()
{
@Override
public void done(ServerConnectRequest.Result result, Throwable error)
{
callback.done( ( result == ServerConnectRequest.Result.SUCCESS ) ? Boolean.TRUE : Boolean.FALSE, error );
}
} );
}

connect( builder.build() );
}

@Override
public void connect(final ServerConnectRequest request)
{
Preconditions.checkNotNull( request, "request" );

final Callback<ServerConnectRequest.Result> callback = request.getCallback();
ServerConnectEvent event = new ServerConnectEvent( this, request.getTarget(), request.getReason() );
if ( bungee.getPluginManager().callEvent( event ).isCancelled() )
{
if ( callback != null )
{
callback.done( false, null );
callback.done( ServerConnectRequest.Result.EVENT_CANCEL, null );
}

if ( getServer() == null && !ch.isClosing() )
Expand All @@ -274,7 +298,7 @@ public void connect(ServerInfo info, final Callback<Boolean> callback, final boo
{
if ( callback != null )
{
callback.done( false, null );
callback.done( ServerConnectRequest.Result.ALREADY_CONNECTED, null );
}

sendMessage( bungee.getTranslation( "already_connected" ) );
Expand All @@ -284,7 +308,7 @@ public void connect(ServerInfo info, final Callback<Boolean> callback, final boo
{
if ( callback != null )
{
callback.done( false, null );
callback.done( ServerConnectRequest.Result.ALREADY_CONNECTING, null );
}

sendMessage( bungee.getTranslation( "already_connecting" ) );
Expand Down Expand Up @@ -312,7 +336,7 @@ public void operationComplete(ChannelFuture future) throws Exception
{
if ( callback != null )
{
callback.done( future.isSuccess(), future.cause() );
callback.done( ( future.isSuccess() ) ? ServerConnectRequest.Result.SUCCESS : ServerConnectRequest.Result.FAIL, future.cause() );
}

if ( !future.isSuccess() )
Expand All @@ -321,7 +345,7 @@ public void operationComplete(ChannelFuture future) throws Exception
pendingConnects.remove( target );

ServerInfo def = updateAndGetNextServer( target );
if ( retry && def != null && ( getServer() == null || def != getServer().getInfo() ) )
if ( request.isRetry() && def != null && ( getServer() == null || def != getServer().getInfo() ) )
{
sendMessage( bungee.getTranslation( "fallback_lobby" ) );
connect( def, null, true, ServerConnectEvent.Reason.LOBBY_FALLBACK );
Expand All @@ -339,7 +363,7 @@ public void operationComplete(ChannelFuture future) throws Exception
.channel( PipelineUtils.getChannel() )
.group( ch.getHandle().eventLoop() )
.handler( initializer )
.option( ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000 ) // TODO: Configurable
.option( ChannelOption.CONNECT_TIMEOUT_MILLIS, request.getConnectTimeout() )
.remoteAddress( target.getAddress() );
// Windows is bugged, multi homed users will just have to live with random connecting IPs
if ( getPendingConnection().getListener().isSetLocalAddress() && !PlatformDependent.isWindows() )
Expand Down

0 comments on commit 715ec07

Please sign in to comment.