From 52dd547863c0cdd22f53f0efcaef11ae096855a0 Mon Sep 17 00:00:00 2001
From: Melanie
Date: Fri, 8 Oct 2010 11:31:52 +0200
Subject: Make SendKillObject send multiple localIDs in one packet. This avoids
 the halting visual behavior of large group deletes and eliminates the packet
 flood

---
 OpenSim/Client/MXP/ClientStack/MXPClientView.cs    |  8 ++++-
 .../Client/VWoHTTP/ClientStack/VWHClientView.cs    |  2 +-
 OpenSim/Framework/IClientAPI.cs                    |  2 +-
 .../Region/ClientStack/LindenUDP/LLClientView.cs   | 41 ++++++++++++++--------
 .../Avatar/Attachments/AttachmentsModule.cs        |  2 +-
 .../EntityTransfer/EntityTransferModule.cs         |  2 +-
 .../Region/Examples/SimpleModule/ComplexObject.cs  |  5 +--
 .../Region/Examples/SimpleModule/MyNpcCharacter.cs |  2 +-
 .../Scenes/AsyncSceneObjectGroupDeleter.cs         |  7 ++++
 OpenSim/Region/Framework/Scenes/Scene.Inventory.cs |  8 +++--
 OpenSim/Region/Framework/Scenes/Scene.cs           | 26 ++++++++------
 .../Framework/Scenes/SceneCommunicationService.cs  |  4 ---
 .../Region/Framework/Scenes/SceneObjectGroup.cs    |  6 +---
 .../Server/IRCClientView.cs                        |  2 +-
 .../ContentManagementSystem/CMModel.cs             |  3 +-
 .../ContentManagementSystem/MetaEntity.cs          |  4 +--
 .../Region/OptionalModules/World/NPC/NPCAvatar.cs  |  2 +-
 .../World/TreePopulator/TreePopulatorModule.cs     |  4 +--
 OpenSim/Tests/Common/Mock/TestClient.cs            |  2 +-
 19 files changed, 79 insertions(+), 53 deletions(-)

diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index 87b99e0..df9d21b 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -897,7 +897,13 @@ namespace OpenSim.Client.MXP.ClientStack
             // Need to translate to MXP somehow
         }
 
-        public void SendKillObject(ulong regionHandle, uint localID)
+        public void SendKillObject(ulong regionHandle, List<uint> localIDs)
+        {
+            foreach (uint localID in localIDs)
+                SendKillObject(regionHandle, localID);
+        }
+
+        private void SendKillObject(ulong regionHandle, uint localID)
         {
             DisappearanceEventMessage de = new DisappearanceEventMessage();
             de.ObjectIndex = localID;
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
index 51c5c17..26be5d9 100644
--- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
+++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
@@ -495,7 +495,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
             throw new System.NotImplementedException();
         }
 
-        public void SendKillObject(ulong regionHandle, uint localID)
+        public void SendKillObject(ulong regionHandle, List<uint> localID)
         {
             throw new System.NotImplementedException();
         }
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 9025dda..51482a1 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -979,7 +979,7 @@ namespace OpenSim.Framework
         /// </summary>
         /// <param name="regionHandle"></param>
         /// <param name="localID"></param>
-        void SendKillObject(ulong regionHandle, uint localID);
+        void SendKillObject(ulong regionHandle, List<uint> localID);
 
         void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
         void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 2b1bd97..fff4300 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -1516,35 +1516,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             OutPacket(pc, ThrottleOutPacketType.Unknown);
         }
 
