several changes to lludp FetchInventory
							parent
							
								
									71b5ca95e6
								
							
						
					
					
						commit
						dc225e348d
					
				|  | @ -223,6 +223,8 @@ namespace OpenSim.Framework | |||
|         UUID RayTargetID, | ||||
|         byte RayEndIsIntersection); | ||||
| 
 | ||||
|     public delegate void AgentDataUpdate(IClientAPI remoteClient, UUID itemID, UUID ownerID); | ||||
| 
 | ||||
|     public delegate void RequestGodlikePowers( | ||||
|         UUID AgentID, UUID SessionID, UUID token, bool GodLike); | ||||
| 
 | ||||
|  | @ -252,7 +254,7 @@ namespace OpenSim.Framework | |||
|     public delegate void PurgeInventoryDescendents( | ||||
|         IClientAPI remoteClient, UUID folderID); | ||||
| 
 | ||||
|     public delegate void FetchInventory(IClientAPI remoteClient, UUID itemID, UUID ownerID); | ||||
|     public delegate void FetchInventory(IClientAPI remoteClient, UUID[] items, UUID[] owner); | ||||
| 
 | ||||
|     public delegate void RequestTaskInventory(IClientAPI remoteClient, uint localID); | ||||
| 
 | ||||
|  | @ -846,7 +848,7 @@ namespace OpenSim.Framework | |||
|         event Action<IClientAPI> OnRequestAvatarsData; | ||||
|         event AddNewPrim OnAddPrim; | ||||
| 
 | ||||
|         event FetchInventory OnAgentDataUpdateRequest; | ||||
|         event AgentDataUpdate OnAgentDataUpdateRequest; | ||||
|         event TeleportLocationRequest OnSetStartLocationRequest; | ||||
| 
 | ||||
|         event RequestGodlikePowers OnRequestGodlikePowers; | ||||
|  | @ -1208,7 +1210,7 @@ namespace OpenSim.Framework | |||
|                                         List<InventoryFolderBase> folders, int version, bool fetchFolders, | ||||
|                                         bool fetchItems); | ||||
| 
 | ||||
|         void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item); | ||||
|         void SendInventoryItemDetails(InventoryItemBase[] items); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Tell the client that we have created the item it requested. | ||||
|  |  | |||
|  | @ -136,7 +136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         public event TeleportCancel OnTeleportCancel; | ||||
|         public event RequestAvatarProperties OnRequestAvatarProperties; | ||||
|         public event SetAlwaysRun OnSetAlwaysRun; | ||||
|         public event FetchInventory OnAgentDataUpdateRequest; | ||||
|         public event AgentDataUpdate OnAgentDataUpdateRequest; | ||||
|         public event TeleportLocationRequest OnSetStartLocationRequest; | ||||
|         public event UpdateAvatarProperties OnUpdateAvatarProperties; | ||||
|         public event CreateNewInventoryItem OnCreateNewInventoryItem; | ||||
|  | @ -2496,50 +2496,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             return descend; | ||||
|         } | ||||
| 
 | ||||
|         public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item) | ||||
|         public void SendInventoryItemDetails(InventoryItemBase[] items) | ||||
|         { | ||||
|             // Fudge this value. It's only needed to make the CRC anyway | ||||
|             const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff; | ||||
| 
 | ||||
|             FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply); | ||||
|             // TODO: don't create new blocks if recycling an old packet | ||||
|             inventoryReply.AgentData.AgentID = AgentId; | ||||
|             inventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[1]; | ||||
|             inventoryReply.InventoryData[0] = new FetchInventoryReplyPacket.InventoryDataBlock(); | ||||
|             inventoryReply.InventoryData[0].ItemID = item.ID; | ||||
|             inventoryReply.InventoryData[0].AssetID = item.AssetID; | ||||
|             inventoryReply.InventoryData[0].CreatorID = item.CreatorIdAsUuid; | ||||
|             inventoryReply.InventoryData[0].BaseMask = item.BasePermissions; | ||||
|             inventoryReply.InventoryData[0].CreationDate = item.CreationDate; | ||||
| 
 | ||||
