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 name name of the server
* @param address connectable Minecraft address + port 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 * @param restricted whether the server info restricted property will be set
* @return the constructed instance * @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 * Returns the console overlord for this proxy. Being the console, this

View File

@ -36,6 +36,13 @@ public interface ServerInfo
*/ */
Collection<ProxiedPlayer> getPlayers(); 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 * Whether the player can access this server. It will only return false when
* the player has no permission and this server is restricted. * the player has no permission and this server is restricted.

View File

@ -474,9 +474,9 @@ public class BungeeCord extends ProxyServer
} }
@Override @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 @Override

View File

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

View File

@ -171,9 +171,10 @@ public class YamlConfig implements ConfigurationAdapter
Map<String, Object> val = entry.getValue(); Map<String, Object> val = entry.getValue();
String name = entry.getKey(); String name = entry.getKey();
String addr = get( "address", "localhost:25565", val ); 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 ); boolean restricted = get( "restricted", false, val );
InetSocketAddress address = Util.getAddr( addr ); 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 ); ret.put( name, info );
} }

View File

@ -3,6 +3,8 @@ 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.AsyncCompletionHandler;
import com.ning.http.client.Response; import com.ning.http.client.Response;
import io.netty.util.concurrent.ScheduledFuture;
import java.io.DataInput;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URLEncoder; import java.net.URLEncoder;
@ -10,6 +12,7 @@ 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;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.SecretKey; 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.PacketFDEncryptionRequest;
import net.md_5.bungee.protocol.packet.PacketFEPing; import net.md_5.bungee.protocol.packet.PacketFEPing;
import net.md_5.bungee.protocol.packet.PacketFFKick; import net.md_5.bungee.protocol.packet.PacketFFKick;
import net.md_5.bungee.reconnect.AbstractReconnectManager;
@RequiredArgsConstructor @RequiredArgsConstructor
public class InitialHandler extends PacketHandler implements PendingConnection public class InitialHandler extends PacketHandler implements PendingConnection
@ -77,6 +81,9 @@ public class InitialHandler extends PacketHandler implements PendingConnection
ch.write( packet ); ch.write( packet );
} }
}; };
private ScheduledFuture<?> pingFuture;
private InetSocketAddress vHost;
private byte version = -1;
private enum State private enum State
{ {
@ -99,6 +106,30 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override @Override
public void handle(PacketFAPluginMessage pluginMessage) throws Exception 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? // TODO: Unregister?
if ( pluginMessage.getTag().equals( "REGISTER" ) ) if ( pluginMessage.getTag().equals( "REGISTER" ) )
{ {
@ -109,13 +140,19 @@ public class InitialHandler extends PacketHandler implements PendingConnection
} }
} }
@Override private void respondToPing()
public void handle(PacketFEPing ping) throws Exception
{ {
ServerInfo forced = AbstractReconnectManager.getForcedHost( this );
String motd = listener.getMotd();
if ( forced != null )
{
motd = forced.getMotd();
}
ServerPing response = new ServerPing( bungee.getProtocolVersion(), bungee.getGameVersion(), ServerPing response = new ServerPing( bungee.getProtocolVersion(), bungee.getGameVersion(),
listener.getMotd(), bungee.getOnlineCount(), listener.getMaxPlayers() ); 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 String kickMessage = ChatColor.DARK_BLUE
+ "\00" + response.getProtocolVersion() + "\00" + response.getProtocolVersion()
@ -126,6 +163,19 @@ public class InitialHandler extends PacketHandler implements PendingConnection
disconnect( kickMessage ); 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 @Override
public void handle(Packet1Login login) throws Exception 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" ); Preconditions.checkState( thisState == State.HANDSHAKE, "Not expecting HANDSHAKE" );
this.handshake = handshake; this.handshake = handshake;
this.vHost = new InetSocketAddress( handshake.getHost(), handshake.getPort() );
bungee.getLogger().log( Level.INFO, "{0} has connected", this ); bungee.getLogger().log( Level.INFO, "{0} has connected", this );
if ( handshake.getProcolVersion() > Vanilla.PROTOCOL_VERSION ) if ( handshake.getProcolVersion() > Vanilla.PROTOCOL_VERSION )
@ -314,13 +365,13 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override @Override
public byte getVersion() public byte getVersion()
{ {
return ( handshake == null ) ? -1 : handshake.getProcolVersion(); return ( handshake == null ) ? version : handshake.getProcolVersion();
} }
@Override @Override
public InetSocketAddress getVirtualHost() public InetSocketAddress getVirtualHost()
{ {
return ( handshake == null ) ? null : new InetSocketAddress( handshake.getHost(), handshake.getPort() ); return vHost;
} }
@Override @Override

View File

@ -3,7 +3,6 @@ package net.md_5.bungee.reconnect;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.ReconnectHandler; 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.config.ServerInfo;
import net.md_5.bungee.api.connection.PendingConnection; import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
@ -14,22 +13,22 @@ public abstract class AbstractReconnectManager implements ReconnectHandler
@Override @Override
public ServerInfo getServer(ProxiedPlayer player) public ServerInfo getServer(ProxiedPlayer player)
{ {
ListenerInfo listener = player.getPendingConnection().getListener(); ServerInfo server = getForcedHost( player.getPendingConnection() );
String name; if ( server == null )
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 )
{ {
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() ); String forced = con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() );
@ -37,8 +36,8 @@ public abstract class AbstractReconnectManager implements ReconnectHandler
{ {
forced = con.getListener().getDefaultServer(); 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.sql.SQLException;
import java.util.logging.Level; import java.util.logging.Level;
import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
public class SQLReconnectHandler extends AbstractReconnectManager public class SQLReconnectHandler extends AbstractReconnectManager
@ -32,7 +33,7 @@ public class SQLReconnectHandler extends AbstractReconnectManager
} }
@Override @Override
protected String getStoredServer(ProxiedPlayer player) protected ServerInfo getStoredServer(ProxiedPlayer player)
{ {
String server = null; String server = null;
try ( PreparedStatement ps = connection.prepareStatement( "SELECT server FROM players WHERE username = ?" ) ) 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 ); ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not load location for player " + player.getName(), ex );
} }
return server;
return ProxyServer.getInstance().getServerInfo( server );
} }
@Override @Override