-        public void SendKillObject(ulong regionHandle, uint localID)
+        public void SendKillObject(ulong regionHandle, List<uint> localIDs)
         {
 //            m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
 
             KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
             // TODO: don't create new blocks if recycling an old packet
-            kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
-            kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
-            kill.ObjectData[0].ID = localID;
+            kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
+            for (int i = 0 ; i < localIDs.Count ; i++ )
+            {
+                kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
+                kill.ObjectData[i].ID = localIDs[i];
+            }
             kill.Header.Reliable = true;
             kill.Header.Zerocoded = true;
 
-            if (m_scene.GetScenePresence(localID) == null)
+            if (localIDs.Count == 1)
             {
-                lock (m_entityUpdates.SyncRoot)
+                if (m_scene.GetScenePresence(localIDs[0]) != null)
                 {
-                    m_killRecord.Add(localID);
-                    
-                    // The throttle queue used here must match that being used for updates.  Otherwise, there is a 
-                    // chance that a kill packet put on a separate queue will be sent to the client before an existing
-                    // update packet on another queue.  Receiving updates after kills results in unowned and undeletable
-                    // scene objects in a viewer until that viewer is relogged in.
-                    OutPacket(kill, ThrottleOutPacketType.Task);
+                    OutPacket(kill, ThrottleOutPacketType.State);
+                    return;
                 }
+                m_killRecord.Add(localIDs[0]);
             }
             else
             {
-                OutPacket(kill, ThrottleOutPacketType.State);
+                lock (m_entityUpdates.SyncRoot)
+                {
+                    foreach (uint localID in localIDs)
+                        m_killRecord.Add(localID);
+                }
             }
+
+            // The throttle queue used here must match that being used for
+            // updates. Otherwise, there is a chance that a kill packet put
+            // on a separate queue will be sent to the client before an
+            // existing update packet on another queue. Receiving updates
+            // after kills results in unowned and undeletable
+            // scene objects in a viewer until that viewer is relogged in.
+            OutPacket(kill, ThrottleOutPacketType.Task);
         }
 
         /// <summary>
@@ -10969,7 +10980,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     {
                         // It's a ghost! tell the client to delete it from view.
                         simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
-                                                 localId);
+                                                 new List<uint>() { localId });
                     }
                     else
                     {
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 87c9100..6ff0ffc 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -616,7 +616,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
                 //
                 if (so.IsSelected)
                 {
-                    m_scene.SendKillObject(so.RootPart.LocalId);
+                    m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId });
                 }
 
                 so.IsSelected = false; // fudge....
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index d506208..2921b0d 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -529,7 +529,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
 
         protected void KillEntity(Scene scene, uint localID)
         {
-            scene.SendKillObject(localID);
+            scene.SendKillObject(new List<uint>() { localID });
         }
 
         protected virtual GridRegion GetFinalDestination(GridRegion region)
diff --git a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs
index e951bef..7a0ce51 100644
--- a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs
+++ b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs
@@ -25,6 +25,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+using System.Collections.Generic;
 using OpenMetaverse;
 using OpenSim.Framework;
 using OpenSim.Region.Framework.Scenes;
@@ -110,7 +111,7 @@ namespace OpenSim.Region.Examples.SimpleModule
         {
             m_parts.Remove(part.UUID);
 
-            remoteClient.SendKillObject(m_regionHandle, part.LocalId);
+            remoteClient.SendKillObject(m_regionHandle, new List<uint>() { part.LocalId} );
             remoteClient.AddMoney(1);
             remoteClient.SendChatMessage("Poof!", 1, AbsolutePosition, "Party Party", UUID.Zero, (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully);
         }
@@ -121,7 +122,7 @@ namespace OpenSim.Region.Examples.SimpleModule
             {
                 m_parts.Remove(m_rootPart.UUID);
                 m_scene.DeleteSceneObject(this, false);
-                remoteClient.SendKillObject(m_regionHandle, m_rootPart.LocalId);
+                remoteClient.SendKillObject(m_regionHandle, new List<uint>() { m_rootPart.LocalId });
                 remoteClient.AddMoney(50);
                 remoteClient.SendChatMessage("KABLAM!!!", 1, AbsolutePosition, "Groupie Groupie", UUID.Zero, (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully);
             }
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 944ad94..db427b4 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -429,7 +429,7 @@ namespace OpenSim.Region.Examples.SimpleModule
 
         }
 
-        public virtual void SendKillObject(ulong regionHandle, uint localID)
+        public virtual void SendKillObject(ulong regionHandle, List<uint> localID)
         {
         }
 
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
index 8feb022..a8d24fd 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -104,8 +104,15 @@ namespace OpenSim.Region.Framework.Scenes
             // better than losing the object for now.
             if (permissionToDelete)
             {
+                List<uint> killIDs = new List<uint>();
+
                 foreach (SceneObjectGroup g in objectGroups)
+                {
+                    killIDs.Add(g.LocalId);
                     g.DeleteGroupFromScene(false);
+                }
+
+                m_scene.SendKillObject(killIDs);
             }
         }
         
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 8b5316a..6d7f984 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1709,7 +1709,7 @@ namespace OpenSim.Region.Framework.Scenes
                 if (part == null)
                 {
                     //Client still thinks the object exists, kill it
-                    SendKillObject(localID);
+                    deleteIDs.Add(localID);
                     continue;
                 }
 
