This is hard >.>
This commit is contained in:
parent
55867dbdc3
commit
32ef5212f8
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user