From bc234a2be957b71eb450ac5dd007ed1b9725fd23 Mon Sep 17 00:00:00 2001
From: Howaner <franzi.moos@googlemail.com>
Date: Tue, 10 Feb 2015 19:07:21 +0100
Subject: [PATCH] Fixed tab list bugs

---
 .../main/java/net/md_5/bungee/ServerConnector.java |   9 +-
 .../md_5/bungee/connection/DownstreamBridge.java   |   2 +-
 .../src/main/java/net/md_5/bungee/tab/Global.java  |  11 +-
 .../java/net/md_5/bungee/tab/ServerUnique.java     | 119 +++++++++++++--------
 .../src/main/java/net/md_5/bungee/tab/TabList.java |   8 +-
 5 files changed, 95 insertions(+), 54 deletions(-)

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 aa4c5e6..f184900 100644
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
@@ -118,6 +118,11 @@ public class ServerConnector extends PacketHandler
         ch.setProtocol( Protocol.GAME );
         thisState = State.LOGIN;
 
+        if ( user.getServer() != null )
+        {
+            user.getTabListHandler().onServerChange( user.getServer() );
+        }
+
         // Only reset the Forge client when:
         // 1) The user is switching servers (so has a current server)
         // 2) The handshake is complete
@@ -207,8 +212,6 @@ public class ServerConnector extends PacketHandler
             }
         } else
         {
-            user.getTabListHandler().onServerChange();
-
             Scoreboard serverScoreboard = user.getServerSentScoreboard();
             for ( Objective objective : serverScoreboard.getObjectives() )
             {
@@ -228,6 +231,8 @@ public class ServerConnector extends PacketHandler
             // Remove from old servers
             user.getServer().setObsolete( true );
             user.getServer().disconnect( "Quitting" );
+
+            user.getTabListHandler().onServerChanged();
         }
 
         // TODO: Fix this?
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 d5f345a..9a69349 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
@@ -97,7 +97,7 @@ public class DownstreamBridge extends PacketHandler
     @Override
     public void handle(PlayerListItem playerList) throws Exception
     {
-        con.getTabListHandler().onUpdate( TabList.rewrite( playerList ) );
+        con.getTabListHandler().onUpdate( TabList.rewrite( playerList ), this.server );
         throw CancelSendSignal.INSTANCE; // Always throw because of profile rewriting
     }
 
diff --git a/proxy/src/main/java/net/md_5/bungee/tab/Global.java b/proxy/src/main/java/net/md_5/bungee/tab/Global.java
index ecd8ff0..dd39073 100644
--- a/proxy/src/main/java/net/md_5/bungee/tab/Global.java
+++ b/proxy/src/main/java/net/md_5/bungee/tab/Global.java
@@ -10,6 +10,7 @@ import net.md_5.bungee.protocol.ProtocolConstants;
 import net.md_5.bungee.protocol.packet.PlayerListItem;
 
 import java.util.Collection;
+import net.md_5.bungee.ServerConnection;
 
 public class Global extends TabList
 {
@@ -22,7 +23,7 @@ public class Global extends TabList
     }
 
     @Override
-    public void onUpdate(PlayerListItem playerListItem)
+    public void onUpdate(PlayerListItem playerListItem, ServerConnection server)
     {
 
     }
@@ -49,7 +50,13 @@ public class Global extends TabList
     }
 
     @Override
-    public void onServerChange()
+    public void onServerChange(ServerConnection oldServer)
+    {
+
+    }
+
+    @Override
+    public void onServerChanged()
     {
 
     }
diff --git a/proxy/src/main/java/net/md_5/bungee/tab/ServerUnique.java b/proxy/src/main/java/net/md_5/bungee/tab/ServerUnique.java
index 60e5914..4deadc8 100644
--- a/proxy/src/main/java/net/md_5/bungee/tab/ServerUnique.java
+++ b/proxy/src/main/java/net/md_5/bungee/tab/ServerUnique.java
@@ -1,8 +1,10 @@
 package net.md_5.bungee.tab;
 
+import java.lang.ref.WeakReference;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.UUID;
+import net.md_5.bungee.ServerConnection;
 
 import net.md_5.bungee.api.connection.ProxiedPlayer;
 import net.md_5.bungee.protocol.ProtocolConstants;
@@ -11,6 +13,8 @@ import net.md_5.bungee.protocol.packet.PlayerListItem;
 public class ServerUnique extends TabList
 {
 
+    private final Object sync = new Object();
+    private WeakReference<ServerConnection> ignoredServer;
     private final Collection<UUID> uuids = new HashSet<>();
     private final Collection<String> usernames = new HashSet<>(); // Support for <=1.7.9
 
@@ -20,31 +24,39 @@ public class ServerUnique extends TabList
     }
 
     @Override