@@ -1717,7 +1717,7 @@ namespace OpenSim.Region.Framework.Scenes
                 if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
                 {
                     //Client still thinks the object exists, kill it
-                    SendKillObject(localID);
+                    deleteIDs.Add(localID);
                     continue;
                 }
 
@@ -1727,8 +1727,8 @@ namespace OpenSim.Region.Framework.Scenes
 
                 SceneObjectGroup grp = part.ParentGroup;
 
-                deleteIDs.Add(localID);
                 deleteGroups.Add(grp);
+                deleteIDs.Add(grp.LocalId);
 
                 if (remoteClient == null)
                 {
@@ -1811,6 +1811,8 @@ namespace OpenSim.Region.Framework.Scenes
                 }
             }
 
+            SendKillObject(deleteIDs);
+
             if (permissionToTake)
             {
                 m_asyncSceneObjectDeleter.DeleteToInventory(
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 76e160d..48ae4ca 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2188,6 +2188,8 @@ namespace OpenSim.Region.Framework.Scenes
             }
 
             group.DeleteGroupFromScene(silent);
+            if (!silent)
+                SendKillObject(new List<uint>() { group.LocalId });
 
 //            m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
         }
@@ -3273,7 +3275,7 @@ namespace OpenSim.Region.Framework.Scenes
                     delegate(IClientAPI client)
                     {
                         //We can safely ignore null reference exceptions.  It means the avatar is dead and cleaned up anyway
-                        try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); }
+                        try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
                         catch (NullReferenceException) { }
                     });
 
@@ -3336,18 +3338,24 @@ namespace OpenSim.Region.Framework.Scenes
 
         #region Entities
 
-        public void SendKillObject(uint localID)
+        public void SendKillObject(List<uint> localIDs)
         {
-            SceneObjectPart part = GetSceneObjectPart(localID);
-            if (part != null) // It is a prim
+            List<uint> deleteIDs = new List<uint>();
+
+            foreach (uint localID in localIDs)
             {
-                if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
+                SceneObjectPart part = GetSceneObjectPart(localID);
+                if (part != null) // It is a prim
                 {
-                    if (part.ParentGroup.RootPart != part) // Child part
-                        return;
+                    if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
+                    {
+                        if (part.ParentGroup.RootPart != part) // Child part
+                            continue;
+                    }
                 }
+                deleteIDs.Add(localID);
             }
-            ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
+            ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
         }
 
         #endregion
@@ -3365,7 +3373,6 @@ namespace OpenSim.Region.Framework.Scenes
             //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
             //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
             m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
-            m_sceneGridService.KiPrimitive += SendKillObject;
             m_sceneGridService.OnGetLandData += GetLandData;
         }
 
