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 9652efd5..39382dcf 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 @@ -120,21 +120,6 @@ 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); - /** * Get the currently in use reconnect handler. * diff --git a/api/src/main/java/net/md_5/bungee/api/TabListHandler.java b/api/src/main/java/net/md_5/bungee/api/TabListHandler.java index e4db4e6f..d3673c6d 100644 --- a/api/src/main/java/net/md_5/bungee/api/TabListHandler.java +++ b/api/src/main/java/net/md_5/bungee/api/TabListHandler.java @@ -1,23 +1,29 @@ package net.md_5.bungee.api; +import lombok.Data; import net.md_5.bungee.api.connection.ProxiedPlayer; -public interface TabListHandler +@Data +public abstract class TabListHandler { + private final ProxiedPlayer player; + + /** + * Called when this player first connects to the proxy. + */ + public void onConnect() + { + } + /** * Called when a player first connects to the proxy. * * @param player the connecting player */ - public void onConnect(ProxiedPlayer player); - - /** - * Called when a player changes their connected server. - * - * @param player the player who changed servers - */ - public void onServerChange(ProxiedPlayer player); + public void onServerChange() + { + } /** * Called when a players ping changes. The new ping will have not updated in @@ -26,14 +32,18 @@ public interface TabListHandler * @param player the player who's ping changed * @param ping the player's new ping. */ - public void onPingChange(ProxiedPlayer player, int ping); + public void onPingChange(int ping) + { + } /** * Called when a player disconnects. * * @param player the disconnected player */ - public void onDisconnect(ProxiedPlayer player); + public void onDisconnect() + { + } /** * Called when a list update packet is sent from server to client. @@ -44,5 +54,5 @@ public interface TabListHandler * @param ping ping of the subject player * @return whether to send the packet to the client */ - public boolean onListUpdate(ProxiedPlayer player, String name, boolean online, int ping); + public abstract boolean onListUpdate(String name, boolean online, int ping); } diff --git a/api/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java b/api/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java index af4999fd..d5e8dffb 100644 --- a/api/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java +++ b/api/src/main/java/net/md_5/bungee/api/config/ListenerInfo.java @@ -3,6 +3,7 @@ package net.md_5.bungee.api.config; import java.net.InetSocketAddress; import java.util.Map; import lombok.Data; +import net.md_5.bungee.api.TabListHandler; /** * Class representing the configuration of a server listener. Used for allowing @@ -52,4 +53,8 @@ public class ListenerInfo * null. */ private final TexturePackInfo texturePack; + /** + * Class used to build tab lists for this player. + */ + private final Class tabList; } diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java index 525795e1..912ff665 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -96,12 +96,6 @@ public class BungeeCord extends ProxyServer */ private final Map connections = new CaseInsensitiveMap<>(); private final ReadWriteLock connectionLock = new ReentrantReadWriteLock(); - /** - * Tab list handler - */ - @Getter - @Setter - public TabListHandler tabListHandler; /** * Plugin manager. */ diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java index 001839b0..776cb39f 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -154,7 +154,7 @@ public class ServerConnector extends PacketHandler user.unsafe().sendPacket( modLogin ); } else { - bungee.getTabListHandler().onServerChange( user ); + user.getTabList().onServerChange(); Scoreboard serverScoreboard = user.getServerSentScoreboard(); for ( Objective objective : serverScoreboard.getObjectives() ) 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 58d01b1f..aef25eba 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -21,6 +21,7 @@ import lombok.RequiredArgsConstructor; import lombok.Setter; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.TabListHandler; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.config.TexturePackInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -62,6 +63,8 @@ public final class UserConnection implements ProxiedPlayer private final Collection pendingConnects = new HashSet<>(); /*========================================================================*/ @Getter + private TabListHandler tabList; + @Getter @Setter private int sentPingId; @Getter @@ -101,6 +104,13 @@ public final class UserConnection implements ProxiedPlayer public void init() { this.displayName = name; + try + { + this.tabList = getPendingConnection().getListener().getTabList().getDeclaredConstructor( ProxiedPlayer.class ).newInstance( this ); + } catch ( ReflectiveOperationException ex ) + { + throw new RuntimeException( ex ); + } Collection g = bungee.getConfigurationAdapter().getGroups( name ); for ( String s : g ) @@ -125,9 +135,9 @@ public final class UserConnection implements ProxiedPlayer { Preconditions.checkNotNull( name, "displayName" ); Preconditions.checkArgument( name.length() <= 16, "Display name cannot be longer than 16 characters" ); - bungee.getTabListHandler().onDisconnect( this ); + getTabList().onDisconnect(); displayName = name; - bungee.getTabListHandler().onConnect( this ); + getTabList().onConnect(); } @Override diff --git a/proxy/src/main/java/net/md_5/bungee/config/Configuration.java b/proxy/src/main/java/net/md_5/bungee/config/Configuration.java index 848cb7ed..fff03e34 100644 --- a/proxy/src/main/java/net/md_5/bungee/config/Configuration.java +++ b/proxy/src/main/java/net/md_5/bungee/config/Configuration.java @@ -22,14 +22,7 @@ import net.md_5.bungee.util.CaseInsensitiveMap; public class Configuration { - /** - * The default tab list options available for picking. - */ - private enum DefaultTabList - { - GLOBAL, GLOBAL_PING, SERVER; - } /** * Time before users are disconnected due to no network activity. */ @@ -62,24 +55,6 @@ public class Configuration onlineMode = adapter.getBoolean( "online_mode", onlineMode ); playerLimit = adapter.getInt( "player_limit", playerLimit ); - DefaultTabList tab = DefaultTabList.valueOf( adapter.getString( "tab_list", "GLOBAL_PING" ) ); - if ( tab == null ) - { - tab = DefaultTabList.GLOBAL_PING; - } - switch ( tab ) - { - case GLOBAL: - ProxyServer.getInstance().setTabListHandler( new Global() ); - break; - case GLOBAL_PING: - ProxyServer.getInstance().setTabListHandler( new GlobalPing() ); - break; - case SERVER: - ProxyServer.getInstance().setTabListHandler( new ServerUnique() ); - break; - } - listeners = adapter.getListeners(); Preconditions.checkArgument( listeners != null && !listeners.isEmpty(), "No listeners defined." ); diff --git a/proxy/src/main/java/net/md_5/bungee/config/YamlConfig.java b/proxy/src/main/java/net/md_5/bungee/config/YamlConfig.java index 878ac767..6e8d577c 100644 --- a/proxy/src/main/java/net/md_5/bungee/config/YamlConfig.java +++ b/proxy/src/main/java/net/md_5/bungee/config/YamlConfig.java @@ -14,13 +14,18 @@ import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.logging.Level; +import lombok.RequiredArgsConstructor; import net.md_5.bungee.Util; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.TabListHandler; import net.md_5.bungee.api.config.ConfigurationAdapter; import net.md_5.bungee.api.config.ListenerInfo; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.config.TexturePackInfo; +import net.md_5.bungee.tablist.Global; +import net.md_5.bungee.tablist.GlobalPing; +import net.md_5.bungee.tablist.ServerUnique; import net.md_5.bungee.util.CaseInsensitiveMap; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -28,6 +33,16 @@ import org.yaml.snakeyaml.Yaml; public class YamlConfig implements ConfigurationAdapter { + /** + * The default tab list options available for picking. + */ + @RequiredArgsConstructor + private enum DefaultTabList + { + + GLOBAL( Global.class ), GLOBAL_PING( GlobalPing.class ), SERVER( ServerUnique.class ); + private final Class clazz; + } private Yaml yaml; private Map config; private final File file = new File( "config.yml" ); @@ -194,7 +209,14 @@ public class YamlConfig implements ConfigurationAdapter String textureURL = get( "texture_url", null, val ); int textureSize = get( "texture_size", 16, val ); TexturePackInfo texture = ( textureURL == null ) ? null : new TexturePackInfo( textureURL, textureSize ); - ListenerInfo info = new ListenerInfo( address, motd, maxPlayers, tabListSize, defaultServer, fallbackServer, forceDefault, forced, texture ); + String tabListName = get( "tab_list", "GLOBAL_PING", val ); + DefaultTabList value = DefaultTabList.valueOf( tabListName.toUpperCase() ); + if ( value == null ) + { + value = DefaultTabList.GLOBAL_PING; + } + + ListenerInfo info = new ListenerInfo( address, motd, maxPlayers, tabListSize, defaultServer, fallbackServer, forceDefault, forced, texture, value.clazz ); ret.add( info ); } diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java index 926ba7bd..af7c20b9 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java @@ -86,7 +86,7 @@ public class DownstreamBridge extends PacketHandler public void handle(PacketC9PlayerListItem playerList) throws Exception { - if ( !bungee.getTabListHandler().onListUpdate( con, playerList.getUsername(), playerList.isOnline(), playerList.getPing() ) ) + if ( !con.getTabList().onListUpdate( playerList.getUsername(), playerList.isOnline(), playerList.getPing() ) ) { throw new CancelSendSignal(); } @@ -161,9 +161,9 @@ public class DownstreamBridge extends PacketHandler t.setDisplayName( team.getDisplayName() ); t.setPrefix( team.getPrefix() ); t.setSuffix( team.getSuffix() ); - t.setFriendlyFire(team.isFriendlyFire() ); + t.setFriendlyFire( team.isFriendlyFire() ); } - if ( team.getPlayers()!= null ) + if ( team.getPlayers() != null ) { for ( String s : team.getPlayers() ) { diff --git a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java index 168034b0..941485fc 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java @@ -28,7 +28,7 @@ public class UpstreamBridge extends PacketHandler this.con = con; BungeeCord.getInstance().addConnection( con ); - bungee.getTabListHandler().onConnect( con ); + con.getTabList().onConnect(); con.unsafe().sendPacket( BungeeCord.getInstance().registerChannels() ); TexturePackInfo texture = con.getPendingConnection().getListener().getTexturePack(); @@ -50,7 +50,7 @@ public class UpstreamBridge extends PacketHandler // We lost connection to the client PlayerDisconnectEvent event = new PlayerDisconnectEvent( con ); bungee.getPluginManager().callEvent( event ); - bungee.getTabListHandler().onDisconnect( con ); + con.getTabList().onDisconnect(); BungeeCord.getInstance().removeConnection( con ); if ( con.getServer() != null ) @@ -75,7 +75,7 @@ public class UpstreamBridge extends PacketHandler if ( alive.getRandomId() == con.getSentPingId() ) { int newPing = (int) ( System.currentTimeMillis() - con.getSentPingTime() ); - bungee.getTabListHandler().onPingChange( con, newPing ); + con.getTabList().onPingChange( newPing ); con.setPing( newPing ); } } diff --git a/proxy/src/main/java/net/md_5/bungee/tablist/Global.java b/proxy/src/main/java/net/md_5/bungee/tablist/Global.java index 0d40e846..db6c4767 100644 --- a/proxy/src/main/java/net/md_5/bungee/tablist/Global.java +++ b/proxy/src/main/java/net/md_5/bungee/tablist/Global.java @@ -1,52 +1,49 @@ package net.md_5.bungee.tablist; -import java.util.Collection; -import java.util.HashSet; import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.TabListHandler; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem; -public class Global implements TabListHandler +public class Global extends TabListHandler { - private final Collection sentPings = new HashSet<>(); + private boolean sentPing; + + public Global(ProxiedPlayer player) + { + super( player ); + } @Override - public void onConnect(ProxiedPlayer player) + public void onConnect() { for ( ProxiedPlayer p : ProxyServer.getInstance().getPlayers() ) { - player.unsafe().sendPacket( new PacketC9PlayerListItem( p.getDisplayName(), true, (short) p.getPing() ) ); + getPlayer().unsafe().sendPacket( new PacketC9PlayerListItem( p.getDisplayName(), true, (short) p.getPing() ) ); } - BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( player.getDisplayName(), true, (short) player.getPing() ) ); + BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( getPlayer().getDisplayName(), true, (short) getPlayer().getPing() ) ); } @Override - public void onPingChange(ProxiedPlayer player, int ping) + public void onPingChange(int ping) { - if ( !sentPings.contains( player ) ) + if ( !sentPing ) { - BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( player.getDisplayName(), true, (short) player.getPing() ) ); - sentPings.add( player ); + sentPing = true; + BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( getPlayer().getDisplayName(), true, (short) getPlayer().getPing() ) ); } } @Override - public void onDisconnect(ProxiedPlayer player) + public void onDisconnect() { - BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( player.getDisplayName(), false, (short) 9999 ) ); - sentPings.remove( player ); + BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( getPlayer().getDisplayName(), false, (short) 9999 ) ); } @Override - public void onServerChange(ProxiedPlayer player) - { - } - - @Override - public boolean onListUpdate(ProxiedPlayer player, String name, boolean online, int ping) + public boolean onListUpdate(String name, boolean online, int ping) { return false; } diff --git a/proxy/src/main/java/net/md_5/bungee/tablist/GlobalPing.java b/proxy/src/main/java/net/md_5/bungee/tablist/GlobalPing.java index 8aaa0a77..24f4c05d 100644 --- a/proxy/src/main/java/net/md_5/bungee/tablist/GlobalPing.java +++ b/proxy/src/main/java/net/md_5/bungee/tablist/GlobalPing.java @@ -1,7 +1,5 @@ package net.md_5.bungee.tablist; -import gnu.trove.map.TObjectIntMap; -import gnu.trove.map.hash.TObjectIntHashMap; import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem; @@ -10,23 +8,21 @@ public class GlobalPing extends Global { private static final int PING_THRESHOLD = 20; - private final TObjectIntMap lastPings = new TObjectIntHashMap<>(); + /*========================================================================*/ + private int lastPing; - @Override - public void onDisconnect(ProxiedPlayer player) + public GlobalPing(ProxiedPlayer player) { - lastPings.remove( player ); - super.onDisconnect( player ); + super( player ); } @Override - public void onPingChange(ProxiedPlayer player, int ping) + public void onPingChange(int ping) { - int lastPing = lastPings.get( player ); if ( ping - PING_THRESHOLD > lastPing && ping + PING_THRESHOLD < lastPing ) { - BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( player.getDisplayName(), true, (short) ping ) ); - lastPings.put( player, ping ); + lastPing = ping; + BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( getPlayer().getDisplayName(), true, (short) ping ) ); } } } diff --git a/proxy/src/main/java/net/md_5/bungee/tablist/ServerUnique.java b/proxy/src/main/java/net/md_5/bungee/tablist/ServerUnique.java index 184f0d31..505e1edc 100644 --- a/proxy/src/main/java/net/md_5/bungee/tablist/ServerUnique.java +++ b/proxy/src/main/java/net/md_5/bungee/tablist/ServerUnique.java @@ -1,58 +1,43 @@ package net.md_5.bungee.tablist; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; import java.util.Collection; -import net.md_5.bungee.UserConnection; +import java.util.HashSet; import net.md_5.bungee.api.TabListHandler; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem; -public class ServerUnique implements TabListHandler +public class ServerUnique extends TabListHandler { - private final Multimap sentUsernames = Multimaps.synchronizedMultimap( HashMultimap.create() ); + private final Collection usernames = new HashSet<>(); - @Override - public void onConnect(ProxiedPlayer player) + public ServerUnique(ProxiedPlayer player) { + super( player ); } @Override - public void onPingChange(ProxiedPlayer player, int ping) + public void onServerChange() { - } - - @Override - public void onDisconnect(ProxiedPlayer player) - { - sentUsernames.removeAll( player ); - } - - @Override - public void onServerChange(ProxiedPlayer player) - { - Collection usernames = sentUsernames.get( player ); - synchronized ( sentUsernames ) + synchronized ( usernames ) { for ( String username : usernames ) { - player.unsafe().sendPacket( new PacketC9PlayerListItem( username, false, (short) 9999 ) ); + getPlayer().unsafe().sendPacket( new PacketC9PlayerListItem( username, false, (short) 9999 ) ); } usernames.clear(); } } @Override - public boolean onListUpdate(ProxiedPlayer player, String name, boolean online, int ping) + public boolean onListUpdate(String name, boolean online, int ping) { if ( online ) { - sentUsernames.put( player, name ); + usernames.add( name ); } else { - sentUsernames.remove( player, name ); + usernames.remove( name ); } return true;