This is hard >.>

This commit is contained in:
md_5 2013-01-18 10:46:55 +11:00
parent 55867dbdc3
commit 32ef5212f8
7 changed files with 93 additions and 132 deletions

View File

@ -113,6 +113,20 @@ public abstract class ProxyServer
*/
public abstract void setTabListHandler(TabListHandler handler);
/**
* Get the currently in use reconnect handler.
*
* @return the in use reconnect handler
*/
public abstract ReconnectHandler getReconnectHandler();
/**
* Sets the reconnect handler to be used for subsequent connections.
*
* @param handler the new handler
*/
public abstract void setReconnectHandler(ReconnectHandler handler);
/**
* Gracefully mark this instance for shutdown.
*/

View File

@ -28,4 +28,12 @@ public interface PendingConnection extends Connection
* @return request virtual host or null if invalid / not specified.
*/
public InetSocketAddress getVirtualHost();
/**
* Completely kick this user from the proxy and all of its child
* connections.
*
* @param reason the disconnect reason displayed to the player
*/
public void disconnect(String reason);
}

View File

@ -49,14 +49,6 @@ public interface ProxiedPlayer extends Connection, CommandSender
*/
public int getPing();
/**
* Completely kick this user from the proxy and all of its child
* connections.
*
* @param reason the disconnect reason displayed to the player
*/
public void disconnect(String reason);
/**
* Send a plugin message to this player.
*

View File

@ -9,24 +9,26 @@ import java.net.Socket;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import lombok.Getter;
import lombok.Setter;
import static net.md_5.bungee.Logger.$;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.ReconnectHandler;
import net.md_5.bungee.api.TabListHandler;
import net.md_5.bungee.api.config.ConfigurationAdapter;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.PluginManager;
import net.md_5.bungee.command.*;
import net.md_5.bungee.packet.DefinedPacket;
import net.md_5.bungee.packet.PacketFAPluginMessage;
import net.md_5.bungee.tablist.GlobalPingTabList;
import net.md_5.bungee.tablist.GlobalTabList;
import net.md_5.bungee.tablist.ServerUniqueTabList;
@ -65,10 +67,6 @@ public class BungeeCord extends ProxyServer
* Server socket listener.
*/
private ListenThread listener;
/**
* Current version.
*/
public static String version = (BungeeCord.class.getPackage().getImplementationVersion() == null) ? "unknown" : BungeeCord.class.getPackage().getImplementationVersion();
/**
* Fully qualified connections.
*/
@ -77,16 +75,17 @@ public class BungeeCord extends ProxyServer
/**
* Tab list handler
*/
@Getter
@Setter
public TabListHandler tabListHandler;
/**
* Registered Global Plugin Channels
*/
public Queue<String> globalPluginChannels = new ConcurrentLinkedQueue<>();
/**
* Plugin manager.
*/
@Getter
public final PluginManager pluginManager = new PluginManager();
@Getter
@Setter
private ReconnectHandler reconnectHandler;
{
@ -163,14 +162,18 @@ public class BungeeCord extends ProxyServer
break;
}
// Add RubberBand to the global plugin channel list
globalPluginChannels.add("RubberBand");
InetSocketAddress addr = Util.getAddr(config.bindHost);
listener = new ListenThread(addr);
listener.start();
saveThread.start();
saveThread.scheduleAtFixedRate(new TimerTask()
{
@Override
public void run()
{
getReconnectHandler().save();
}
}, 0, TimeUnit.MINUTES.toMillis(5));
$().info("Listening on " + addr);
if (config.metricsEnabled)
@ -186,8 +189,11 @@ public class BungeeCord extends ProxyServer
public void stop()
{
this.isRunning = false;
$().info("Disabling plugin");
pluginManager.onDisable();
$().info("Disabling plugins");
for (Plugin plugin : pluginManager.getPlugins())
{
plugin.onDisable();
}
$().info("Closing listen thread");
try
@ -209,13 +215,7 @@ public class BungeeCord extends ProxyServer
}
$().info("Saving reconnect locations");
saveThread.interrupt();
try
{
saveThread.join();
} catch (InterruptedException ex)
{
}
saveThread.cancel();
$().info("Thank you and goodbye");
System.exit(0);
@ -248,71 +248,6 @@ public class BungeeCord extends ProxyServer
}
}
/**
* Broadcasts a plugin message to all servers with currently connected
* players.
*
* @param channel name
* @param message to send
*/
public void broadcastPluginMessage(String channel, String message)
{
broadcastPluginMessage(channel, message, null);
}
/**
* Broadcasts a plugin message to all servers with currently connected
* players.
*
* @param channel name
* @param message to send
* @param server the message was sent from originally
*/
public void broadcastPluginMessage(String channel, String message, String sourceServer)
{
for (String server : connectionsByServer.keySet())
{
if (sourceServer == null || !sourceServer.equals(server))
{
List<UserConnection> conns = BungeeCord.instance.connectionsByServer.get(server);
if (conns != null && conns.size() > 0)
{
UserConnection user = conns.get(0);
user.sendPluginMessage(channel, message.getBytes());
}
}
}
}
/**
* Send a plugin message to a specific server if it has currently connected
* players.
*
* @param channel name
* @param message to send
* @param server the message is to be sent to
*/
public void sendPluginMessage(String channel, String message, String targetServer)
{
List<UserConnection> conns = connectionsByServer.get(targetServer);
if (conns != null && conns.size() > 0)
{
UserConnection user = conns.get(0);
user.sendPluginMessage(channel, message.getBytes());
}
}
/**
* Register a plugin channel for all users
*
* @param channel name
*/
public void registerPluginChannel(String channel)
{
globalPluginChannels.add(channel);
broadcast(new PacketFAPluginMessage("REGISTER", channel.getBytes()));
}
@Override
public String getName()
{
@ -322,7 +257,7 @@ public class BungeeCord extends ProxyServer
@Override
public String getVersion()
{
return version;
return (BungeeCord.class.getPackage().getImplementationVersion() == null) ? "unknown" : BungeeCord.class.getPackage().getImplementationVersion();
}
@Override
@ -332,15 +267,16 @@ public class BungeeCord extends ProxyServer
}
@Override
@SuppressWarnings("unchecked") // TODO: Abstract more
public Collection<ProxiedPlayer> getPlayers()
{
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
return (Collection) connections.values();
}
@Override
public ProxiedPlayer getPlayer(String name)
{
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
return connections.get(name);
}
@Override

