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.cs96
1 files changed, 75 insertions, 21 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 1f7e66d..14c5d6c 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3561,6 +3561,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3561 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); 3561 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
3562 } 3562 }
3563 3563
3564 /// <summary>
3565 /// Requeue an EntityUpdate when it was not acknowledged by the client.
3566 /// We will update the priority and put it in the correct queue, merging update flags
3567 /// with any other updates that may be queued for the same entity.
3568 /// The original update time is used for the merged update.
3569 /// </summary>
3570 public void ResendPrimUpdate(EntityUpdate update)
3571 {
3572 // If the update exists in priority queue, it will be updated.
3573 // If it does not exist then it will be added with the current (rather than its original) priority
3574 uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
3575
3576 lock (m_entityUpdates.SyncRoot)
3577 m_entityUpdates.Enqueue(priority, update);
3578 }
3579
3580 /// <summary>
3581 /// Requeue a list of EntityUpdates when they were not acknowledged by the client.
3582 /// We will update the priority and put it in the correct queue, merging update flags
3583 /// with any other updates that may be queued for the same entity.
3584 /// The original update time is used for the merged update.
3585 /// </summary>
3586 void ResendPrimUpdates(List<EntityUpdate> updates)
3587 {
3588 foreach (EntityUpdate update in updates)
3589 ResendPrimUpdate(update);
3590 }
3591
3564 private void ProcessEntityUpdates(int maxUpdates) 3592 private void ProcessEntityUpdates(int maxUpdates)
3565 { 3593 {
3566 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3594 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
@@ -3568,6 +3596,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3568 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); 3596 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3569 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); 3597 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3570 3598
3599 OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3600 OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3601 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3602 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3603
3571 // Check to see if this is a flush 3604 // Check to see if this is a flush
3572 if (maxUpdates <= 0) 3605 if (maxUpdates <= 0)
3573 { 3606 {
@@ -3583,7 +3616,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3583 float avgTimeDilation = 1.0f; 3616 float avgTimeDilation = 1.0f;
3584 IEntityUpdate iupdate; 3617 IEntityUpdate iupdate;
3585 Int32 timeinqueue; // this is just debugging code & can be dropped later 3618 Int32 timeinqueue; // this is just debugging code & can be dropped later
3586 3619
3587 while (updatesThisCall < maxUpdates) 3620 while (updatesThisCall < maxUpdates)
3588 { 3621 {
3589 lock (m_entityUpdates.SyncRoot) 3622 lock (m_entityUpdates.SyncRoot)
@@ -3688,24 +3721,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3688 if (update.Entity is ScenePresence) 3721 if (update.Entity is ScenePresence)
3689 { 3722 {
3690 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3723 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3724 objectUpdates.Value.Add(update);
3691 } 3725 }
3692 else 3726 else
3693 { 3727 {
3694 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3728 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3729 objectUpdates.Value.Add(update);
3695 } 3730 }
3696 } 3731 }
3697 else if (!canUseImproved) 3732 else if (!canUseImproved)
3698 { 3733 {
3699 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3734 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3735 compressedUpdates.Value.Add(update);
3700 } 3736 }
3701 else 3737 else
3702 { 3738 {
3703 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3739 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3740 {
3704 // Self updates go into a special list 3741 // Self updates go into a special list
3705 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); 3742 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3743 terseAgentUpdates.Value.Add(update);
3744 }
3706 else 3745 else
3746 {
3707 // Everything else goes here 3747 // Everything else goes here
3708 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); 3748 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3749 terseUpdates.Value.Add(update);
3750 }
3709 } 3751 }
3710 3752
3711 #endregion Block Construction 3753 #endregion Block Construction
@@ -3713,28 +3755,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3713 3755
3714 3756
3715 #region Packet Sending 3757 #region Packet Sending
3716
3717 //const float TIME_DILATION = 1.0f;
3718
3719
3720 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3758 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3721 3759
3722 if (terseAgentUpdateBlocks.IsValueCreated) 3760 if (terseAgentUpdateBlocks.IsValueCreated)
3723 { 3761 {
3724 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3762 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3725 3763
3726 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3764 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3727 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3765 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3728 packet.RegionData.TimeDilation = timeDilation; 3766 packet.RegionData.TimeDilation = timeDilation;
3729 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3767 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3730 3768
3731 for (int i = 0; i < blocks.Count; i++) 3769 for (int i = 0; i < blocks.Count; i++)
3732 packet.ObjectData[i] = blocks[i]; 3770 packet.ObjectData[i] = blocks[i];
3733 3771 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3734 3772 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate() { ResendPrimUpdates(terseAgentUpdates.Value); });
3735 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3736 } 3773 }
3737 3774
3738 if (objectUpdateBlocks.IsValueCreated) 3775 if (objectUpdateBlocks.IsValueCreated)
3739 { 3776 {
3740 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3777 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
@@ -3746,8 +3783,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3746 3783
3747 for (int i = 0; i < blocks.Count; i++) 3784 for (int i = 0; i < blocks.Count; i++)
3748 packet.ObjectData[i] = blocks[i]; 3785 packet.ObjectData[i] = blocks[i];
3749 3786 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3750 OutPacket(packet, ThrottleOutPacketType.Task, true); 3787 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate() { ResendPrimUpdates(objectUpdates.Value); });
3751 } 3788 }
3752 3789
3753 if (compressedUpdateBlocks.IsValueCreated) 3790 if (compressedUpdateBlocks.IsValueCreated)
@@ -3761,10 +3798,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3761 3798
3762 for (int i = 0; i < blocks.Count; i++) 3799 for (int i = 0; i < blocks.Count; i++)
3763 packet.ObjectData[i] = blocks[i]; 3800 packet.ObjectData[i] = blocks[i];
3764 3801 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3765 OutPacket(packet, ThrottleOutPacketType.Task, true); 3802 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate() { ResendPrimUpdates(compressedUpdates.Value); });
3766 } 3803 }
3767 3804
3768 if (terseUpdateBlocks.IsValueCreated) 3805 if (terseUpdateBlocks.IsValueCreated)
3769 { 3806 {
3770 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3807 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
@@ -3776,8 +3813,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3776 3813
3777 for (int i = 0; i < blocks.Count; i++) 3814 for (int i = 0; i < blocks.Count; i++)
3778 packet.ObjectData[i] = blocks[i]; 3815 packet.ObjectData[i] = blocks[i];
3779 3816 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3780 OutPacket(packet, ThrottleOutPacketType.Task, true); 3817 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate() { ResendPrimUpdates(terseUpdates.Value); });
3781 } 3818 }
3782 } 3819 }
3783 3820
@@ -3969,7 +4006,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3969 { 4006 {
3970 SendFamilyProps = SendFamilyProps || update.SendFamilyProps; 4007 SendFamilyProps = SendFamilyProps || update.SendFamilyProps;
3971 SendObjectProps = SendObjectProps || update.SendObjectProps; 4008 SendObjectProps = SendObjectProps || update.SendObjectProps;
3972 Flags |= update.Flags; 4009 // other properties may need to be updated by base class
4010 base.Update(update);
3973 } 4011 }
3974 } 4012 }
3975 4013
@@ -11363,6 +11401,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11363 /// handles splitting manually</param> 11401 /// handles splitting manually</param>
11364 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting) 11402 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting)
11365 { 11403 {
11404 OutPacket(packet, throttlePacketType, doAutomaticSplitting, null);
11405 }
11406
11407 /// <summary>
11408 /// This is the starting point for sending a simulator packet out to the client
11409 /// </summary>
11410 /// <param name="packet">Packet to send</param>
11411 /// <param name="throttlePacketType">Throttling category for the packet</param>
11412 /// <param name="doAutomaticSplitting">True to automatically split oversized
11413 /// packets (the default), or false to disable splitting if the calling code
11414 /// handles splitting manually</param>
11415 /// <param name="method">The method to be called in the event this packet is reliable
11416 /// and unacknowledged. The server will provide normal resend capability if you do not
11417 /// provide your own method.</param>
11418 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
11419 {
11366 if (m_debugPacketLevel > 0) 11420 if (m_debugPacketLevel > 0)
11367 { 11421 {
11368 bool logPacket = true; 11422 bool logPacket = true;
@@ -11388,7 +11442,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11388 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); 11442 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type);
11389 } 11443 }
11390 11444
11391 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); 11445 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
11392 } 11446 }
11393 11447
11394 public bool AddMoney(int debit) 11448 public bool AddMoney(int debit)