diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyServer.java b/api/src/main/java/net/md_5/bungee/api/ProxyServer.java index 112beac5..dd51cdd9 100644 --- a/api/src/main/java/net/md_5/bungee/api/ProxyServer.java +++ b/api/src/main/java/net/md_5/bungee/api/ProxyServer.java @@ -98,6 +98,21 @@ public abstract class ProxyServer */ public abstract void setConfigurationAdapter(ConfigurationAdapter adapter); + /** + * Get the currently in use tab list handle. + * + * @return the tab list handler + */ + public abstract TabListHandler getTabListHandler(); + + /** + * Set the used tab list handler, should not be changed once players have + * connected + * + * @param handler the tab list handler to set + */ + public abstract void setTabListHandler(TabListHandler handler); + /** * Gracefully mark this instance for shutdown. */ diff --git a/api/src/main/java/net/md_5/bungee/api/event/PluginMessageEvent.java b/api/src/main/java/net/md_5/bungee/api/event/PluginMessageEvent.java index 8ef3ac9b..7ac4cf86 100644 --- a/api/src/main/java/net/md_5/bungee/api/event/PluginMessageEvent.java +++ b/api/src/main/java/net/md_5/bungee/api/event/PluginMessageEvent.java @@ -22,11 +22,11 @@ public class PluginMessageEvent extends TargetedEvent implements Cancellable /** * Tag specified for this plugin message. */ - private String tag; + private final String tag; /** * Data contained in this plugin message. */ - private byte[] data; + private final byte[] data; public PluginMessageEvent(Connection sender, Connection receiver, String tag, byte[] data) { diff --git a/api/src/main/java/net/md_5/bungee/api/event/ServerConnectEvent.java b/api/src/main/java/net/md_5/bungee/api/event/ServerConnectEvent.java new file mode 100644 index 00000000..b050d582 --- /dev/null +++ b/api/src/main/java/net/md_5/bungee/api/event/ServerConnectEvent.java @@ -0,0 +1,26 @@ +package net.md_5.bungee.api.event; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.connection.Server; +import net.md_5.bungee.api.plugin.Event; + +@Data +@AllArgsConstructor +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +public class ServerConnectEvent extends Event +{ + + /** + * Player connecting to a new server. + */ + private final ProxiedPlayer player; + /** + * Server the player will be connected to. + */ + private Server target; +} diff --git a/api/src/main/java/net/md_5/bungee/api/event/TargetedEvent.java b/api/src/main/java/net/md_5/bungee/api/event/TargetedEvent.java index 800990b8..c64105ab 100644 --- a/api/src/main/java/net/md_5/bungee/api/event/TargetedEvent.java +++ b/api/src/main/java/net/md_5/bungee/api/event/TargetedEvent.java @@ -2,7 +2,9 @@ package net.md_5.bungee.api.event; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.EqualsAndHashCode; import net.md_5.bungee.api.connection.Connection; +import net.md_5.bungee.api.plugin.Event; /** * An event which occurs in the communication between two nodes. It is not @@ -12,7 +14,8 @@ import net.md_5.bungee.api.connection.Connection; */ @Data @AllArgsConstructor -public abstract class TargetedEvent +@EqualsAndHashCode(callSuper = false) +public abstract class TargetedEvent extends Event { /** diff --git a/proxy/src/main/java/net/md_5/bungee/Configuration.java b/proxy/src/main/java/net/md_5/bungee/Configuration.java index 86545f6c..92ca0ebd 100644 --- a/proxy/src/main/java/net/md_5/bungee/Configuration.java +++ b/proxy/src/main/java/net/md_5/bungee/Configuration.java @@ -268,7 +268,7 @@ public class Configuration */ public void setServer(UserConnection user, String server) { - reconnectLocations.put(user.username, server); + reconnectLocations.put(user.name, server); } /** diff --git a/proxy/src/main/java/net/md_5/bungee/GenericConnection.java b/proxy/src/main/java/net/md_5/bungee/GenericConnection.java index b06fa2d2..a4e89301 100644 --- a/proxy/src/main/java/net/md_5/bungee/GenericConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/GenericConnection.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.RequiredArgsConstructor; import static net.md_5.bungee.Logger.$; import net.md_5.bungee.packet.PacketFFKick; @@ -20,8 +21,10 @@ public class GenericConnection protected final Socket socket; protected final PacketInputStream in; protected final OutputStream out; - public String username; - public String tabListName; + @Getter + public String name; + @Getter + public String displayName; /** * Close the socket with the specified reason. @@ -55,6 +58,6 @@ public class GenericConnection public void log(String message) { - $().info(socket.getInetAddress() + ((username == null) ? " " : " [" + username + "] ") + message); + $().info(socket.getInetAddress() + ((name == null) ? " " : " [" + name + "] ") + message); } } diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index 815cf20c..1dbd5516 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -4,17 +4,18 @@ import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; -import java.net.SocketAddress; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; -import javax.print.attribute.standard.Destination; +import lombok.Getter; +import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.Server; import net.md_5.bungee.api.event.ChatEvent; import net.md_5.bungee.api.event.PluginMessageEvent; +import net.md_5.bungee.api.event.ServerConnectEvent; import net.md_5.bungee.packet.*; public class UserConnection extends GenericConnection implements ProxiedPlayer @@ -23,6 +24,7 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer public final Packet2Handshake handshake; public Queue packetQueue = new ConcurrentLinkedQueue<>(); public List loginPackets = new ArrayList<>(); + @Getter private ServerConnection server; private UpstreamBridge upBridge; private DownstreamBridge downBridge; @@ -33,6 +35,7 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer // ping stuff private int trackingPingId; private long pingTime; + @Getter private int ping; public UserConnection instance = this; @@ -40,39 +43,25 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer { super(socket, in, out); this.handshake = handshake; - username = handshake.username; - tabListName = handshake.username; + name = handshake.username; + displayName = handshake.username; this.loginPackets = loginPackets; - BungeeCord.instance.connections.put(username, this); + BungeeCord.instance.connections.put(name, this); BungeeCord.instance.tabListHandler.onJoin(this); } - public void setTabListName(String newName) + @Override + public void setDisplayName(String name) { - BungeeCord.instance.tabListHandler.onDisconnect(this); - tabListName = newName; - BungeeCord.instance.tabListHandler.onJoin(this); + ProxyServer.getInstance().getTabListHandler().onDisconnect(this); + displayName = name; + ProxyServer.getInstance().getTabListHandler().onConnect(this); } - public void connect(String server) + public void connect(Server server) { - ServerConnectEvent event = new ServerConnectEvent(this.server == null, this, server); - event.setNewServer(server); - BungeeCord.instance.pluginManager.onServerConnect(event); - if (event.getMessage() != null) - { - this.sendMessage(event.getMessage()); - } - if (event.getNewServer() == null) - { - if (event.isFirstTime()) - { - event.setNewServer(BungeeCord.instance.config.defaultServerName); - } else - { - return; - } - } + ServerConnectEvent event = new ServerConnectEvent(this, server); + BungeeCord.getInstance().getPluginManager().callEvent(event); InetSocketAddress addr = BungeeCord.instance.config.getServer(event.getNewServer()); connect(server, addr); } @@ -146,21 +135,6 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer } } - public String getServer() - { - return server.name; - } - - public SocketAddress getAddress() - { - return socket.getRemoteSocketAddress(); - } - - public int getPing() - { - return ping; - } - private void setPing(int ping) { BungeeCord.instance.tabListHandler.onPingChange(this, ping); @@ -171,7 +145,7 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer { if (BungeeCord.instance.isRunning) { - BungeeCord.instance.connections.remove(username); + BungeeCord.instance.connections.remove(name); if (server != null) { List conns = BungeeCord.instance.connectionsByServer.get(server.name); @@ -202,45 +176,10 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer packetQueue.add(new Packet3Chat(message)); } - public void sendPluginMessage(String tag, byte[] data) - { - server.packetQueue.add(new PacketFAPluginMessage(tag, data)); - } - - @Override - public String getName() - { - return username; - } - - @Override - public String getDisplayName() - { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setDisplayName(String name) - { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void connect(Server server) - { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Server getServer() - { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - @Override public void sendData(String channel, byte[] data) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + server.packetQueue.add(new PacketFAPluginMessage(channel, data)); } @Override @@ -284,7 +223,7 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer public UpstreamBridge() { - super("Upstream Bridge - " + username); + super("Upstream Bridge - " + name); } @Override @@ -298,39 +237,37 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer boolean sendPacket = true; int id = Util.getId(packet); - if (id == 0xFA) + switch (id) { - // Call the onPluginMessage event - PacketFAPluginMessage message = new PacketFAPluginMessage(packet); - PluginMessageEvent event = new PluginMessageEvent(Destination.SERVER, instance); - event.setTag(message.tag); - event.setData(new String(message.data)); - BungeeCord.instance.pluginManager.onPluginMessage(event); + case 0x00: + if (trackingPingId == new Packet0KeepAlive(packet).id) + { + setPing((int) (System.currentTimeMillis() - pingTime)); + } + break; + case 0x03: + Packet3Chat chat = new Packet3Chat(packet); + if (chat.message.startsWith("/")) + { + sendPacket = !ProxyServer.getInstance().getPluginManager().dispatchCommand(UserConnection.this, chat.message.substring(1)); + } else + { + ChatEvent chatEvent = new ChatEvent(UserConnection.this, server, chat.message); + ProxyServer.getInstance().getPluginManager().callEvent(chatEvent); + sendPacket = !chatEvent.isCancelled(); + } + break; + case 0xFA: + // Call the onPluginMessage event + PacketFAPluginMessage message = new PacketFAPluginMessage(packet); + PluginMessageEvent event = new PluginMessageEvent(UserConnection.this, server, message.tag, message.data); + ProxyServer.getInstance().getPluginManager().callEvent(event); - if (event.isCancelled()) - { - continue; - } - } else if (id == 0x03) - { - Packet3Chat chat = new Packet3Chat(packet); - String message = chat.message; - if (message.startsWith("/")) - { - sendPacket = !BungeeCord.instance.dispatchCommand(message.substring(1), UserConnection.this); - } else - { - ChatEvent chatEvent = new ChatEvent(ChatEvent.Destination.SERVER, instance); - chatEvent.setText(message); - BungeeCord.instance.pluginManager.onChat(chatEvent); - sendPacket = !chatEvent.isCancelled(); - } - } else if (id == 0x00) - { - if (trackingPingId == new Packet0KeepAlive(packet).id) - { - setPing((int) (System.currentTimeMillis() - pingTime)); - } + if (event.isCancelled()) + { + continue; + } + break; } while (!server.packetQueue.isEmpty()) @@ -363,7 +300,7 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer public DownstreamBridge() { - super("Downstream Bridge - " + username); + super("Downstream Bridge - " + name); } @Override @@ -371,61 +308,59 @@ public class UserConnection extends GenericConnection implements ProxiedPlayer { try { + outer: while (!reconnecting) { byte[] packet = server.in.readPacket(); int id = Util.getId(packet); - if (id == 0xFA) + switch (id) { - // Call the onPluginMessage event - PacketFAPluginMessage message = new PacketFAPluginMessage(packet); - PluginMessageEvent event = new PluginMessageEvent(Destination.CLIENT, instance); - event.setTag(message.tag); - event.setData(new String(message.data)); - BungeeCord.instance.pluginManager.onPluginMessage(event); - - if (event.isCancelled()) - { - continue; - } - - message.tag = event.getTag(); - message.data = event.getData().getBytes(); - - // Allow a message for killing the connection outright - if (message.tag.equals("KillCon")) - { + case 0x00: + trackingPingId = new Packet0KeepAlive(packet).id; + pingTime = System.currentTimeMillis(); break; - } + case 0x03: + Packet3Chat chat = new Packet3Chat(packet); + ChatEvent chatEvent = new ChatEvent(server, UserConnection.this, chat.message); + ProxyServer.getInstance().getPluginManager().callEvent(chatEvent); - if (message.tag.equals("RubberBand")) - { - String server = new String(message.data); - connect(server); + if (chatEvent.isCancelled()) + { + continue; + } break; - } - } else if (id == 0x00) - { - trackingPingId = new Packet0KeepAlive(packet).id; - pingTime = System.currentTimeMillis(); - } else if (id == 0x03) - { - Packet3Chat chat = new Packet3Chat(packet); - String message = chat.message; - ChatEvent chatEvent = new ChatEvent(ChatEvent.Destination.CLIENT, instance); - chatEvent.setText(message); - BungeeCord.instance.pluginManager.onChat(chatEvent); - if (chatEvent.isCancelled()) - { - continue; - } - } else if (id == 0xC9) - { - if (!BungeeCord.instance.tabListHandler.onPacketC9(UserConnection.this, new PacketC9PlayerListItem(packet))) - { - continue; - } + case 0xC9: + PacketC9PlayerListItem playerList = new PacketC9PlayerListItem(packet); + if (!ProxyServer.getInstance().getTabListHandler().onListUpdate(instance, playerList.username, playerList.online, playerList.ping)) + { + continue; + } + break; + case 0xFA: + // Call the onPluginMessage event + PacketFAPluginMessage message = new PacketFAPluginMessage(packet); + PluginMessageEvent event = new PluginMessageEvent(server, UserConnection.this, message.tag, message.data); + ProxyServer.getInstance().getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + continue; + } + + switch (message.tag) + { + case "BungeeCord::Disconnect": + break outer; + case "BungeeCord::Connect": + Server server = ProxyServer.getInstance().getServer(new String(message.data)); + if (server != null) + { + connect(server); + break outer; + } + break; + } } while (!packetQueue.isEmpty()) diff --git a/proxy/src/main/java/net/md_5/bungee/tablist/GlobalTabList.java b/proxy/src/main/java/net/md_5/bungee/tablist/GlobalTabList.java index 08432b5a..ec4e551a 100644 --- a/proxy/src/main/java/net/md_5/bungee/tablist/GlobalTabList.java +++ b/proxy/src/main/java/net/md_5/bungee/tablist/GlobalTabList.java @@ -19,7 +19,7 @@ public class GlobalTabList implements TabListHandler { for (UserConnection c : BungeeCord.getInstance().connections.values()) { - c.packetQueue.add(new PacketC9PlayerListItem(c.tabListName, true, c.getPing())); + c.packetQueue.add(new PacketC9PlayerListItem(c.displayName, true, c.getPing())); } }