@@ -3374,7 +3381,6 @@ namespace OpenSim.Region.Framework.Scenes
         /// </summary>
         public void UnRegisterRegionWithComms()
         {
-            m_sceneGridService.KiPrimitive -= SendKillObject;
             m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
             //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
             //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 1293d5d..632646d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -44,8 +44,6 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
 
 namespace OpenSim.Region.Framework.Scenes
 {
-    public delegate void KiPrimitiveDelegate(uint localID);
-
     public delegate void RemoveKnownRegionsFromAvatarList(UUID avatarID, List<ulong> regionlst);
 
     /// <summary>
@@ -113,8 +111,6 @@ namespace OpenSim.Region.Framework.Scenes
 //        private LogOffUser handlerLogOffUser = null;
 //        private GetLandData handlerGetLandData = null; // OnGetLandData
 
-        public KiPrimitiveDelegate KiPrimitive;
-
         public SceneCommunicationService()
         {
         }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 9a7d560..c870797 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1151,7 +1151,7 @@ namespace OpenSim.Region.Framework.Scenes
                     //
                     if (IsSelected)
                     {
-                        m_scene.SendKillObject(m_rootPart.LocalId);
+                        m_scene.SendKillObject(new List<uint> { m_rootPart.LocalId });
                     }
 
                     IsSelected = false; // fudge....
@@ -1415,11 +1415,7 @@ namespace OpenSim.Region.Framework.Scenes
                         avatar.StandUp();
 
                     if (!silent)
-                    {
                         part.UpdateFlag = 0;
-                        if (part == m_rootPart)
-                            avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
-                    }
                 });
             }
             
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 4ab67aa..72e5ebd 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -947,7 +947,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
             
         }
 
-        public void SendKillObject(ulong regionHandle, uint localID)
+        public void SendKillObject(ulong regionHandle, List<uint> localID)
         {
             
         }
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
index 3a6996e..84c7f29 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
@@ -259,9 +259,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
                     // I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles.
                     ((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup();
                     scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor);
-                    scene.SendKillObject(scene.Entities[uuid].LocalId);
+                    scene.SendKillObject(new List<uint>() { scene.Entities[uuid].LocalId });
                     scene.SceneGraph.DeleteSceneObject(uuid, false);
                     ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroupFromScene(false);
+                    scene.SendKillObject(new List<uint>() { ((SceneObjectGroup)scene.Entities[uuid]).LocalId });
                 }
                 catch(Exception e)
                 {
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
index c7b1ed7..cd60f4b 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
@@ -175,7 +175,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
             //This is important because we are not IN any database.
             //m_Entity.FakeDeleteGroup();
             foreach (SceneObjectPart part in m_Entity.Parts)
-                client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
+                client.SendKillObject(m_Entity.RegionHandle, new List<uint>() { part.LocalId });
         }
 
         /// <summary>
@@ -187,7 +187,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
             {
                 m_Entity.Scene.ForEachClient(
                     delegate(IClientAPI controller)
-                    { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); }
+                    { controller.SendKillObject(m_Entity.RegionHandle, new List<uint>() { part.LocalId }); }
                 );
             }
         }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 1653ecb..3cbe391 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -519,7 +519,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
 
         }
 
-        public virtual void SendKillObject(ulong regionHandle, uint localID)
+        public virtual void SendKillObject(ulong regionHandle, List<uint> localID)
         {
         }
 
diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
index 421da36..2563361 100644
--- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
+++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
@@ -386,7 +386,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
                         m_scene.ForEachClient(delegate(IClientAPI controller)
                         {
                             controller.SendKillObject(m_scene.RegionInfo.RegionHandle,
-                                                      selectedTree.LocalId);
+                                                      new List<uint>() { selectedTree.LocalId });
                         });
                     }
                     else
@@ -727,7 +727,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
                                 m_scene.ForEachClient(delegate(IClientAPI controller)
                                                           {
                                                               controller.SendKillObject(m_scene.RegionInfo.RegionHandle,
-                                                                                        selectedTree.LocalId);
+                                                                                        new List<uint>() { selectedTree.LocalId });
                                                           });
 
                                 break;
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 1c860a7..6324146 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -487,7 +487,7 @@ namespace OpenSim.Tests.Common.Mock
 
         }
 
-        public virtual void SendKillObject(ulong regionHandle, uint localID)
+        public virtual void SendKillObject(ulong regionHandle, List<uint> localID)
         {
         }
 
-- 
cgit v1.1