|             inventoryReply.InventoryData[0].Description = Util.StringToBytes256(item.Description); | ||||
|             inventoryReply.InventoryData[0].EveryoneMask = item.EveryOnePermissions; | ||||
|             inventoryReply.InventoryData[0].FolderID = item.Folder; | ||||
|             inventoryReply.InventoryData[0].InvType = (sbyte)item.InvType; | ||||
|             inventoryReply.InventoryData[0].Name = Util.StringToBytes256(item.Name); | ||||
|             inventoryReply.InventoryData[0].NextOwnerMask = item.NextPermissions; | ||||
|             inventoryReply.InventoryData[0].OwnerID = item.Owner; | ||||
|             inventoryReply.InventoryData[0].OwnerMask = item.CurrentPermissions; | ||||
|             inventoryReply.InventoryData[0].Type = (sbyte)item.AssetType; | ||||
|             int total = items.Length; | ||||
|             int count = 0; | ||||
|             for(int i = 0; i < items.Length; ++i) | ||||
|             { | ||||
|                 if(count == 0) | ||||
|                 { | ||||
|                     if(total < 10) | ||||
|                     { | ||||
|                         inventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[total]; | ||||
|                         total = 0; | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         inventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[10]; | ||||
|                         total -= 10; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|             inventoryReply.InventoryData[0].GroupID = item.GroupID; | ||||
|             inventoryReply.InventoryData[0].GroupOwned = item.GroupOwned; | ||||
|             inventoryReply.InventoryData[0].GroupMask = item.GroupPermissions; | ||||
|             inventoryReply.InventoryData[0].Flags = item.Flags; | ||||
|             inventoryReply.InventoryData[0].SalePrice = item.SalePrice; | ||||
|             inventoryReply.InventoryData[0].SaleType = item.SaleType; | ||||
|                 inventoryReply.InventoryData[count] = new FetchInventoryReplyPacket.InventoryDataBlock(); | ||||
|                 FetchInventoryReplyPacket.InventoryDataBlock data = inventoryReply.InventoryData[count]; | ||||
| 
 | ||||
|             inventoryReply.InventoryData[0].CRC = | ||||
|                 Helpers.InventoryCRC( | ||||
|                     1000, 0, inventoryReply.InventoryData[0].InvType, | ||||
|                     inventoryReply.InventoryData[0].Type, inventoryReply.InventoryData[0].AssetID, | ||||
|                     inventoryReply.InventoryData[0].GroupID, 100, | ||||
|                     inventoryReply.InventoryData[0].OwnerID, inventoryReply.InventoryData[0].CreatorID, | ||||
|                     inventoryReply.InventoryData[0].ItemID, inventoryReply.InventoryData[0].FolderID, | ||||
|                     FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, | ||||
|                     FULL_MASK_PERMISSIONS); | ||||
|             inventoryReply.Header.Zerocoded = true; | ||||
|             OutPacket(inventoryReply, ThrottleOutPacketType.Asset); | ||||
|                 data.ItemID = items[i].ID; | ||||
|                 data.AssetID = items[i].AssetID; | ||||
|                 data.CreatorID = items[i].CreatorIdAsUuid; | ||||
|                 data.BaseMask = items[i].BasePermissions; | ||||
|                 data.CreationDate = items[i].CreationDate; | ||||
| 
 | ||||
|                 data.Description = Util.StringToBytes256(items[i].Description); | ||||
|                 data.EveryoneMask = items[i].EveryOnePermissions; | ||||
|                 data.FolderID = items[i].Folder; | ||||
|                 data.InvType = (sbyte)items[i].InvType; | ||||
|                 data.Name = Util.StringToBytes256(items[i].Name); | ||||
|                 data.NextOwnerMask = items[i].NextPermissions; | ||||
|                 data.OwnerID = items[i].Owner; | ||||
|                 data.OwnerMask = items[i].CurrentPermissions; | ||||
|                 data.Type = (sbyte)items[i].AssetType; | ||||
| 
 | ||||
|                 data.GroupID = items[i].GroupID; | ||||
|                 data.GroupOwned = items[i].GroupOwned; | ||||
|                 data.GroupMask = items[i].GroupPermissions; | ||||
|                 data.Flags = items[i].Flags; | ||||
|                 data.SalePrice = items[i].SalePrice; | ||||
|                 data.SaleType = items[i].SaleType; | ||||
| 
 | ||||
|                 data.CRC = Helpers.InventoryCRC( | ||||
|                         1000, 0, data.InvType, data.Type, data.AssetID, | ||||
|                         data.GroupID, 100, data.OwnerID, data.CreatorID, | ||||
|                         data.ItemID, data.FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, | ||||
|                         FULL_MASK_PERMISSIONS); | ||||
| 
 | ||||
|                 ++count; | ||||
|                 if(count == 10 || total == 0) | ||||
|                 { | ||||
|                     inventoryReply.Header.Zerocoded = true; | ||||
|                     OutPacket(inventoryReply, ThrottleOutPacketType.Asset); | ||||
|                     if(total == 0) | ||||
|                         break; | ||||
|                     count = 0; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         protected void SendBulkUpdateInventoryFolder(InventoryFolderBase folderBase) | ||||
|  | @ -10146,11 +10170,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             if (FetchInventoryx.AgentData.SessionID != SessionId || FetchInventoryx.AgentData.AgentID != AgentId) | ||||
|                 return; | ||||
| 
 | ||||
|             for (int i = 0; i < FetchInventoryx.InventoryData.Length; i++) | ||||
|             FetchInventoryPacket.InventoryDataBlock[] data = FetchInventoryx.InventoryData; | ||||
| 
 | ||||
|             UUID[] items = new UUID[data.Length]; | ||||
|             UUID[]  owners = new UUID[data.Length]; | ||||
| 
 | ||||
|             for (int i = 0; i < data.Length; ++i) | ||||
|             { | ||||
|                 OnFetchInventory?.Invoke(this, FetchInventoryx.InventoryData[i].ItemID, | ||||
|                                         FetchInventoryx.InventoryData[i].OwnerID); | ||||
|                 items[i] =data[i].ItemID; | ||||
|                 owners[i] = data[i].OwnerID; | ||||
|             } | ||||
| 
 | ||||
|             OnFetchInventory?.Invoke(this, items, owners); | ||||
|         } | ||||
| 
 | ||||
|         private void HandleFetchInventoryDescendents(Packet Pack) | ||||
|  |  | |||
|  | @ -27,7 +27,8 @@ | |||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Reflection; | ||||
| using System.Collections.Concurrent; | ||||
| //using System.Reflection; | ||||
| using System.Threading; | ||||
| using log4net; | ||||
| using OpenMetaverse; | ||||
|  | @ -39,12 +40,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
|     class FetchHolder | ||||
|     { | ||||
|         public IClientAPI Client { get; private set; } | ||||
|         public UUID ItemID { get; private set; } | ||||
|         public UUID[] Items { get; private set; } | ||||
|         public UUID[] Owners { get; private set; } | ||||
| 
 | ||||
|         public FetchHolder(IClientAPI client, UUID itemID) | ||||
|         public FetchHolder(IClientAPI client, UUID[] items, UUID[] owners) | ||||
|         { | ||||
|             Client = client; | ||||
|             ItemID = itemID; | ||||
|             Items = items; | ||||
|             Owners = owners; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -77,16 +80,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// <summary> | ||||
|         /// Queues fetch requests | ||||
|         /// </summary> | ||||
|         Queue<FetchHolder> m_fetchHolder = new Queue<FetchHolder>(); | ||||
|         private static ConcurrentQueue<FetchHolder> m_fetchHolder = new ConcurrentQueue<FetchHolder>(); | ||||
|         static private object m_threadLock = new object(); | ||||
|         static private bool m_running; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Signal whether a queue is currently being processed or not. | ||||
|         /// </summary> | ||||
|         protected volatile bool m_processing; | ||||
| 
 | ||||
|         public AsyncInventorySender(Scene scene) | ||||
|         { | ||||
|             m_processing = false; | ||||
|             m_scene = scene; | ||||
|         } | ||||
| 
 | ||||
|  | @ -96,20 +98,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// <param name="remoteClient"></param> | ||||
|         /// <param name="itemID"></param> | ||||
|         /// <param name="ownerID"></param> | ||||
|         public void HandleFetchInventory(IClientAPI remoteClient, UUID itemID, UUID ownerID) | ||||
|         public void HandleFetchInventory(IClientAPI remoteClient, UUID[] items, UUID[] owners) | ||||
|         { | ||||
|             lock (m_fetchHolder) | ||||
|             { | ||||
| //                m_log.DebugFormat( | ||||
| //                    "[ASYNC INVENTORY SENDER]: Putting request from {0} for {1} on queue", remoteClient.Name, itemID); | ||||
|                //m_log.DebugFormat( | ||||
|                //     "[ASYNC INVENTORY SENDER]: Putting request from {0} for {1} on queue", remoteClient.Name, itemID); | ||||
| 
 | ||||
|                 m_fetchHolder.Enqueue(new FetchHolder(remoteClient, itemID)); | ||||
|             } | ||||
| 
 | ||||
|             if (!m_processing) | ||||
|             m_fetchHolder.Enqueue(new FetchHolder(remoteClient, items, owners)); | ||||
|             if (Monitor.TryEnter(m_threadLock)) | ||||
|             { | ||||
|                 m_processing = true; | ||||
|                 ProcessQueue(); | ||||
|                 if (!m_running) | ||||
|                 { | ||||
|                     m_running = true; | ||||
|                     Util.FireAndForget(x => ProcessQueue()); | ||||
|                 } | ||||
|                 Monitor.Exit(m_threadLock); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -118,37 +120,42 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// </summary> | ||||
|         protected void ProcessQueue() | ||||
|         { | ||||
|             FetchHolder fh = null; | ||||
| 
 | ||||
|             while (true) | ||||
|             lock(m_threadLock) | ||||
|             { | ||||
|                 lock (m_fetchHolder) | ||||
|                 try | ||||
|                 { | ||||
| //                    m_log.DebugFormat("[ASYNC INVENTORY SENDER]: {0} items left to process", m_fetchHolder.Count); | ||||
|                     while (m_fetchHolder.TryDequeue(out FetchHolder fh)) | ||||
|                     { | ||||
|                         if (!fh.Client.IsActive) | ||||
|                             continue; | ||||
|                         // m_log.DebugFormat( | ||||
|                         //     "[ASYNC INVENTORY SENDER]: Handling request from {0} for {1} on queue", fh.Client.Name, fh.ItemID); | ||||
| 
 | ||||
|                     if (m_fetchHolder.Count == 0) | ||||
|                     { | ||||
|                         m_processing = false; | ||||
|                         return; | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         fh = m_fetchHolder.Dequeue(); | ||||
|                         var items = new List<InventoryItemBase>(); | ||||
|                         for(int i = 0; i < fh.Items.Length; ++i ) | ||||
|                         { | ||||
|                             InventoryItemBase item = m_scene.InventoryService.GetItem(fh.Owners[i], fh.Items[i]); | ||||
|                             if (item == null) | ||||
|                                 continue; | ||||
| 
 | ||||
|                             /* | ||||
|                             if (item.AssetType == (int)AssetType.Link) | ||||
|                             { | ||||
|                                 InventoryItemBase itemlk = m_scene.InventoryService.GetItem(fh.Owners[i], item.AssetID); | ||||
|                                 if(itemlk != null) | ||||
|                                     items.Add(itemlk); | ||||
|                             } | ||||
|                             */ | ||||
| 
 | ||||
|                             items.Add(item); | ||||
|                         } | ||||
| 
 | ||||
|                         fh.Client.SendInventoryItemDetails(items.ToArray()); | ||||
|                          // TODO: Possibly log any failure | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if (!fh.Client.IsActive) | ||||
|                     continue; | ||||
| 
 | ||||
| //                m_log.DebugFormat( | ||||
| //                    "[ASYNC INVENTORY SENDER]: Handling request from {0} for {1} on queue", fh.Client.Name, fh.ItemID); | ||||
| 
 | ||||
|                 InventoryItemBase item = m_scene.InventoryService.GetItem(fh.Client.AgentId, fh.ItemID); | ||||
| 
 | ||||
|                 if (item != null) | ||||
|                     fh.Client.SendInventoryItemDetails(item.Owner, item); | ||||
| 
 | ||||
|                  // TODO: Possibly log any failure | ||||
|                 catch  { } | ||||
|                 m_running = false; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ | |||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Reflection; | ||||
| //using System.Reflection; | ||||
| using System.Threading; | ||||
| using log4net; | ||||
| using OpenMetaverse; | ||||
|  | @ -52,7 +52,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|     /// </summary> | ||||
|     public class AsyncSceneObjectGroupDeleter | ||||
|     { | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         /// <value> | ||||
|         /// Is the deleter currently enabled? | ||||
|         /// </value> | ||||
|  | @ -145,8 +145,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     } | ||||
|                     catch (Exception e) | ||||
|                     { | ||||
|                         m_log.ErrorFormat( | ||||
|                             "[ASYNC OBJECT DELETER]: Exception background sending object: {0}{1}", e.Message, e.StackTrace); | ||||
|                         //m_log.ErrorFormat( | ||||
|                         //    "[ASYNC OBJECT DELETER]: Exception background sending object: {0}{1}", e.Message, e.StackTrace); | ||||
|                     } | ||||
|                 } | ||||
|                 // m_log.Debug("[ASYNC DELETER]: No objects left in inventory send queue."); | ||||
|  |  | |||
|  | @ -714,7 +714,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
|         public event AvatarPickerRequest OnAvatarPickerRequest; | ||||
|         public event Action<IClientAPI> OnRequestAvatarsData; | ||||
|         public event AddNewPrim OnAddPrim; | ||||
|         public event FetchInventory OnAgentDataUpdateRequest; | ||||
|         public event AgentDataUpdate OnAgentDataUpdateRequest; | ||||
|         public event TeleportLocationRequest OnSetStartLocationRequest; | ||||
|         public event RequestGodlikePowers OnRequestGodlikePowers; | ||||
|         public event GodKickUser OnGodKickUser; | ||||
|  | @ -1124,7 +1124,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item) | ||||
|         public void SendInventoryItemDetails(InventoryItemBase[] items) | ||||
|         { | ||||
| 
 | ||||
|         } | ||||
|  |  | |||
|  | @ -348,7 +348,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
|         public event SpinStop OnSpinStop; | ||||
|         public event ViewerEffectEventHandler OnViewerEffect; | ||||
| 
 | ||||
|         public event FetchInventory OnAgentDataUpdateRequest; | ||||
|         public event AgentDataUpdate OnAgentDataUpdateRequest; | ||||
|         public event TeleportLocationRequest OnSetStartLocationRequest; | ||||
| 
 | ||||
|         public event UpdateShape OnUpdatePrimShape; | ||||
|  | @ -847,7 +847,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item) | ||||
|         public virtual void SendInventoryItemDetails(InventoryItemBase[] items) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -141,7 +141,7 @@ namespace OpenSim.Tests.Common | |||
|         public event SpinStop OnSpinStop; | ||||
|         public event ViewerEffectEventHandler OnViewerEffect; | ||||
| 
 | ||||
|         public event FetchInventory OnAgentDataUpdateRequest; | ||||
|         public event AgentDataUpdate OnAgentDataUpdateRequest; | ||||
|         public event TeleportLocationRequest OnSetStartLocationRequest; | ||||
| 
 | ||||
|         public event UpdateShape OnUpdatePrimShape; | ||||
|  | @ -796,7 +796,7 @@ namespace OpenSim.Tests.Common | |||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item) | ||||
|         public virtual void SendInventoryItemDetails(InventoryItemBase[] items) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 UbitUmarov
						UbitUmarov