aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2011-04-18 20:36:26 +0100
committerJustin Clark-Casey (justincc)2011-04-18 20:36:26 +0100
commit8533c63d8903d896da0bbbcebb00d48c4e2415f6 (patch)
tree95f0db9dc79a1d51def32b491df0c9913ad2c45b /OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
parentProvide a configuration setting to control whether multiple taken objects are... (diff)
parentMerge branch 'master' into test-merge0418 (diff)
downloadopensim-SC_OLD-8533c63d8903d896da0bbbcebb00d48c4e2415f6.zip
opensim-SC_OLD-8533c63d8903d896da0bbbcebb00d48c4e2415f6.tar.gz
opensim-SC_OLD-8533c63d8903d896da0bbbcebb00d48c4e2415f6.tar.bz2
opensim-SC_OLD-8533c63d8903d896da0bbbcebb00d48c4e2415f6.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs431
1 files changed, 220 insertions, 211 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 76d7f79..1f7e66d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -300,77 +300,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
300 /// <summary>Used to adjust Sun Orbit values so Linden based viewers properly position sun</summary> 300 /// <summary>Used to adjust Sun Orbit values so Linden based viewers properly position sun</summary>
301 private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; 301 private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f;
302 302
303 // First log file or time has expired, start writing to a new log file
304//<MIC>
305// -----------------------------------------------------------------
306// -----------------------------------------------------------------
307// THIS IS DEBUGGING CODE & SHOULD BE REMOVED
308// -----------------------------------------------------------------
309// -----------------------------------------------------------------
310 public class QueueLogger
311 {
312 public Int32 start = 0;
313 public StreamWriter Log = null;
314 private Dictionary<UUID,int> m_idMap = new Dictionary<UUID,int>();
315
316 public QueueLogger()
317 {
318 DateTime now = DateTime.Now;
319 String fname = String.Format("queue-{0}.log", now.ToString("yyyyMMddHHmmss"));
320 Log = new StreamWriter(fname);
321
322 start = Util.EnvironmentTickCount();
323 }
324
325 public int LookupID(UUID uuid)
326 {
327 int localid;
328 if (! m_idMap.TryGetValue(uuid,out localid))
329 {
330 localid = m_idMap.Count + 1;
331 m_idMap[uuid] = localid;
332 }
333
334 return localid;
335 }
336 }
337
338 public static QueueLogger QueueLog = null;
339
340 // -----------------------------------------------------------------
341 public void LogAvatarUpdateEvent(UUID client, UUID avatar, Int32 timeinqueue)
342 {
343 if (QueueLog == null)
344 QueueLog = new QueueLogger();
345
346 Int32 ticks = Util.EnvironmentTickCountSubtract(QueueLog.start);
347 lock(QueueLog)
348 {
349 int cid = QueueLog.LookupID(client);
350 int aid = QueueLog.LookupID(avatar);
351 QueueLog.Log.WriteLine("{0},AU,AV{1:D4},AV{2:D4},{3}",ticks,cid,aid,timeinqueue);
352 }
353 }
354
355 // -----------------------------------------------------------------
356 public void LogQueueProcessEvent(UUID client, PriorityQueue queue, uint maxup)
357 {
358 if (QueueLog == null)
359 QueueLog = new QueueLogger();
360
361 Int32 ticks = Util.EnvironmentTickCountSubtract(QueueLog.start);
362 lock(QueueLog)
363 {
364 int cid = QueueLog.LookupID(client);
365 QueueLog.Log.WriteLine("{0},PQ,AV{1:D4},{2},{3}",ticks,cid,maxup,queue.ToString());
366 }
367 }
368// -----------------------------------------------------------------
369// -----------------------------------------------------------------
370// -----------------------------------------------------------------
371// -----------------------------------------------------------------
372//</MIC>
373
374 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 303 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
375 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients 304 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
376 305
@@ -386,6 +315,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
386 315
387 private int m_cachedTextureSerial; 316 private int m_cachedTextureSerial;
388 private PriorityQueue m_entityUpdates; 317 private PriorityQueue m_entityUpdates;
318 private PriorityQueue m_entityProps;
389 private Prioritizer m_prioritizer; 319 private Prioritizer m_prioritizer;
390 private bool m_disableFacelights = false; 320 private bool m_disableFacelights = false;
391 321
@@ -433,9 +363,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
433 protected IAssetService m_assetService; 363 protected IAssetService m_assetService;
434 private const bool m_checkPackets = true; 364 private const bool m_checkPackets = true;
435 365
436 private Timer m_propertiesPacketTimer;
437 private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>();
438
439 #endregion Class Members 366 #endregion Class Members
440 367
441 #region Properties 368 #region Properties
@@ -511,6 +438,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
511 m_scene = scene; 438 m_scene = scene;
512 439
513 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 440 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
441 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
514 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 442 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
515 m_killRecord = new HashSet<uint>(); 443 m_killRecord = new HashSet<uint>();
516// m_attachmentsSent = new HashSet<uint>(); 444// m_attachmentsSent = new HashSet<uint>();
@@ -534,9 +462,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
534 m_udpClient.OnQueueEmpty += HandleQueueEmpty; 462 m_udpClient.OnQueueEmpty += HandleQueueEmpty;
535 m_udpClient.OnPacketStats += PopulateStats; 463 m_udpClient.OnPacketStats += PopulateStats;
536 464
537 m_propertiesPacketTimer = new Timer(100);
538 m_propertiesPacketTimer.Elapsed += ProcessObjectPropertiesPacket;
539
540 m_prioritizer = new Prioritizer(m_scene); 465 m_prioritizer = new Prioritizer(m_scene);
541 466
542 RegisterLocalPacketHandlers(); 467 RegisterLocalPacketHandlers();
@@ -1610,7 +1535,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1610 } 1535 }
1611 else 1536 else
1612 { 1537 {
1613 OutPacket(kill, ThrottleOutPacketType.State); 1538 // OutPacket(kill, ThrottleOutPacketType.State);
1539 OutPacket(kill, ThrottleOutPacketType.Task);
1614 } 1540 }
1615 } 1541 }
1616 1542
@@ -2440,7 +2366,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2440 2366
2441 packet.Effect = effectBlocks; 2367 packet.Effect = effectBlocks;
2442 2368
2443 OutPacket(packet, ThrottleOutPacketType.State); 2369 // OutPacket(packet, ThrottleOutPacketType.State);
2370 OutPacket(packet, ThrottleOutPacketType.Task);
2444 } 2371 }
2445 2372
2446 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, 2373 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember,
@@ -3634,9 +3561,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3634 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); 3561 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
3635 } 3562 }
3636 3563
3637 private Int32 m_LastQueueFill = 0;
3638 private uint m_maxUpdates = 0;
3639
3640 private void ProcessEntityUpdates(int maxUpdates) 3564 private void ProcessEntityUpdates(int maxUpdates)
3641 { 3565 {
3642 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3566 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
@@ -3644,46 +3568,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3644 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); 3568 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3645 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); 3569 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3646 3570
3571 // Check to see if this is a flush
3647 if (maxUpdates <= 0) 3572 if (maxUpdates <= 0)
3648 { 3573 {
3649 m_maxUpdates = Int32.MaxValue; 3574 maxUpdates = Int32.MaxValue;
3650 }
3651 else
3652 {
3653 if (m_maxUpdates == 0 || m_LastQueueFill == 0)
3654 {
3655 m_maxUpdates = (uint)maxUpdates;
3656 }
3657 else
3658 {
3659 if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200)
3660 m_maxUpdates += 5;
3661 else
3662 m_maxUpdates = m_maxUpdates >> 1;
3663 }
3664 m_maxUpdates = Util.Clamp<uint>(m_maxUpdates,10,500);
3665 } 3575 }
3666 m_LastQueueFill = Util.EnvironmentTickCount(); 3576
3667
3668 int updatesThisCall = 0; 3577 int updatesThisCall = 0;
3669 3578
3670//<MIC>
3671// DEBUGGING CODE... REMOVE
3672// LogQueueProcessEvent(this.m_agentId,m_entityUpdates,m_maxUpdates);
3673//</MIC>
3674 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3579 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3675 // condition where a kill can be processed before an out-of-date update for the same object. 3580 // condition where a kill can be processed before an out-of-date update for the same object.
3676 lock (m_killRecord) 3581 lock (m_killRecord)
3677 { 3582 {
3678 float avgTimeDilation = 1.0f; 3583 float avgTimeDilation = 1.0f;
3679 EntityUpdate update; 3584 IEntityUpdate iupdate;
3680 Int32 timeinqueue; // this is just debugging code & can be dropped later 3585 Int32 timeinqueue; // this is just debugging code & can be dropped later
3681 3586
3682 while (updatesThisCall < m_maxUpdates) 3587 while (updatesThisCall < maxUpdates)
3683 { 3588 {
3684 lock (m_entityUpdates.SyncRoot) 3589 lock (m_entityUpdates.SyncRoot)
3685 if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) 3590 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3686 break; 3591 break;
3592
3593 EntityUpdate update = (EntityUpdate)iupdate;
3594
3687 avgTimeDilation += update.TimeDilation; 3595 avgTimeDilation += update.TimeDilation;
3688 avgTimeDilation *= 0.5f; 3596 avgTimeDilation *= 0.5f;
3689 3597
@@ -3723,7 +3631,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3723 3631
3724 #region UpdateFlags to packet type conversion 3632 #region UpdateFlags to packet type conversion
3725 3633
3726 PrimUpdateFlags updateFlags = update.Flags; 3634 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3727 3635
3728 bool canUseCompressed = true; 3636 bool canUseCompressed = true;
3729 bool canUseImproved = true; 3637 bool canUseImproved = true;
@@ -3802,6 +3710,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3802 3710
3803 #endregion Block Construction 3711 #endregion Block Construction
3804 } 3712 }
3713
3805 3714
3806 #region Packet Sending 3715 #region Packet Sending
3807 3716
@@ -3902,12 +3811,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3902 3811
3903 #endregion Primitive Packet/Data Sending Methods 3812 #endregion Primitive Packet/Data Sending Methods
3904 3813
3814 // These are used to implement an adaptive backoff in the number
3815 // of updates converted to packets. Since we don't want packets
3816 // to sit in the queue with old data, only convert enough updates
3817 // to packets that can be sent in 200ms.
3818 private Int32 m_LastQueueFill = 0;
3819 private Int32 m_maxUpdates = 0;
3820
3905 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) 3821 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
3906 { 3822 {
3907 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) 3823 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
3908 { 3824 {
3825 if (m_maxUpdates == 0 || m_LastQueueFill == 0)
3826 {
3827 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
3828 }
3829 else
3830 {
3831 if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200)
3832 m_maxUpdates += 5;
3833 else
3834 m_maxUpdates = m_maxUpdates >> 1;
3835 }
3836 m_maxUpdates = Util.Clamp<Int32>(m_maxUpdates,10,500);
3837 m_LastQueueFill = Util.EnvironmentTickCount();
3838
3909 if (m_entityUpdates.Count > 0) 3839 if (m_entityUpdates.Count > 0)
3910 ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback); 3840 ProcessEntityUpdates(m_maxUpdates);
3841
3842 if (m_entityProps.Count > 0)
3843 ProcessEntityPropertyRequests(m_maxUpdates);
3911 } 3844 }
3912 3845
3913 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) 3846 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
@@ -4021,132 +3954,206 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4021 OutPacket(pack, ThrottleOutPacketType.Task); 3954 OutPacket(pack, ThrottleOutPacketType.Task);
4022 } 3955 }
4023 3956
4024 public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, 3957 private class ObjectPropertyUpdate : IEntityUpdate
4025 uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask,
4026 uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category,
4027 UUID LastOwnerID, string ObjectName, string Description)
4028 { 3958 {
4029 ObjectPropertiesFamilyPacket objPropFamilyPack = (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); 3959 internal bool SendFamilyProps;
4030 // TODO: don't create new blocks if recycling an old packet 3960 internal bool SendObjectProps;
4031 3961
4032 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = new ObjectPropertiesFamilyPacket.ObjectDataBlock(); 3962 public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam, bool sendobj)
4033 objPropDB.RequestFlags = RequestFlags; 3963 : base(entity,flags)
4034 objPropDB.ObjectID = ObjectUUID; 3964 {
4035 if (OwnerID == GroupID) 3965 SendFamilyProps = sendfam;
4036 objPropDB.OwnerID = UUID.Zero; 3966 SendObjectProps = sendobj;
4037 else 3967 }
4038 objPropDB.OwnerID = OwnerID; 3968 public void Update(ObjectPropertyUpdate update)
4039 objPropDB.GroupID = GroupID; 3969 {
4040 objPropDB.BaseMask = BaseMask; 3970 SendFamilyProps = SendFamilyProps || update.SendFamilyProps;
4041 objPropDB.OwnerMask = OwnerMask; 3971 SendObjectProps = SendObjectProps || update.SendObjectProps;
4042 objPropDB.GroupMask = GroupMask; 3972 Flags |= update.Flags;
4043 objPropDB.EveryoneMask = EveryoneMask; 3973 }
4044 objPropDB.NextOwnerMask = NextOwnerMask; 3974 }
4045 3975
4046 // TODO: More properties are needed in SceneObjectPart! 3976 public void SendObjectPropertiesFamilyData(ISceneEntity entity, uint requestFlags)
4047 objPropDB.OwnershipCost = OwnershipCost;
4048 objPropDB.SaleType = SaleType;
4049 objPropDB.SalePrice = SalePrice;
4050 objPropDB.Category = Category;
4051 objPropDB.LastOwnerID = LastOwnerID;
4052 objPropDB.Name = Util.StringToBytes256(ObjectName);
4053 objPropDB.Description = Util.StringToBytes256(Description);
4054 objPropFamilyPack.ObjectData = objPropDB;
4055 objPropFamilyPack.Header.Zerocoded = true;
4056 OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task);
4057 }
4058
4059 public void SendObjectPropertiesReply(
4060 UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID,
4061 UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID,
4062 UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName,
4063 string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask,
4064 uint BaseMask, byte saleType, int salePrice)
4065 { 3977 {
4066 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 3978 uint priority = 0; // time based ordering only
4067 // TODO: don't create new blocks if recycling an old packet 3979 lock (m_entityProps.SyncRoot)
3980 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false));
3981 }
4068 3982
4069 ObjectPropertiesPacket.ObjectDataBlock block = 3983 public void SendObjectPropertiesReply(ISceneEntity entity)
4070 new ObjectPropertiesPacket.ObjectDataBlock(); 3984 {
3985 uint priority = 0; // time based ordering only
3986 lock (m_entityProps.SyncRoot)
3987 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true));
3988 }
4071 3989
4072 block.ItemID = ItemID; 3990 private void ProcessEntityPropertyRequests(int maxUpdates)
4073 block.CreationDate = CreationDate; 3991 {
4074 block.CreatorID = CreatorUUID; 3992 OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks =
4075 block.FolderID = FolderUUID; 3993 new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>();
4076 block.FromTaskID = FromTaskUUID;
4077 block.GroupID = GroupUUID;
4078 block.InventorySerial = InventorySerial;
4079 3994
4080 block.LastOwnerID = LastOwnerUUID; 3995 OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks =
4081 // proper.ObjectData[0].LastOwnerID = UUID.Zero; 3996 new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>();
4082 3997
4083 block.ObjectID = ObjectUUID; 3998 IEntityUpdate iupdate;
4084 if (OwnerUUID == GroupUUID) 3999 Int32 timeinqueue; // this is just debugging code & can be dropped later
4085 block.OwnerID = UUID.Zero;
4086 else
4087 block.OwnerID = OwnerUUID;
4088 block.TouchName = Util.StringToBytes256(TouchTitle);
4089 block.TextureID = TextureID;
4090 block.SitName = Util.StringToBytes256(SitTitle);
4091 block.Name = Util.StringToBytes256(ItemName);
4092 block.Description = Util.StringToBytes256(ItemDescription);
4093 block.OwnerMask = OwnerMask;
4094 block.NextOwnerMask = NextOwnerMask;
4095 block.GroupMask = GroupMask;
4096 block.EveryoneMask = EveryoneMask;
4097 block.BaseMask = BaseMask;
4098 // proper.ObjectData[0].AggregatePerms = 53;
4099 // proper.ObjectData[0].AggregatePermTextures = 0;
4100 // proper.ObjectData[0].AggregatePermTexturesOwner = 0;
4101 block.SaleType = saleType;
4102 block.SalePrice = salePrice;
4103 4000
4104 lock (m_propertiesPacketTimer) 4001 int updatesThisCall = 0;
4002 while (updatesThisCall < m_maxUpdates)
4105 { 4003 {
4106 m_propertiesBlocks.Add(block); 4004 lock (m_entityProps.SyncRoot)
4005 if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
4006 break;
4107 4007
4108 int length = 0; 4008 ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate;
4109 foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) 4009 if (update.SendFamilyProps)
4110 { 4010 {
4111 length += b.Length; 4011 if (update.Entity is SceneObjectPart)
4012 {
4013 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4014 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
4015 objectFamilyBlocks.Value.Add(objPropDB);
4016 }
4112 } 4017 }
4113 if (length > 1100) // FIXME: use real MTU 4018
4019 if (update.SendObjectProps)
4114 { 4020 {
4115 ProcessObjectPropertiesPacket(null, null); 4021 if (update.Entity is SceneObjectPart)
4116 m_propertiesPacketTimer.Stop(); 4022 {
4117 return; 4023 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4024 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
4025 objectPropertiesBlocks.Value.Add(objPropDB);
4026 }
4118 } 4027 }
4119 4028
4120 m_propertiesPacketTimer.Stop(); 4029 updatesThisCall++;
4121 m_propertiesPacketTimer.Start();
4122 } 4030 }
4031
4123 4032
4124 //proper.Header.Zerocoded = true; 4033 Int32 ppcnt = 0;
4125 //OutPacket(proper, ThrottleOutPacketType.Task); 4034 Int32 pbcnt = 0;
4126 } 4035
4036 if (objectPropertiesBlocks.IsValueCreated)
4037 {
4038 List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
4127 4039
4128 private void ProcessObjectPropertiesPacket(Object sender, ElapsedEventArgs e) 4040 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
4129 { 4041 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count];
4130 ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 4042 for (int i = 0; i < blocks.Count; i++)
4043 packet.ObjectData[i] = blocks[i];
4131 4044
4132 lock (m_propertiesPacketTimer) 4045 packet.Header.Zerocoded = true;
4133 { 4046 OutPacket(packet, ThrottleOutPacketType.Task, true);
4134 m_propertiesPacketTimer.Stop();
4135 4047
4136 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; 4048 pbcnt += blocks.Count;
4049 ppcnt++;
4050 }
4051
4052 Int32 fpcnt = 0;
4053 Int32 fbcnt = 0;
4054
4055 if (objectFamilyBlocks.IsValueCreated)
4056 {
4057 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
4137 4058
4138 int index = 0; 4059 // ObjectPropertiesFamilyPacket objPropFamilyPack =
4060 // (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
4061 //
4062 // objPropFamilyPack.ObjectData = new ObjectPropertiesFamilyPacket.ObjectDataBlock[blocks.Count];
4063 // for (int i = 0; i < blocks.Count; i++)
4064 // objPropFamilyPack.ObjectData[i] = blocks[i];
4065 //
4066 // OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task, true);
4139 4067
4140 foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) 4068 // one packet per object block... uggh...
4069 for (int i = 0; i < blocks.Count; i++)
4141 { 4070 {
4142 proper.ObjectData[index++] = b; 4071 ObjectPropertiesFamilyPacket packet =
4143 } 4072 (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
4073
4074 packet.ObjectData = blocks[i];
4075 packet.Header.Zerocoded = true;
4076 OutPacket(packet, ThrottleOutPacketType.Task);
4144 4077
4145 m_propertiesBlocks.Clear(); 4078 fpcnt++;
4079 fbcnt++;
4080 }
4081
4146 } 4082 }
4083
4084 // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt);
4085 // m_log.WarnFormat("[PACKETCOUNTS] queued {0} family property packets with {1} blocks",fpcnt,fbcnt);
4086 }
4087
4088 private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, uint requestFlags)
4089 {
4090 ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock();
4091
4092 block.RequestFlags = requestFlags;
4093 block.ObjectID = sop.UUID;
4094 if (sop.OwnerID == sop.GroupID)
4095 block.OwnerID = UUID.Zero;
4096 else
4097 block.OwnerID = sop.OwnerID;
4098 block.GroupID = sop.GroupID;
4099 block.BaseMask = sop.BaseMask;
4100 block.OwnerMask = sop.OwnerMask;
4101 block.GroupMask = sop.GroupMask;
4102 block.EveryoneMask = sop.EveryoneMask;
4103 block.NextOwnerMask = sop.NextOwnerMask;
4104
4105 // TODO: More properties are needed in SceneObjectPart!
4106 block.OwnershipCost = sop.OwnershipCost;
4107 block.SaleType = sop.ObjectSaleType;
4108 block.SalePrice = sop.SalePrice;
4109 block.Category = sop.Category;
4110 block.LastOwnerID = sop.CreatorID; // copied from old SOG call... is this right?
4111 block.Name = Util.StringToBytes256(sop.Name);
4112 block.Description = Util.StringToBytes256(sop.Description);
4113
4114 return block;
4115 }
4147 4116
4148 proper.Header.Zerocoded = true; 4117 private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop)
4149 OutPacket(proper, ThrottleOutPacketType.Task); 4118 {
4119 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
4120 // TODO: don't create new blocks if recycling an old packet
4121
4122 ObjectPropertiesPacket.ObjectDataBlock block =
4123 new ObjectPropertiesPacket.ObjectDataBlock();
4124
4125 block.ObjectID = sop.UUID;
4126 block.Name = Util.StringToBytes256(sop.Name);
4127 block.Description = Util.StringToBytes256(sop.Description);
4128
4129 block.CreationDate = (ulong)sop.CreationDate * 1000000; // viewer wants date in microseconds
4130 block.CreatorID = sop.CreatorID;
4131 block.GroupID = sop.GroupID;
4132 block.LastOwnerID = sop.LastOwnerID;
4133 if (sop.OwnerID == sop.GroupID)
4134 block.OwnerID = UUID.Zero;
4135 else
4136 block.OwnerID = sop.OwnerID;
4137
4138 block.ItemID = sop.FromUserInventoryItemID;
4139 block.FolderID = UUID.Zero; // sop.FromFolderID ??
4140 block.FromTaskID = UUID.Zero; // ???
4141 block.InventorySerial = (short)sop.InventorySerial;
4142
4143 SceneObjectPart root = sop.ParentGroup.RootPart;
4144
4145 block.TouchName = Util.StringToBytes256(root.TouchName);
4146 block.TextureID = new byte[0]; // TextureID ???
4147 block.SitName = Util.StringToBytes256(root.SitName);
4148 block.OwnerMask = root.OwnerMask;
4149 block.NextOwnerMask = root.NextOwnerMask;
4150 block.GroupMask = root.GroupMask;
4151 block.EveryoneMask = root.EveryoneMask;
4152 block.BaseMask = root.BaseMask;
4153 block.SaleType = root.ObjectSaleType;
4154 block.SalePrice = root.SalePrice;
4155
4156 return block;
4150 } 4157 }
4151 4158
4152 #region Estate Data Sending Methods 4159 #region Estate Data Sending Methods
@@ -4487,6 +4494,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4487 4494
4488 public void SendForceClientSelectObjects(List<uint> ObjectIDs) 4495 public void SendForceClientSelectObjects(List<uint> ObjectIDs)
4489 { 4496 {
4497 m_log.WarnFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count);
4498
4490 bool firstCall = true; 4499 bool firstCall = true;
4491 const int MAX_OBJECTS_PER_PACKET = 251; 4500 const int MAX_OBJECTS_PER_PACKET = 251;
4492 ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); 4501 ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect);
@@ -11378,7 +11387,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11378 if (logPacket) 11387 if (logPacket)
11379 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); 11388 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type);
11380 } 11389 }
11381 11390
11382 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); 11391 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting);
11383 } 11392 }
11384 11393