Partially support forced_hosts MOTD without SRV records - gonna think how best to put this in the config, for now its server: motd:, might remove listener motd later on

This commit is contained in:
md_5 2013-07-01 14:05:57 +10:00
parent 8732904bfd
commit 632fa8bd94
8 changed files with 89 additions and 26 deletions

View File

@ -189,10 +189,11 @@ public abstract class ProxyServer
*
* @param name name of the server
* @param address connectable Minecraft address + port of the server
* @param motd the motd when used as a forced server
* @param restricted whether the server info restricted property will be set
* @return the constructed instance
*/
public abstract ServerInfo constructServerInfo(String name, InetSocketAddress address, boolean restricted);
public abstract ServerInfo constructServerInfo(String name, InetSocketAddress address, String motd, boolean restricted);
/**
* Returns the console overlord for this proxy. Being the console, this

View File

@ -36,6 +36,13 @@ public interface ServerInfo
*/
Collection<ProxiedPlayer> getPlayers();
/**
* Returns the MOTD which should be used when this server is a forced host.
*
* @return the motd
*/
String getMotd();
/**
* Whether the player can access this server. It will only return false when
* the player has no permission and this server is restricted.

View File

@ -474,9 +474,9 @@ public class BungeeCord extends ProxyServer
}
@Override
public ServerInfo constructServerInfo(String name, InetSocketAddress address, boolean restricted)
public ServerInfo constructServerInfo(String name, InetSocketAddress address, String motd, boolean restricted)
{
return new BungeeServerInfo( name, address, restricted );
return new BungeeServerInfo( name, address, motd, restricted );
}
@Override

View File

@ -38,6 +38,8 @@ public class BungeeServerInfo implements ServerInfo
private final InetSocketAddress address;
private final Collection<ProxiedPlayer> players = new ArrayList<>();
@Getter
private final String motd;
@Getter
private final boolean restricted;
@Getter
private final Queue<DefinedPacket> packetQueue = new LinkedList<>();

View File

@ -171,9 +171,10 @@ public class YamlConfig implements ConfigurationAdapter
Map<String, Object> val = entry.getValue();
String name = entry.getKey();
String addr = get( "address", "localhost:25565", val );
String motd = ChatColor.translateAlternateColorCodes( '&', get( "motd", "Just another BungeeCord - Forced Host", val ) );
boolean restricted = get( "restricted", false, val );
InetSocketAddress address = Util.getAddr( addr );
ServerInfo info = ProxyServer.getInstance().constructServerInfo( name, address, restricted );
ServerInfo info = ProxyServer.getInstance().constructServerInfo( name, address, motd, restricted );
ret.put( name, info );
}

View File

@ -3,6 +3,8 @@ package net.md_5.bungee.connection;
import com.google.common.base.Preconditions;
import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.Response;
import io.netty.util.concurrent.ScheduledFuture;
import java.io.DataInput;
import java.math.BigInteger;
import java.net.InetSocketAddress;
import java.net.URLEncoder;
@ -10,6 +12,7 @@ import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
@ -49,6 +52,7 @@ import net.md_5.bungee.protocol.packet.PacketFCEncryptionResponse;
import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest;
import net.md_5.bungee.protocol.packet.PacketFEPing;
import net.md_5.bungee.protocol.packet.PacketFFKick;
import net.md_5.bungee.reconnect.AbstractReconnectManager;
@RequiredArgsConstructor
public class InitialHandler extends PacketHandler implements PendingConnection
@ -77,6 +81,9 @@ public class InitialHandler extends PacketHandler implements PendingConnection
ch.write( packet );
}
};
private ScheduledFuture<?> pingFuture;
private InetSocketAddress vHost;
private byte version = -1;
private enum State
{
@ -99,6 +106,30 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public void handle(PacketFAPluginMessage pluginMessage) throws Exception
{
if ( pluginMessage.getTag().equals( "MC|PingHost" ) )
{
if ( pingFuture.cancel( false ) )
{
DataInput in = pluginMessage.getStream();
version = in.readByte();
//
short len = in.readShort();
char[] chars = new char[ len ];
for ( int i = 0; i < len; i++ )
{
chars[i] = in.readChar();
}
//
String connectHost = new String( chars );
int connectPort = in.readInt();
this.vHost = new InetSocketAddress( connectHost, connectPort );
respondToPing();
}
return;
}
// TODO: Unregister?
if ( pluginMessage.getTag().equals( "REGISTER" ) )
{
@ -109,13 +140,19 @@ public class InitialHandler extends PacketHandler implements PendingConnection
}
}
@Override
public void handle(PacketFEPing ping) throws Exception
private void respondToPing()
{
ServerInfo forced = AbstractReconnectManager.getForcedHost( this );
String motd = listener.getMotd();
if ( forced != null )
{
motd = forced.getMotd();
}
ServerPing response = new ServerPing( bungee.getProtocolVersion(), bungee.getGameVersion(),
listener.getMotd(), bungee.getOnlineCount(), listener.getMaxPlayers() );
response = bungee.getPluginManager().callEvent( new ProxyPingEvent( this, response ) ).getResponse();
response = bungee.getPluginManager().callEvent( new ProxyPingEvent( InitialHandler.this, response ) ).getResponse();
String kickMessage = ChatColor.DARK_BLUE
+ "\00" + response.getProtocolVersion()
@ -126,6 +163,19 @@ public class InitialHandler extends PacketHandler implements PendingConnection
disconnect( kickMessage );
}
@Override
public void handle(PacketFEPing ping) throws Exception
{
pingFuture = ch.getHandle().eventLoop().schedule( new Runnable()
{
@Override
public void run()
{
respondToPing();
}
}, 1000, TimeUnit.MILLISECONDS );
}
@Override
public void handle(Packet1Login login) throws Exception
{
@ -141,6 +191,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{
Preconditions.checkState( thisState == State.HANDSHAKE, "Not expecting HANDSHAKE" );
this.handshake = handshake;
this.vHost = new InetSocketAddress( handshake.getHost(), handshake.getPort() );
bungee.getLogger().log( Level.INFO, "{0} has connected", this );
if ( handshake.getProcolVersion() > Vanilla.PROTOCOL_VERSION )
@ -314,13 +365,13 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public byte getVersion()
{
return ( handshake == null ) ? -1 : handshake.getProcolVersion();
return ( handshake == null ) ? version : handshake.getProcolVersion();
}
@Override
public InetSocketAddress getVirtualHost()
{
return ( handshake == null ) ? null : new InetSocketAddress( handshake.getHost(), handshake.getPort() );
return vHost;
}
@Override

View File

@ -3,7 +3,6 @@ package net.md_5.bungee.reconnect;
import com.google.common.base.Preconditions;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.ReconnectHandler;
import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer;
@ -14,22 +13,22 @@ public abstract class AbstractReconnectManager implements ReconnectHandler
@Override
public ServerInfo getServer(ProxiedPlayer player)
{
ListenerInfo listener = player.getPendingConnection().getListener();
String name;
ServerInfo forced = getHost( player.getPendingConnection() );
String server = ( forced == null ) ? getStoredServer( player ) : forced.getName();
name = ( server != null ) ? server : listener.getDefaultServer();
ServerInfo info = ProxyServer.getInstance().getServerInfo( name );
if ( info == null )
ServerInfo server = getForcedHost( player.getPendingConnection() );
if ( server == null )
{
info = ProxyServer.getInstance().getServerInfo( listener.getDefaultServer() );
server = getStoredServer( player );
if ( server == null )
{
server = ProxyServer.getInstance().getServerInfo( player.getPendingConnection().getListener().getDefaultServer() );
}
Preconditions.checkState( server != null, "Default server not defined" );
}
Preconditions.checkState( info != null, "Default server not defined" );
return info;
return server;
}
public static ServerInfo getHost(PendingConnection con)
public static ServerInfo getForcedHost(PendingConnection con)
{
String forced = con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() );
@ -37,8 +36,8 @@ public abstract class AbstractReconnectManager implements ReconnectHandler
{
forced = con.getListener().getDefaultServer();
}
return ( forced != null ) ? ProxyServer.getInstance().getServerInfo( forced ) : null;
return ProxyServer.getInstance().getServerInfo( forced );
}
protected abstract String getStoredServer(ProxiedPlayer player);
protected abstract ServerInfo getStoredServer(ProxiedPlayer player);
}

View File

@ -7,6 +7,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class SQLReconnectHandler extends AbstractReconnectManager
@ -32,7 +33,7 @@ public class SQLReconnectHandler extends AbstractReconnectManager
}
@Override
protected String getStoredServer(ProxiedPlayer player)
protected ServerInfo getStoredServer(ProxiedPlayer player)
{
String server = null;
try ( PreparedStatement ps = connection.prepareStatement( "SELECT server FROM players WHERE username = ?" ) )
@ -56,7 +57,8 @@ public class SQLReconnectHandler extends AbstractReconnectManager
{
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not load location for player " + player.getName(), ex );
}
return server;
return ProxyServer.getInstance().getServerInfo( server );
}
@Override