View File

@ -2,26 +2,30 @@ package net.md_5.bungee;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import javax.crypto.SecretKey;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.event.LoginEvent;
import net.md_5.bungee.packet.Packet2Handshake;
import net.md_5.bungee.packet.PacketFCEncryptionResponse;
import net.md_5.bungee.packet.PacketFDEncryptionRequest;
import net.md_5.bungee.packet.PacketFFKick;
import net.md_5.bungee.packet.PacketInputStream;
import net.md_5.bungee.plugin.LoginEvent;
import org.bouncycastle.crypto.io.CipherInputStream;
import org.bouncycastle.crypto.io.CipherOutputStream;
public class InitialHandler implements Runnable
public class InitialHandler implements Runnable, PendingConnection
{
private final Socket socket;
private PacketInputStream in;
private OutputStream out;
private Packet2Handshake handshake;
public InitialHandler(Socket socket) throws IOException
{
@ -40,15 +44,7 @@ public class InitialHandler implements Runnable
switch (id)
{
case 0x02:
Packet2Handshake handshake = new Packet2Handshake(packet);
// fire connect event
LoginEvent event = new LoginEvent(handshake.username, socket.getInetAddress(), handshake.host);
BungeeCord.instance.pluginManager.onHandshake(event);
if (event.isCancelled())
{
throw new KickException(event.getCancelReason());
}
handshake = new Packet2Handshake(packet);
PacketFDEncryptionRequest request = EncryptionUtil.encryptRequest();
out.write(request.getPacket());
PacketFCEncryptionResponse response = new PacketFCEncryptionResponse(in.readPacket());
@ -59,8 +55,8 @@ public class InitialHandler implements Runnable
throw new KickException("Not authenticated with minecraft.net");
}
// fire post auth event
BungeeCord.instance.pluginManager.onLogin(event);
// fire login event
LoginEvent event = new LoginEvent(this);
if (event.isCancelled())
{
throw new KickException(event.getCancelReason());
@ -77,8 +73,6 @@ public class InitialHandler implements Runnable
}
UserConnection userCon = new UserConnection(socket, in, out, handshake, customPackets);
String server = (BungeeCord.instance.config.forceDefaultServer) ? BungeeCord.instance.config.defaultServerName : BungeeCord.instance.config.getServer(handshake.username, handshake.host);
userCon.connect(server);
break;
case 0xFE:
socket.setSoTimeout(100);
@ -90,14 +84,14 @@ public class InitialHandler implements Runnable
} catch (IOException ex)
{
}
Configuration conf = BungeeCord.instance.config;
Configuration conf = BungeeCord.getInstance().config;
String ping = (newPing) ? ChatColor.COLOR_CHAR + "1"
+ "\00" + BungeeCord.PROTOCOL_VERSION
+ "\00" + BungeeCord.GAME_VERSION
+ "\00" + conf.motd
+ "\00" + BungeeCord.instance.connections.size()
+ "\00" + ProxyServer.getInstance().getPlayers().size()
+ "\00" + conf.maxPlayers
: conf.motd + ChatColor.COLOR_CHAR + BungeeCord.instance.connections.size() + ChatColor.COLOR_CHAR + conf.maxPlayers;
: conf.motd + ChatColor.COLOR_CHAR + ProxyServer.getInstance().getPlayers().size() + ChatColor.COLOR_CHAR + conf.maxPlayers;
throw new KickException(ping);
default:
if (id == 0xFA)
@ -110,18 +104,19 @@ public class InitialHandler implements Runnable
}
} catch (KickException ex)
{
kick(ex.getMessage());
disconnect(ex.getMessage());
} catch (Exception ex)
{
kick("[Proxy Error] " + Util.exception(ex));
disconnect("[Proxy Error] " + Util.exception(ex));
}
}
private void kick(String message)
@Override
public void disconnect(String reason)
{
try
{
out.write(new PacketFFKick(message).getPacket());
out.write(new PacketFFKick(reason).getPacket());
} catch (IOException ioe)
{
} finally
@ -135,4 +130,28 @@ public class InitialHandler implements Runnable
}
}
}
@Override
public String getName()
{
return (handshake == null) ? null : handshake.username;
}
@Override
public byte getVersion()
{
return (handshake == null) ? -1 : handshake.procolVersion;
}
@Override
public InetSocketAddress getVirtualHost()
{
return (handshake == null) ? null : new InetSocketAddress(handshake.host, handshake.port);
}
@Override
public InetSocketAddress getAddress()
{
return (InetSocketAddress) socket.getRemoteSocketAddress();
}
}