-    public void onUpdate(PlayerListItem playerListItem)
+    public void onUpdate(PlayerListItem playerListItem, ServerConnection server)
     {
-        for ( PlayerListItem.Item item : playerListItem.getItems() )
+        synchronized ( sync )
         {
-            if ( playerListItem.getAction() == PlayerListItem.Action.ADD_PLAYER )
+            if ( this.ignoredServer != null && this.ignoredServer.get() == server )
             {
-                if ( item.getUuid() != null )
-                {
-                    uuids.add( item.getUuid() );
-                } else
-                {
-                    usernames.add( item.getUsername() );
-                }
-            } else if ( playerListItem.getAction() == PlayerListItem.Action.REMOVE_PLAYER )
+                return;
+            }
+
+            for ( PlayerListItem.Item item : playerListItem.getItems() )
             {
-                if ( item.getUuid() != null )
+                if ( playerListItem.getAction() == PlayerListItem.Action.ADD_PLAYER )
                 {
-                    uuids.remove( item.getUuid() );
-                } else
+                    if ( item.getUuid() != null )
+                    {
+                        uuids.add( item.getUuid() );
+                    } else
+                    {
+                        usernames.add( item.getUsername() );
+                    }
+                } else if ( playerListItem.getAction() == PlayerListItem.Action.REMOVE_PLAYER )
                 {
-                    usernames.remove( item.getUsername() );
+                    if ( item.getUuid() != null )
+                    {
+                        uuids.remove( item.getUuid() );
+                    } else
+                    {
+                        usernames.remove( item.getUsername() );
+                    }
                 }
             }
+            player.unsafe().sendPacket( playerListItem );
         }
-        player.unsafe().sendPacket( playerListItem );
     }
 
     @Override
@@ -54,44 +66,57 @@ public class ServerUnique extends TabList
     }
 
     @Override
-    public void onServerChange()
+    public void onServerChange(ServerConnection oldServer)
     {
-        PlayerListItem packet = new PlayerListItem();
-        packet.setAction( PlayerListItem.Action.REMOVE_PLAYER );
-        PlayerListItem.Item[] items = new PlayerListItem.Item[ uuids.size() + usernames.size() ];
-        int i = 0;
-        for ( UUID uuid : uuids )
-        {
-            PlayerListItem.Item item = items[i++] = new PlayerListItem.Item();
-            item.setUuid( uuid );
-        }
-        for ( String username : usernames )
-        {
-            PlayerListItem.Item item = items[i++] = new PlayerListItem.Item();
-            item.setUsername( username );
-            item.setDisplayName( username );
-        }
-        packet.setItems( items );
-        if ( player.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_SNAPSHOT )
-        {
-            player.unsafe().sendPacket( packet );
-        } else
+        this.ignoredServer = new WeakReference<>(oldServer);
+    }
+
+    @Override
+    public void onServerChanged()
+    {
+        synchronized ( sync )
         {
-            // Split up the packet
-            for ( PlayerListItem.Item item : packet.getItems() )
+            PlayerListItem packet = new PlayerListItem();
+            packet.setAction( PlayerListItem.Action.REMOVE_PLAYER );
+
+            PlayerListItem.Item[] items = new PlayerListItem.Item[ uuids.size() + usernames.size() ];
+
+            int i = 0;
+            for ( UUID uuid : uuids )
+            {
+                PlayerListItem.Item item = items[i++] = new PlayerListItem.Item();
+                item.setUuid( uuid );
+            }
+            for ( String username : usernames )
             {
-                PlayerListItem p2 = new PlayerListItem();
-                p2.setAction( packet.getAction() );
+                PlayerListItem.Item item = items[i++] = new PlayerListItem.Item();
+                item.setUsername( username );
+                item.setDisplayName( username );
+            }
+            packet.setItems( items );
 
-                p2.setItems( new PlayerListItem.Item[]
+            if ( player.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_SNAPSHOT )
+            {
+                player.unsafe().sendPacket( packet );
+            } else
+            {
+                // Split up the packet
+                for ( PlayerListItem.Item item : packet.getItems() )
                 {
-                    item
-                } );
-                player.unsafe().sendPacket( p2 );
+                    PlayerListItem p2 = new PlayerListItem();
+                    p2.setAction( packet.getAction() );
+
+                    p2.setItems( new PlayerListItem.Item[]
+                    {
+                        item
+                    } );
+                    player.unsafe().sendPacket( p2 );
+                }
             }
+
+            uuids.clear();
+            usernames.clear();
         }
-        uuids.clear();
-        usernames.clear();
     }
 
     @Override
diff --git a/proxy/src/main/java/net/md_5/bungee/tab/TabList.java b/proxy/src/main/java/net/md_5/bungee/tab/TabList.java
index bab75b1..48d326c 100644
--- a/proxy/src/main/java/net/md_5/bungee/tab/TabList.java
+++ b/proxy/src/main/java/net/md_5/bungee/tab/TabList.java
@@ -2,6 +2,7 @@ package net.md_5.bungee.tab;
 
 import lombok.RequiredArgsConstructor;
 import net.md_5.bungee.BungeeCord;
+import net.md_5.bungee.ServerConnection;
 import net.md_5.bungee.UserConnection;
 import net.md_5.bungee.api.connection.ProxiedPlayer;
 import net.md_5.bungee.connection.LoginResult;
@@ -13,11 +14,13 @@ public abstract class TabList
 
     protected final ProxiedPlayer player;
 
-    public abstract void onUpdate(PlayerListItem playerListItem);
+    public abstract void onUpdate(PlayerListItem playerListItem, ServerConnection server);
 
     public abstract void onPingChange(int ping);
 
-    public abstract void onServerChange();
+    public abstract void onServerChange(ServerConnection oldServer);
+
+    public abstract void onServerChanged();
 
     public abstract void onConnect();
 
@@ -31,6 +34,7 @@ public abstract class TabList
             {
                 continue;
             }
+
             UserConnection player = BungeeCord.getInstance().getPlayerByOfflineUUID( item.getUuid() );
             if ( player != null )
             {
-- 
1.9.1

