aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs428
1 files changed, 217 insertions, 211 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 1c3ecb2..803114f 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -301,77 +301,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
301 /// <summary>Used to adjust Sun Orbit values so Linden based viewers properly position sun</summary> 301 /// <summary>Used to adjust Sun Orbit values so Linden based viewers properly position sun</summary>
302 private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; 302 private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f;
303 303
304 // First log file or time has expired, start writing to a new log file
305//<MIC>
306// -----------------------------------------------------------------
307// -----------------------------------------------------------------
308// THIS IS DEBUGGING CODE & SHOULD BE REMOVED
309// -----------------------------------------------------------------
310// -----------------------------------------------------------------
311 public class QueueLogger
312 {
313 public Int32 start = 0;
314 public StreamWriter Log = null;
315 private Dictionary<UUID,int> m_idMap = new Dictionary<UUID,int>();
316
317 public QueueLogger()
318 {
319 DateTime now = DateTime.Now;
320 String fname = String.Format("queue-{0}.log", now.ToString("yyyyMMddHHmmss"));
321 Log = new StreamWriter(fname);
322
323 start = Util.EnvironmentTickCount();
324 }
325
326 public int LookupID(UUID uuid)
327 {
328 int localid;
329 if (! m_idMap.TryGetValue(uuid,out localid))
330 {
331 localid = m_idMap.Count + 1;
332 m_idMap[uuid] = localid;
333 }
334
335 return localid;
336 }
337 }
338
339 public static QueueLogger QueueLog = null;
340
341 // -----------------------------------------------------------------
342 public void LogAvatarUpdateEvent(UUID client, UUID avatar, Int32 timeinqueue)
343 {
344 if (QueueLog == null)
345 QueueLog = new QueueLogger();
346
347 Int32 ticks = Util.EnvironmentTickCountSubtract(QueueLog.start);
348 lock(QueueLog)
349 {
350 int cid = QueueLog.LookupID(client);
351 int aid = QueueLog.LookupID(avatar);
352 QueueLog.Log.WriteLine("{0},AU,AV{1:D4},AV{2:D4},{3}",ticks,cid,aid,timeinqueue);
353 }
354 }
355
356 // -----------------------------------------------------------------
357 public void LogQueueProcessEvent(UUID client, PriorityQueue queue, uint maxup)
358 {
359 if (QueueLog == null)
360 QueueLog = new QueueLogger();
361
362 Int32 ticks = Util.EnvironmentTickCountSubtract(QueueLog.start);
363 lock(QueueLog)
364 {
365 int cid = QueueLog.LookupID(client);
366 QueueLog.Log.WriteLine("{0},PQ,AV{1:D4},{2},{3}",ticks,cid,maxup,queue.ToString());
367 }
368 }
369// -----------------------------------------------------------------
370// -----------------------------------------------------------------
371// -----------------------------------------------------------------
372// -----------------------------------------------------------------
373//</MIC>
374
375 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 304 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
376 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients 305 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
377 306
@@ -387,6 +316,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
387 316
388 private int m_cachedTextureSerial; 317 private int m_cachedTextureSerial;
389 private PriorityQueue m_entityUpdates; 318 private PriorityQueue m_entityUpdates;
319 private PriorityQueue m_entityProps;
390 private Prioritizer m_prioritizer; 320 private Prioritizer m_prioritizer;
391 private bool m_disableFacelights = false; 321 private bool m_disableFacelights = false;
392 322
@@ -435,9 +365,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
435 protected IAssetService m_assetService; 365 protected IAssetService m_assetService;
436 private const bool m_checkPackets = true; 366 private const bool m_checkPackets = true;
437 367
438 private Timer m_propertiesPacketTimer;
439 private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>();
440
441 #endregion Class Members 368 #endregion Class Members
442 369
443 #region Properties 370 #region Properties
@@ -521,6 +448,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
521 m_scene = scene; 448 m_scene = scene;
522 449
523 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 450 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
451 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
524 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 452 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
525 m_killRecord = new HashSet<uint>(); 453 m_killRecord = new HashSet<uint>();
526// m_attachmentsSent = new HashSet<uint>(); 454// m_attachmentsSent = new HashSet<uint>();
@@ -544,9 +472,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
544 m_udpClient.OnQueueEmpty += HandleQueueEmpty; 472 m_udpClient.OnQueueEmpty += HandleQueueEmpty;
545 m_udpClient.OnPacketStats += PopulateStats; 473 m_udpClient.OnPacketStats += PopulateStats;
546 474
547 m_propertiesPacketTimer = new Timer(100);
548 m_propertiesPacketTimer.Elapsed += ProcessObjectPropertiesPacket;
549
550 m_prioritizer = new Prioritizer(m_scene); 475 m_prioritizer = new Prioritizer(m_scene);
551 476
552 RegisterLocalPacketHandlers(); 477 RegisterLocalPacketHandlers();
@@ -2468,7 +2393,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2468 2393
2469 packet.Effect = effectBlocks; 2394 packet.Effect = effectBlocks;
2470 2395
2471 OutPacket(packet, ThrottleOutPacketType.State); 2396 // OutPacket(packet, ThrottleOutPacketType.State);
2397 OutPacket(packet, ThrottleOutPacketType.Task);
2472 } 2398 }
2473 2399
2474 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, 2400 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember,
@@ -3670,9 +3596,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3670 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); 3596 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
3671 } 3597 }
3672 3598
3673 private Int32 m_LastQueueFill = 0;
3674 private uint m_maxUpdates = 0;
3675
3676 private void ProcessEntityUpdates(int maxUpdates) 3599 private void ProcessEntityUpdates(int maxUpdates)
3677 { 3600 {
3678 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3601 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
@@ -3680,41 +3603,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3680 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); 3603 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3681 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); 3604 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3682 3605
3606 // Check to see if this is a flush
3683 if (maxUpdates <= 0) 3607 if (maxUpdates <= 0)
3684 { 3608 {
3685 m_maxUpdates = Int32.MaxValue; 3609 maxUpdates = Int32.MaxValue;
3686 }
3687 else
3688 {
3689 if (m_maxUpdates == 0 || m_LastQueueFill == 0)
3690 {
3691 m_maxUpdates = (uint)maxUpdates;
3692 }
3693 else
3694 {
3695 if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200)
3696 m_maxUpdates += 5;
3697 else
3698 m_maxUpdates = m_maxUpdates >> 1;
3699 }
3700 m_maxUpdates = Util.Clamp<uint>(m_maxUpdates,10,500);
3701 } 3610 }
3702 m_LastQueueFill = Util.EnvironmentTickCount(); 3611
3703
3704 int updatesThisCall = 0; 3612 int updatesThisCall = 0;
3705 3613
3706 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3614 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3707 // condition where a kill can be processed before an out-of-date update for the same object. 3615 // condition where a kill can be processed before an out-of-date update for the same object.
3708 float avgTimeDilation = 1.0f; 3616 float avgTimeDilation = 1.0f;
3709 3617 IEntityUpdate iupdate;
3710 EntityUpdate update;
3711 Int32 timeinqueue; // this is just debugging code & can be dropped later 3618 Int32 timeinqueue; // this is just debugging code & can be dropped later
3712 3619
3713 while (updatesThisCall < m_maxUpdates) 3620 while (updatesThisCall < maxUpdates)
3714 { 3621 {
3715 lock (m_entityUpdates.SyncRoot) 3622 lock (m_entityUpdates.SyncRoot)
3716 if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) 3623 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3717 break; 3624 break;
3625
3626 EntityUpdate update = (EntityUpdate)iupdate;
3627
3718 avgTimeDilation += update.TimeDilation; 3628 avgTimeDilation += update.TimeDilation;
3719 avgTimeDilation *= 0.5f; 3629 avgTimeDilation *= 0.5f;
3720 3630
@@ -3770,7 +3680,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3770 if (!found) 3680 if (!found)
3771 continue; 3681 continue;
3772 } 3682 }
3773
3774 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3683 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3775 { 3684 {
3776 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3685 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
@@ -3785,7 +3694,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3785 3694
3786 #region UpdateFlags to packet type conversion 3695 #region UpdateFlags to packet type conversion
3787 3696
3788 PrimUpdateFlags updateFlags = update.Flags; 3697 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3789 3698
3790 bool canUseCompressed = true; 3699 bool canUseCompressed = true;
3791 bool canUseImproved = true; 3700 bool canUseImproved = true;
@@ -3960,12 +3869,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3960 3869
3961 #endregion Primitive Packet/Data Sending Methods 3870 #endregion Primitive Packet/Data Sending Methods
3962 3871
3872 // These are used to implement an adaptive backoff in the number
3873 // of updates converted to packets. Since we don't want packets
3874 // to sit in the queue with old data, only convert enough updates
3875 // to packets that can be sent in 200ms.
3876 private Int32 m_LastQueueFill = 0;
3877 private Int32 m_maxUpdates = 0;
3878
3963 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) 3879 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
3964 { 3880 {
3965 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) 3881 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
3966 { 3882 {
3883 if (m_maxUpdates == 0 || m_LastQueueFill == 0)
3884 {
3885 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
3886 }
3887 else
3888 {
3889 if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200)
3890 m_maxUpdates += 5;
3891 else
3892 m_maxUpdates = m_maxUpdates >> 1;
3893 }
3894 m_maxUpdates = Util.Clamp<Int32>(m_maxUpdates,10,500);
3895 m_LastQueueFill = Util.EnvironmentTickCount();
3896
3967 if (m_entityUpdates.Count > 0) 3897 if (m_entityUpdates.Count > 0)
3968 ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback); 3898 ProcessEntityUpdates(m_maxUpdates);
3899
3900 if (m_entityProps.Count > 0)
3901 ProcessEntityPropertyRequests(m_maxUpdates);
3969 } 3902 }
3970 3903
3971 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) 3904 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
@@ -4079,135 +4012,206 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4079 OutPacket(pack, ThrottleOutPacketType.Task); 4012 OutPacket(pack, ThrottleOutPacketType.Task);
4080 } 4013 }
4081 4014
4082 public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, 4015 private class ObjectPropertyUpdate : IEntityUpdate
4083 uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask,
4084 uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category,
4085 UUID LastOwnerID, string ObjectName, string Description)
4086 { 4016 {
4087 ObjectPropertiesFamilyPacket objPropFamilyPack = (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); 4017 internal bool SendFamilyProps;
4088 // TODO: don't create new blocks if recycling an old packet 4018 internal bool SendObjectProps;
4089 4019
4090 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = new ObjectPropertiesFamilyPacket.ObjectDataBlock(); 4020 public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam, bool sendobj)
4091 objPropDB.RequestFlags = RequestFlags; 4021 : base(entity,flags)
4092 objPropDB.ObjectID = ObjectUUID; 4022 {
4093 if (OwnerID == GroupID) 4023 SendFamilyProps = sendfam;
4094 objPropDB.OwnerID = UUID.Zero; 4024 SendObjectProps = sendobj;
4095 else 4025 }
4096 objPropDB.OwnerID = OwnerID; 4026 public void Update(ObjectPropertyUpdate update)
4097 objPropDB.GroupID = GroupID; 4027 {
4098 objPropDB.BaseMask = BaseMask; 4028 SendFamilyProps = SendFamilyProps || update.SendFamilyProps;
4099 objPropDB.OwnerMask = OwnerMask; 4029 SendObjectProps = SendObjectProps || update.SendObjectProps;
4100 objPropDB.GroupMask = GroupMask; 4030 Flags |= update.Flags;
4101 objPropDB.EveryoneMask = EveryoneMask; 4031 }
4102 objPropDB.NextOwnerMask = NextOwnerMask; 4032 }
4103 4033
4104 // TODO: More properties are needed in SceneObjectPart! 4034 public void SendObjectPropertiesFamilyData(ISceneEntity entity, uint requestFlags)
4105 objPropDB.OwnershipCost = OwnershipCost;
4106 objPropDB.SaleType = SaleType;
4107 objPropDB.SalePrice = SalePrice;
4108 objPropDB.Category = Category;
4109 objPropDB.LastOwnerID = LastOwnerID;
4110 objPropDB.Name = Util.StringToBytes256(ObjectName);
4111 objPropDB.Description = Util.StringToBytes256(Description);
4112 objPropFamilyPack.ObjectData = objPropDB;
4113 objPropFamilyPack.Header.Zerocoded = true;
4114 OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task);
4115 }
4116
4117 public void SendObjectPropertiesReply(
4118 UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID,
4119 UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID,
4120 UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName,
4121 string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask,
4122 uint BaseMask, byte saleType, int salePrice)
4123 { 4035 {
4124 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 4036 uint priority = 0; // time based ordering only
4125 // TODO: don't create new blocks if recycling an old packet 4037 lock (m_entityProps.SyncRoot)
4038 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false));
4039 }
4126 4040
4127 ObjectPropertiesPacket.ObjectDataBlock block = 4041 public void SendObjectPropertiesReply(ISceneEntity entity)
4128 new ObjectPropertiesPacket.ObjectDataBlock(); 4042 {
4043 uint priority = 0; // time based ordering only
4044 lock (m_entityProps.SyncRoot)
4045 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true));
4046 }
4129 4047
4130 block.ItemID = ItemID; 4048 private void ProcessEntityPropertyRequests(int maxUpdates)
4131 block.CreationDate = CreationDate; 4049 {
4132 block.CreatorID = CreatorUUID; 4050 OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks =
4133 block.FolderID = FolderUUID; 4051 new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>();
4134 block.FromTaskID = FromTaskUUID;
4135 block.GroupID = GroupUUID;
4136 block.InventorySerial = InventorySerial;
4137 4052
4138 block.LastOwnerID = LastOwnerUUID; 4053 OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks =
4139 // proper.ObjectData[0].LastOwnerID = UUID.Zero; 4054 new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>();
4140 4055
4141 block.ObjectID = ObjectUUID; 4056 IEntityUpdate iupdate;
4142 if (OwnerUUID == GroupUUID) 4057 Int32 timeinqueue; // this is just debugging code & can be dropped later
4143 block.OwnerID = UUID.Zero;
4144 else
4145 block.OwnerID = OwnerUUID;
4146 block.TouchName = Util.StringToBytes256(TouchTitle);
4147 block.TextureID = TextureID;
4148 block.SitName = Util.StringToBytes256(SitTitle);
4149 block.Name = Util.StringToBytes256(ItemName);
4150 block.Description = Util.StringToBytes256(ItemDescription);
4151 block.OwnerMask = OwnerMask;
4152 block.NextOwnerMask = NextOwnerMask;
4153 block.GroupMask = GroupMask;
4154 block.EveryoneMask = EveryoneMask;
4155 block.BaseMask = BaseMask;
4156 // proper.ObjectData[0].AggregatePerms = 53;
4157 // proper.ObjectData[0].AggregatePermTextures = 0;
4158 // proper.ObjectData[0].AggregatePermTexturesOwner = 0;
4159 block.SaleType = saleType;
4160 block.SalePrice = salePrice;
4161 4058
4162 lock (m_propertiesPacketTimer) 4059 int updatesThisCall = 0;
4060 while (updatesThisCall < m_maxUpdates)
4163 { 4061 {
4164 m_propertiesBlocks.Add(block); 4062 lock (m_entityProps.SyncRoot)
4063 if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
4064 break;
4165 4065
4166 int length = 0; 4066 ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate;
4167 foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) 4067 if (update.SendFamilyProps)
4168 { 4068 {
4169 length += b.Length; 4069 if (update.Entity is SceneObjectPart)
4070 {
4071 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4072 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
4073 objectFamilyBlocks.Value.Add(objPropDB);
4074 }
4170 } 4075 }
4171 if (length > 1100) // FIXME: use real MTU 4076
4077 if (update.SendObjectProps)
4172 { 4078 {
4173 ProcessObjectPropertiesPacket(null, null); 4079 if (update.Entity is SceneObjectPart)
4174 m_propertiesPacketTimer.Stop(); 4080 {
4175 return; 4081 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4082 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
4083 objectPropertiesBlocks.Value.Add(objPropDB);
4084 }
4176 } 4085 }
4177 4086
4178 m_propertiesPacketTimer.Stop(); 4087 updatesThisCall++;
4179 m_propertiesPacketTimer.Start();
4180 } 4088 }
4089
4181 4090
4182 //proper.Header.Zerocoded = true; 4091 Int32 ppcnt = 0;
4183 //OutPacket(proper, ThrottleOutPacketType.Task); 4092 Int32 pbcnt = 0;
4184 } 4093
4094 if (objectPropertiesBlocks.IsValueCreated)
4095 {
4096 List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
4185 4097
4186 private void ProcessObjectPropertiesPacket(Object sender, ElapsedEventArgs e) 4098 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
4187 { 4099 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count];
4188 ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 4100 for (int i = 0; i < blocks.Count; i++)
4101 packet.ObjectData[i] = blocks[i];
4189 4102
4190 lock (m_propertiesPacketTimer) 4103 packet.Header.Zerocoded = true;
4104 OutPacket(packet, ThrottleOutPacketType.Task, true);
4105
4106 pbcnt += blocks.Count;
4107 ppcnt++;
4108 }
4109
4110 Int32 fpcnt = 0;
4111 Int32 fbcnt = 0;
4112
4113 if (objectFamilyBlocks.IsValueCreated)
4191 { 4114 {
4192 m_propertiesPacketTimer.Stop(); 4115 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
4193 4116
4194 if (m_propertiesBlocks.Count == 0) 4117 // ObjectPropertiesFamilyPacket objPropFamilyPack =
4195 return; 4118 // (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
4119 //
4120 // objPropFamilyPack.ObjectData = new ObjectPropertiesFamilyPacket.ObjectDataBlock[blocks.Count];
4121 // for (int i = 0; i < blocks.Count; i++)
4122 // objPropFamilyPack.ObjectData[i] = blocks[i];
4123 //
4124 // OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task, true);
4196 4125
4197 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; 4126 // one packet per object block... uggh...
4127 for (int i = 0; i < blocks.Count; i++)
4128 {
4129 ObjectPropertiesFamilyPacket packet =
4130 (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
4198 4131
4199 int index = 0; 4132 packet.ObjectData = blocks[i];
4133 packet.Header.Zerocoded = true;
4134 OutPacket(packet, ThrottleOutPacketType.Task);
4200 4135
4201 foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) 4136 fpcnt++;
4202 { 4137 fbcnt++;
4203 proper.ObjectData[index++] = b;
4204 } 4138 }
4205 4139
4206 m_propertiesBlocks.Clear();
4207 } 4140 }
4141
4142 // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt);
4143 // m_log.WarnFormat("[PACKETCOUNTS] queued {0} family property packets with {1} blocks",fpcnt,fbcnt);
4144 }
4145
4146 private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, uint requestFlags)
4147 {
4148 ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock();
4208 4149
4209 proper.Header.Zerocoded = true; 4150 block.RequestFlags = requestFlags;
4210 OutPacket(proper, ThrottleOutPacketType.Task); 4151 block.ObjectID = sop.UUID;
4152 if (sop.OwnerID == sop.GroupID)
4153 block.OwnerID = UUID.Zero;
4154 else
4155 block.OwnerID = sop.OwnerID;
4156 block.GroupID = sop.GroupID;
4157 block.BaseMask = sop.BaseMask;
4158 block.OwnerMask = sop.OwnerMask;
4159 block.GroupMask = sop.GroupMask;
4160 block.EveryoneMask = sop.EveryoneMask;
4161 block.NextOwnerMask = sop.NextOwnerMask;
4162
4163 // TODO: More properties are needed in SceneObjectPart!
4164 block.OwnershipCost = sop.OwnershipCost;
4165 block.SaleType = sop.ObjectSaleType;
4166 block.SalePrice = sop.SalePrice;
4167 block.Category = sop.Category;
4168 block.LastOwnerID = sop.CreatorID; // copied from old SOG call... is this right?
4169 block.Name = Util.StringToBytes256(sop.Name);
4170 block.Description = Util.StringToBytes256(sop.Description);
4171
4172 return block;
4173 }
4174
4175 private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop)
4176 {
4177 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
4178 // TODO: don't create new blocks if recycling an old packet
4179
4180 ObjectPropertiesPacket.ObjectDataBlock block =
4181 new ObjectPropertiesPacket.ObjectDataBlock();
4182
4183 block.ObjectID = sop.UUID;
4184 block.Name = Util.StringToBytes256(sop.Name);
4185 block.Description = Util.StringToBytes256(sop.Description);
4186
4187 block.CreationDate = (ulong)sop.CreationDate * 1000000; // viewer wants date in microseconds
4188 block.CreatorID = sop.CreatorID;
4189 block.GroupID = sop.GroupID;
4190 block.LastOwnerID = sop.LastOwnerID;
4191 if (sop.OwnerID == sop.GroupID)
4192 block.OwnerID = UUID.Zero;
4193 else
4194 block.OwnerID = sop.OwnerID;
4195
4196 block.ItemID = sop.FromUserInventoryItemID;
4197 block.FolderID = UUID.Zero; // sop.FromFolderID ??
4198 block.FromTaskID = UUID.Zero; // ???
4199 block.InventorySerial = (short)sop.InventorySerial;
4200
4201 SceneObjectPart root = sop.ParentGroup.RootPart;
4202
4203 block.TouchName = Util.StringToBytes256(root.TouchName);
4204 block.TextureID = new byte[0]; // TextureID ???
4205 block.SitName = Util.StringToBytes256(root.SitName);
4206 block.OwnerMask = root.OwnerMask;
4207 block.NextOwnerMask = root.NextOwnerMask;
4208 block.GroupMask = root.GroupMask;
4209 block.EveryoneMask = root.EveryoneMask;
4210 block.BaseMask = root.BaseMask;
4211 block.SaleType = root.ObjectSaleType;
4212 block.SalePrice = root.SalePrice;
4213
4214 return block;
4211 } 4215 }
4212 4216
4213 #region Estate Data Sending Methods 4217 #region Estate Data Sending Methods
@@ -4548,6 +4552,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4548 4552
4549 public void SendForceClientSelectObjects(List<uint> ObjectIDs) 4553 public void SendForceClientSelectObjects(List<uint> ObjectIDs)
4550 { 4554 {
4555 m_log.WarnFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count);
4556
4551 bool firstCall = true; 4557 bool firstCall = true;
4552 const int MAX_OBJECTS_PER_PACKET = 251; 4558 const int MAX_OBJECTS_PER_PACKET = 251;
4553 ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); 4559 ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect);
@@ -11491,7 +11497,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11491 if (logPacket) 11497 if (logPacket)
11492 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); 11498 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type);
11493 } 11499 }
11494 11500
11495 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); 11501 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting);
11496 } 11502 }
11497 11503