View File

@ -17,7 +17,6 @@ import net.md_5.bungee.packet.DefinedPacket;
import net.md_5.bungee.packet.Packet1Login;
import net.md_5.bungee.packet.Packet2Handshake;
import net.md_5.bungee.packet.PacketCDClientStatus;
import net.md_5.bungee.packet.PacketFAPluginMessage;
import net.md_5.bungee.packet.PacketFCEncryptionResponse;
import net.md_5.bungee.packet.PacketFDEncryptionRequest;
import net.md_5.bungee.packet.PacketFFKick;
@ -84,13 +83,6 @@ public class ServerConnection extends GenericConnection implements Server
}
Packet1Login login = new Packet1Login(loginResponse);
// Register all global plugin message channels
// TODO: Allow player-specific plugin message channels for full mod support
for (String channel : BungeeCord.getInstance().globalPluginChannels)
{
out.write(new PacketFAPluginMessage("REGISTER", channel.getBytes()).getPacket());
}
return new ServerConnection(name, socket, in, out, login);
} catch (KickException ex)
{

View File

@ -1,8 +1,8 @@
package net.md_5.bungee.command;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Command;
public class CommandBungee extends Command
@ -16,6 +16,6 @@ public class CommandBungee extends Command
@Override
public void execute(CommandSender sender, String[] args)
{
sender.sendMessage(ChatColor.BLUE + "This server is running BungeeCord version " + BungeeCord.version + " by md_5");
sender.sendMessage(ChatColor.BLUE + "This server is running BungeeCord version " + ProxyServer.getInstance().getVersion() + " by md_5");
}
}