From 095e602c4ac6da315f3f6711e24f034b6c490a02 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Tue, 12 Apr 2011 12:36:36 -0700 Subject: First pass at moving object property requests into a queue similar to the entity update queue. The number of property packets can become significant when selecting/deselecting large numbers of objects. This is experimental code. --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 4 +- .../Client/VWoHTTP/ClientStack/VWHClientView.cs | 4 +- OpenSim/Framework/IClientAPI.cs | 39 +-- .../Region/ClientStack/LindenUDP/LLClientView.cs | 351 +++++++++++++-------- .../Region/ClientStack/LindenUDP/PriorityQueue.cs | 12 +- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 12 +- .../Region/Framework/Scenes/SceneObjectGroup.cs | 10 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 10 +- .../Server/IRCClientView.cs | 5 +- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 12 +- OpenSim/Tests/Common/Mock/TestClient.cs | 11 +- 11 files changed, 262 insertions(+), 208 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index d1a0440..a604a2e 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -1337,12 +1337,12 @@ namespace OpenSim.Client.MXP.ClientStack // Need to translate to MXP somehow } - public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, UUID LastOwnerID, string ObjectName, string Description) + public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) { //throw new System.NotImplementedException(); } - public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, byte saleType, int salePrice) + public void SendObjectPropertiesReply(ISceneEntity entity) { //throw new System.NotImplementedException(); } diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index fc27f01..d8cd0ac 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -884,12 +884,12 @@ namespace OpenSim.Client.VWoHTTP.ClientStack throw new System.NotImplementedException(); } - public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, UUID LastOwnerID, string ObjectName, string Description) + public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) { throw new System.NotImplementedException(); } - public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, byte saleType, int salePrice) + public void SendObjectPropertiesReply(ISceneEntity entity) { throw new System.NotImplementedException(); } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 5bf0b7b..c56a756 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -570,16 +570,30 @@ namespace OpenSim.Framework public float dwell; } - public class EntityUpdate + public class IEntityUpdate { public ISceneEntity Entity; - public PrimUpdateFlags Flags; - public float TimeDilation; + public uint Flags; - public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) + public IEntityUpdate(ISceneEntity entity, uint flags) { Entity = entity; Flags = flags; + } + } + + + public class EntityUpdate : IEntityUpdate + { + // public ISceneEntity Entity; + // public PrimUpdateFlags Flags; + public float TimeDilation; + + public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) + : base(entity,(uint)flags) + { + //Entity = entity; + // Flags = flags; TimeDilation = timedilation; } } @@ -1211,20 +1225,9 @@ namespace OpenSim.Framework /// void SendSimStats(SimStats stats); - void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, - uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, - uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, - uint Category, - UUID LastOwnerID, string ObjectName, string Description); - - void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, - UUID FromTaskUUID, - UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, - UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, - string ItemName, - string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, - uint EveryoneMask, - uint BaseMask, byte saleType, int salePrice); + void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags); + + void SendObjectPropertiesReply(ISceneEntity Entity); void SendAgentOffline(UUID[] agentIDs); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 934a2d5..b96343e 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -386,6 +386,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_cachedTextureSerial; private PriorityQueue m_entityUpdates; + private PriorityQueue m_entityProps; private Prioritizer m_prioritizer; private bool m_disableFacelights = false; @@ -433,9 +434,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected IAssetService m_assetService; private const bool m_checkPackets = true; - private Timer m_propertiesPacketTimer; - private List m_propertiesBlocks = new List(); - #endregion Class Members #region Properties @@ -511,6 +509,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_scene = scene; m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); + m_entityProps = new PriorityQueue(m_scene.Entities.Count); m_fullUpdateDataBlocksBuilder = new List(); m_killRecord = new HashSet(); // m_attachmentsSent = new HashSet(); @@ -534,9 +533,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_udpClient.OnQueueEmpty += HandleQueueEmpty; m_udpClient.OnPacketStats += PopulateStats; - m_propertiesPacketTimer = new Timer(100); - m_propertiesPacketTimer.Elapsed += ProcessObjectPropertiesPacket; - m_prioritizer = new Prioritizer(m_scene); RegisterLocalPacketHandlers(); @@ -3636,9 +3632,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); } - private Int32 m_LastQueueFill = 0; - private uint m_maxUpdates = 0; - private void ProcessEntityUpdates(int maxUpdates) { OpenSim.Framework.Lazy> objectUpdateBlocks = new OpenSim.Framework.Lazy>(); @@ -3646,46 +3639,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP OpenSim.Framework.Lazy> terseUpdateBlocks = new OpenSim.Framework.Lazy>(); OpenSim.Framework.Lazy> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy>(); + // Check to see if this is a flush if (maxUpdates <= 0) { - m_maxUpdates = Int32.MaxValue; + maxUpdates = Int32.MaxValue; } - else - { - if (m_maxUpdates == 0 || m_LastQueueFill == 0) - { - m_maxUpdates = (uint)maxUpdates; - } - else - { - if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200) - m_maxUpdates += 5; - else - m_maxUpdates = m_maxUpdates >> 1; - } - m_maxUpdates = Util.Clamp(m_maxUpdates,10,500); - } - m_LastQueueFill = Util.EnvironmentTickCount(); - + int updatesThisCall = 0; -// -// DEBUGGING CODE... REMOVE -// LogQueueProcessEvent(this.m_agentId,m_entityUpdates,m_maxUpdates); -// // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race // condition where a kill can be processed before an out-of-date update for the same object. lock (m_killRecord) { float avgTimeDilation = 1.0f; - EntityUpdate update; + IEntityUpdate iupdate; Int32 timeinqueue; // this is just debugging code & can be dropped later - while (updatesThisCall < m_maxUpdates) + while (updatesThisCall < maxUpdates) { lock (m_entityUpdates.SyncRoot) - if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) + if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue)) break; + + EntityUpdate update = (EntityUpdate)iupdate; + avgTimeDilation += update.TimeDilation; avgTimeDilation *= 0.5f; @@ -3725,7 +3702,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region UpdateFlags to packet type conversion - PrimUpdateFlags updateFlags = update.Flags; + PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; bool canUseCompressed = true; bool canUseImproved = true; @@ -3804,6 +3781,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Block Construction } + #region Packet Sending @@ -3904,12 +3882,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Primitive Packet/Data Sending Methods + // These are used to implement an adaptive backoff in the number + // of updates converted to packets. Since we don't want packets + // to sit in the queue with old data, only convert enough updates + // to packets that can be sent in 200ms. + private Int32 m_LastQueueFill = 0; + private Int32 m_maxUpdates = 0; + void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) { if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) { + if (m_maxUpdates == 0 || m_LastQueueFill == 0) + { + m_maxUpdates = m_udpServer.PrimUpdatesPerCallback; + } + else + { + if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200) + m_maxUpdates += 5; + else + m_maxUpdates = m_maxUpdates >> 1; + } + m_maxUpdates = Util.Clamp(m_maxUpdates,10,500); + m_LastQueueFill = Util.EnvironmentTickCount(); + if (m_entityUpdates.Count > 0) - ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback); + ProcessEntityUpdates(m_maxUpdates); + + if (m_entityProps.Count > 0) + ProcessEntityPropertyRequests(m_maxUpdates); } if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) @@ -4023,134 +4025,192 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(pack, ThrottleOutPacketType.Task); } - public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, - uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, - uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, - UUID LastOwnerID, string ObjectName, string Description) - { - ObjectPropertiesFamilyPacket objPropFamilyPack = (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); - // TODO: don't create new blocks if recycling an old packet - - ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = new ObjectPropertiesFamilyPacket.ObjectDataBlock(); - objPropDB.RequestFlags = RequestFlags; - objPropDB.ObjectID = ObjectUUID; - if (OwnerID == GroupID) - objPropDB.OwnerID = UUID.Zero; - else - objPropDB.OwnerID = OwnerID; - objPropDB.GroupID = GroupID; - objPropDB.BaseMask = BaseMask; - objPropDB.OwnerMask = OwnerMask; - objPropDB.GroupMask = GroupMask; - objPropDB.EveryoneMask = EveryoneMask; - objPropDB.NextOwnerMask = NextOwnerMask; +/// ----------------------------------------------------------------- +/// +/// ----------------------------------------------------------------- - // TODO: More properties are needed in SceneObjectPart! - objPropDB.OwnershipCost = OwnershipCost; - objPropDB.SaleType = SaleType; - objPropDB.SalePrice = SalePrice; - objPropDB.Category = Category; - objPropDB.LastOwnerID = LastOwnerID; - objPropDB.Name = Util.StringToBytes256(ObjectName); - objPropDB.Description = Util.StringToBytes256(Description); - objPropFamilyPack.ObjectData = objPropDB; - objPropFamilyPack.Header.Zerocoded = true; - OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task); - } - - public void SendObjectPropertiesReply( - UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, - UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, - UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, - string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, - uint BaseMask, byte saleType, int salePrice) + private class ObjectPropertyUpdate : IEntityUpdate { - //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); - // TODO: don't create new blocks if recycling an old packet + internal bool SendFamilyProps; + + public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam) + : base(entity,flags) + { + SendFamilyProps = sendfam; + } + } + + public void SendObjectPropertiesFamilyData(ISceneEntity entity, uint requestFlags) + { + uint priority = m_prioritizer.GetUpdatePriority(this, entity); + lock (m_entityProps.SyncRoot) + m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true)); + } - ObjectPropertiesPacket.ObjectDataBlock block = - new ObjectPropertiesPacket.ObjectDataBlock(); + public void SendObjectPropertiesReply(ISceneEntity entity) + { + uint priority = m_prioritizer.GetUpdatePriority(this, entity); + lock (m_entityProps.SyncRoot) + m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false)); + } - block.ItemID = ItemID; - block.CreationDate = CreationDate; - block.CreatorID = CreatorUUID; - block.FolderID = FolderUUID; - block.FromTaskID = FromTaskUUID; - block.GroupID = GroupUUID; - block.InventorySerial = InventorySerial; + private void ProcessEntityPropertyRequests(int maxUpdates) + { + OpenSim.Framework.Lazy> objectFamilyBlocks = + new OpenSim.Framework.Lazy>(); - block.LastOwnerID = LastOwnerUUID; - // proper.ObjectData[0].LastOwnerID = UUID.Zero; + OpenSim.Framework.Lazy> objectPropertiesBlocks = + new OpenSim.Framework.Lazy>(); - block.ObjectID = ObjectUUID; - if (OwnerUUID == GroupUUID) - block.OwnerID = UUID.Zero; - else - block.OwnerID = OwnerUUID; - block.TouchName = Util.StringToBytes256(TouchTitle); - block.TextureID = TextureID; - block.SitName = Util.StringToBytes256(SitTitle); - block.Name = Util.StringToBytes256(ItemName); - block.Description = Util.StringToBytes256(ItemDescription); - block.OwnerMask = OwnerMask; - block.NextOwnerMask = NextOwnerMask; - block.GroupMask = GroupMask; - block.EveryoneMask = EveryoneMask; - block.BaseMask = BaseMask; - // proper.ObjectData[0].AggregatePerms = 53; - // proper.ObjectData[0].AggregatePermTextures = 0; - // proper.ObjectData[0].AggregatePermTexturesOwner = 0; - block.SaleType = saleType; - block.SalePrice = salePrice; + IEntityUpdate iupdate; + Int32 timeinqueue; // this is just debugging code & can be dropped later - lock (m_propertiesPacketTimer) + int updatesThisCall = 0; + while (updatesThisCall < m_maxUpdates) { - m_propertiesBlocks.Add(block); + lock (m_entityProps.SyncRoot) + if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) + break; - int length = 0; - foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) + ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate; + if (update.SendFamilyProps) { - length += b.Length; + if (update.Entity is SceneObjectPart) + { + SceneObjectPart sop = (SceneObjectPart)update.Entity; + ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); + objectFamilyBlocks.Value.Add(objPropDB); + } } - if (length > 1100) // FIXME: use real MTU + else { - ProcessObjectPropertiesPacket(null, null); - m_propertiesPacketTimer.Stop(); - return; + if (update.Entity is SceneObjectPart) + { + SceneObjectPart sop = (SceneObjectPart)update.Entity; + ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); + objectPropertiesBlocks.Value.Add(objPropDB); + } } + } + + + if (objectPropertiesBlocks.IsValueCreated) + { + List blocks = objectPropertiesBlocks.Value; - m_propertiesPacketTimer.Stop(); - m_propertiesPacketTimer.Start(); + ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); + packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count]; + for (int i = 0; i < blocks.Count; i++) + packet.ObjectData[i] = blocks[i]; + + packet.Header.Zerocoded = true; + OutPacket(packet, ThrottleOutPacketType.Task, true); } + + + if (objectFamilyBlocks.IsValueCreated) + { + List blocks = objectFamilyBlocks.Value; + + // ObjectPropertiesFamilyPacket objPropFamilyPack = + // (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); + // + // objPropFamilyPack.ObjectData = new ObjectPropertiesFamilyPacket.ObjectDataBlock[blocks.Count]; + // for (int i = 0; i < blocks.Count; i++) + // objPropFamilyPack.ObjectData[i] = blocks[i]; + // + // OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task, true); + + // one packet per object block... uggh... + for (int i = 0; i < blocks.Count; i++) + { + ObjectPropertiesFamilyPacket packet = + (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); - //proper.Header.Zerocoded = true; - //OutPacket(proper, ThrottleOutPacketType.Task); + packet.ObjectData = blocks[i]; + packet.Header.Zerocoded = true; + OutPacket(packet, ThrottleOutPacketType.Task); + } + + } + } - private void ProcessObjectPropertiesPacket(Object sender, ElapsedEventArgs e) + private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, uint requestFlags) { - ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); + ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock(); - lock (m_propertiesPacketTimer) - { - m_propertiesPacketTimer.Stop(); + block.RequestFlags = requestFlags; + block.ObjectID = sop.UUID; + if (sop.OwnerID == sop.GroupID) + block.OwnerID = UUID.Zero; + else + block.OwnerID = sop.OwnerID; + block.GroupID = sop.GroupID; + block.BaseMask = sop.BaseMask; + block.OwnerMask = sop.OwnerMask; + block.GroupMask = sop.GroupMask; + block.EveryoneMask = sop.EveryoneMask; + block.NextOwnerMask = sop.NextOwnerMask; - proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; + // TODO: More properties are needed in SceneObjectPart! + block.OwnershipCost = sop.OwnershipCost; + block.SaleType = sop.ObjectSaleType; + block.SalePrice = sop.SalePrice; + block.Category = sop.Category; + block.LastOwnerID = sop.CreatorID; // copied from old SOG call... is this right? + block.Name = Util.StringToBytes256(sop.Name); + block.Description = Util.StringToBytes256(sop.Description); - int index = 0; + return block; + } - foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) - { - proper.ObjectData[index++] = b; - } + private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop) + { + //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); + // TODO: don't create new blocks if recycling an old packet - m_propertiesBlocks.Clear(); - } + ObjectPropertiesPacket.ObjectDataBlock block = + new ObjectPropertiesPacket.ObjectDataBlock(); + + block.ObjectID = sop.UUID; + block.Name = Util.StringToBytes256(sop.Name); + block.Description = Util.StringToBytes256(sop.Description); - proper.Header.Zerocoded = true; - OutPacket(proper, ThrottleOutPacketType.Task); + block.CreationDate = (ulong)sop.CreationDate * 1000000; // viewer wants date in microseconds + block.CreatorID = sop.CreatorID; + block.GroupID = sop.GroupID; + block.LastOwnerID = sop.LastOwnerID; + if (sop.OwnerID == sop.GroupID) + block.OwnerID = UUID.Zero; + else + block.OwnerID = sop.OwnerID; + + block.ItemID = sop.FromUserInventoryItemID; + block.FolderID = UUID.Zero; // sop.FromFolderID ?? + block.FromTaskID = UUID.Zero; // ??? + block.InventorySerial = (short)sop.InventorySerial; + + SceneObjectPart root = sop.ParentGroup.RootPart; + + block.TouchName = Util.StringToBytes256(root.TouchName); + block.TextureID = new byte[0]; // TextureID ??? + block.SitName = Util.StringToBytes256(root.SitName); + block.OwnerMask = root.OwnerMask; + block.NextOwnerMask = root.NextOwnerMask; + block.GroupMask = root.GroupMask; + block.EveryoneMask = root.EveryoneMask; + block.BaseMask = root.BaseMask; + block.SaleType = root.ObjectSaleType; + block.SalePrice = root.SalePrice; + + return block; } +/// ----------------------------------------------------------------- +/// +/// ----------------------------------------------------------------- + #region Estate Data Sending Methods private static bool convertParamStringToBool(byte[] field) @@ -4482,6 +4542,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendForceClientSelectObjects(List ObjectIDs) { + m_log.WarnFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count); + bool firstCall = true; const int MAX_OBJECTS_PER_PACKET = 251; ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); @@ -11374,6 +11436,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); } + if (throttlePacketType == ThrottleOutPacketType.Task) + { + System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace(); // get call stack + System.Diagnostics.StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) + + string stack = ""; + for (int count = 1; count < stackFrames.Length; count++) + { + stack += (stack == "" ? "" : ",") + stackFrames[count].GetMethod().Name; + if (count > 5) break; + } + + // m_log.WarnFormat("[BADGUY] {0}", stack); + } + m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); } diff --git a/OpenSim/Region/ClientStack/LindenUDP/PriorityQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/PriorityQueue.cs index 364ce4b..6521a00 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/PriorityQueue.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/PriorityQueue.cs @@ -78,7 +78,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public bool Enqueue(uint pqueue, EntityUpdate value) + public bool Enqueue(uint pqueue, IEntityUpdate value) { LookupItem lookup; @@ -99,7 +99,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return true; } - internal bool TryDequeue(out EntityUpdate value, out Int32 timeinqueue) + internal bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) { for (int i = 0; i < m_numberOfQueues; ++i) { @@ -122,7 +122,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } timeinqueue = 0; - value = default(EntityUpdate); + value = default(IEntityUpdate); return false; } @@ -175,8 +175,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region MinHeapItem private struct MinHeapItem : IComparable { - private EntityUpdate value; - internal EntityUpdate Value { + private IEntityUpdate value; + internal IEntityUpdate Value { get { return this.value; } @@ -212,7 +212,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP this.pqueue = pqueue; } - internal MinHeapItem(uint pqueue, UInt64 entryorder, EntityUpdate value) + internal MinHeapItem(uint pqueue, UInt64 entryorder, IEntityUpdate value) { this.entrytime = Util.EnvironmentTickCount(); this.entryorder = entryorder; diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index d939329..89e9e20 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -702,18 +702,12 @@ namespace OpenSim.Region.Examples.SimpleModule { } - public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, - uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, - uint NextOwnerMask, int OwnershipCost, byte SaleType,int SalePrice, uint Category, - UUID LastOwnerID, string ObjectName, string Description) + public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) { + } - public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, - UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, - UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, - string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, - uint BaseMask, byte saleType, int salePrice) + public void SendObjectPropertiesReply(ISceneEntity entity) { } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ca7d9d9..30563d4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1765,10 +1765,12 @@ namespace OpenSim.Region.Framework.Scenes /// public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) { - remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, - RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, - RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, - RootPart.CreatorID, RootPart.Name, RootPart.Description); + remoteClient.SendObjectPropertiesFamilyData(RootPart, RequestFlags); + +// remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, +// RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, +// RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, +// RootPart.CreatorID, RootPart.Name, RootPart.Description); } public void SetPartOwner(SceneObjectPart part, UUID cAgentID, UUID cGroupID) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4d5eedf..3d2eacd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2055,15 +2055,7 @@ namespace OpenSim.Region.Framework.Scenes public void GetProperties(IClientAPI client) { - //Viewer wants date in microseconds so multiply it by 1,000,000. - client.SendObjectPropertiesReply( - m_fromUserInventoryItemID, (ulong)_creationDate*(ulong)1e6, _creatorID, UUID.Zero, UUID.Zero, - _groupID, (short)InventorySerial, _lastOwnerID, UUID, _ownerID, - ParentGroup.RootPart.TouchName, new byte[0], ParentGroup.RootPart.SitName, Name, Description, - ParentGroup.RootPart._ownerMask, ParentGroup.RootPart._nextOwnerMask, ParentGroup.RootPart._groupMask, ParentGroup.RootPart._everyoneMask, - ParentGroup.RootPart._baseMask, - ParentGroup.RootPart.ObjectSaleType, - ParentGroup.RootPart.SalePrice); + client.SendObjectPropertiesReply(this); } public UUID GetRootPartUUID() diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 821cd4b..4b6e52e 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1332,14 +1332,13 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } - public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, UUID LastOwnerID, string ObjectName, string Description) + public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) { } - public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, byte saleType, int salePrice) + public void SendObjectPropertiesReply(ISceneEntity entity) { - } public void SendAgentOffline(UUID[] agentIDs) diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 96760a2..2504e30 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -786,18 +786,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, - uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, - uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, - UUID LastOwnerID, string ObjectName, string Description) + public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) { + } - public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, - UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, - UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, - string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, - uint BaseMask, byte saleType, int salePrice) + public void SendObjectPropertiesReply(ISceneEntity entity) { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index d1dc17f..dca5626 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -816,18 +816,11 @@ namespace OpenSim.Tests.Common.Mock { } - public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, - uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, - uint NextOwnerMask, int OwnershipCost, byte SaleType,int SalePrice, uint Category, - UUID LastOwnerID, string ObjectName, string Description) + public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) { } - public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, - UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, - UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, - string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, - uint BaseMask, byte saleType, int salePrice) + public void SendObjectPropertiesReply(ISceneEntity entity) { } -- cgit v1.1