[Breaking] Close #423 by making tab list per listener.

This commit is contained in:
md_5 2013-06-08 13:13:17 +10:00
parent b5aecd5dcc
commit b75a2b5060
13 changed files with 104 additions and 125 deletions

View File

@ -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.
*

View File

@ -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);
}

View File

@ -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<? extends TabListHandler> tabList;
}

View File

@ -96,12 +96,6 @@ public class BungeeCord extends ProxyServer
*/
private final Map<String, UserConnection> connections = new CaseInsensitiveMap<>();
private final ReadWriteLock connectionLock = new ReentrantReadWriteLock();
/**
* Tab list handler
*/
@Getter
@Setter
public TabListHandler tabListHandler;
/**
* Plugin manager.
*/

View File

@ -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() )

View File

@ -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<ServerInfo> 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<String> 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

View File

@ -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." );

View File

@ -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<? extends TabListHandler> 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 );
}

View File

@ -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();
}

View File

@ -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 );
}
}

View File

@ -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<ProxiedPlayer> 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;
}

View File

@ -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<ProxiedPlayer> 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 ) );
}
}
}

View File

@ -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<ProxiedPlayer, String> sentUsernames = Multimaps.synchronizedMultimap( HashMultimap.<ProxiedPlayer, String>create() );
private final Collection<String> 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<String> 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;