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.cs253
1 files changed, 127 insertions, 126 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index c934b9e..979dd47 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3557,107 +3557,109 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3557 if (maxUpdates <= 0) maxUpdates = Int32.MaxValue; 3557 if (maxUpdates <= 0) maxUpdates = Int32.MaxValue;
3558 int updatesThisCall = 0; 3558 int updatesThisCall = 0;
3559 3559
3560 lock (m_entityUpdates.SyncRoot) 3560 EntityUpdate update;
3561 while (updatesThisCall < maxUpdates)
3561 { 3562 {
3562 EntityUpdate update; 3563 lock (m_entityUpdates.SyncRoot)
3563 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update)) 3564 if (!m_entityUpdates.TryDequeue(out update))
3564 { 3565 break;
3565 if (update.Entity is SceneObjectPart) 3566
3567 if (update.Entity is SceneObjectPart)
3568 {
3569 SceneObjectPart part = (SceneObjectPart)update.Entity;
3570
3571 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3572 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3573 // safety measure.
3574 //
3575 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3576 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3577 // updates and kills on different threads with different scheduling strategies, hence this protection.
3578 //
3579 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3580 // after the root prim has been deleted.
3581 if (m_killRecord.Contains(part.LocalId))
3566 { 3582 {
3567 SceneObjectPart part = (SceneObjectPart)update.Entity; 3583 // m_log.WarnFormat(
3568 3584 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3569 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3585 // part.LocalId, Name);
3570 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3586 continue;
3571 // safety measure. 3587 }
3572 //
3573 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3574 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3575 // updates and kills on different threads with different scheduling strategies, hence this protection.
3576 //
3577 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3578 // after the root prim has been deleted.
3579 if (m_killRecord.Contains(part.LocalId))
3580 {
3581 // m_log.WarnFormat(
3582 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3583 // part.LocalId, Name);
3584 continue;
3585 }
3586 3588
3587 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3589 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3590 {
3591 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3592 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3588 { 3593 {
3589 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3594 part.Shape.LightEntry = false;
3590 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3591 {
3592 part.Shape.LightEntry = false;
3593 }
3594 } 3595 }
3595 } 3596 }
3597 }
3596 3598
3597 ++updatesThisCall; 3599 ++updatesThisCall;
3598 3600
3599 #region UpdateFlags to packet type conversion 3601 #region UpdateFlags to packet type conversion
3600 3602
3601 PrimUpdateFlags updateFlags = update.Flags; 3603 PrimUpdateFlags updateFlags = update.Flags;
3602 3604
3603 bool canUseCompressed = true; 3605 bool canUseCompressed = true;
3604 bool canUseImproved = true; 3606 bool canUseImproved = true;
3605 3607
3606 // Compressed object updates only make sense for LL primitives 3608 // Compressed object updates only make sense for LL primitives
3607 if (!(update.Entity is SceneObjectPart)) 3609 if (!(update.Entity is SceneObjectPart))
3610 {
3611 canUseCompressed = false;
3612 }
3613
3614 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3615 {
3616 canUseCompressed = false;
3617 canUseImproved = false;
3618 }
3619 else
3620 {
3621 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3622 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3623 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3624 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3608 { 3625 {
3609 canUseCompressed = false; 3626 canUseCompressed = false;
3610 } 3627 }
3611 3628
3612 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3629 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3630 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3631 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3632 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3633 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3634 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3635 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3636 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3637 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3638 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3639 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3640 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3641 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3642 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3613 { 3643 {
3614 canUseCompressed = false;
3615 canUseImproved = false; 3644 canUseImproved = false;
3616 } 3645 }
3617 else 3646 }
3618 {
3619 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3620 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3621 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3622 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3623 {
3624 canUseCompressed = false;
3625 }
3626 3647
3627 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) || 3648 #endregion UpdateFlags to packet type conversion
3628 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3629 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3630 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3631 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3632 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3633 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3634 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3635 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3636 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3637 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3638 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3639 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3640 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3641 {
3642 canUseImproved = false;
3643 }
3644 }
3645 3649
3646 #endregion UpdateFlags to packet type conversion 3650 #region Block Construction
3647 3651
3648 #region Block Construction 3652 // TODO: Remove this once we can build compressed updates
3653 canUseCompressed = false;
3649 3654
3650 // TODO: Remove this once we can build compressed updates 3655 if (!canUseImproved && !canUseCompressed)
3651 canUseCompressed = false; 3656 {
3652 3657 if (update.Entity is ScenePresence)
3653 if (!canUseImproved && !canUseCompressed) 3658 {
3659 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3660 }
3661 else
3654 { 3662 {
3655 if (update.Entity is ScenePresence)
3656 {
3657 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3658 }
3659 else
3660 {
3661// if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment) 3663// if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment)
3662// { 3664// {
3663// SceneObjectPart sop = (SceneObjectPart)update.Entity; 3665// SceneObjectPart sop = (SceneObjectPart)update.Entity;
@@ -3686,71 +3688,70 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3686// } 3688// }
3687// else 3689// else
3688// { 3690// {
3689 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3691 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3690// } 3692// }
3691 }
3692 }
3693 else if (!canUseImproved)
3694 {
3695 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3696 }
3697 else
3698 {
3699 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3700 } 3693 }
3701 3694 }
3702 #endregion Block Construction 3695 else if (!canUseImproved)
3696 {
3697 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3698 }
3699 else
3700 {
3701 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3703 } 3702 }
3704 3703
3705 #region Packet Sending 3704 #endregion Block Construction
3705 }
3706
3707 #region Packet Sending
3706 3708
3707 const float TIME_DILATION = 1.0f; 3709 const float TIME_DILATION = 1.0f;
3708 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); 3710 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
3709 3711
3710 if (objectUpdateBlocks.IsValueCreated) 3712 if (objectUpdateBlocks.IsValueCreated)
3711 { 3713 {
3712 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3714 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3713 3715
3714 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3716 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3715 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3717 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3716 packet.RegionData.TimeDilation = timeDilation; 3718 packet.RegionData.TimeDilation = timeDilation;
3717 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3719 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3718 3720
3719 for (int i = 0; i < blocks.Count; i++) 3721 for (int i = 0; i < blocks.Count; i++)
3720 packet.ObjectData[i] = blocks[i]; 3722 packet.ObjectData[i] = blocks[i];
3721 3723
3722 OutPacket(packet, ThrottleOutPacketType.Task, true); 3724 OutPacket(packet, ThrottleOutPacketType.Task, true);
3723 } 3725 }
3724 3726
3725 if (compressedUpdateBlocks.IsValueCreated) 3727 if (compressedUpdateBlocks.IsValueCreated)
3726 { 3728 {
3727 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3729 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3728 3730
3729 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 3731 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3730 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3732 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3731 packet.RegionData.TimeDilation = timeDilation; 3733 packet.RegionData.TimeDilation = timeDilation;
3732 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 3734 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3733 3735
3734 for (int i = 0; i < blocks.Count; i++) 3736 for (int i = 0; i < blocks.Count; i++)
3735 packet.ObjectData[i] = blocks[i]; 3737 packet.ObjectData[i] = blocks[i];
3736 3738
3737 OutPacket(packet, ThrottleOutPacketType.Task, true); 3739 OutPacket(packet, ThrottleOutPacketType.Task, true);
3738 } 3740 }
3739 3741
3740 if (terseUpdateBlocks.IsValueCreated) 3742 if (terseUpdateBlocks.IsValueCreated)
3741 { 3743 {
3742 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3744 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3743 3745
3744 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3746 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3745 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3747 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3746 packet.RegionData.TimeDilation = timeDilation; 3748 packet.RegionData.TimeDilation = timeDilation;
3747 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3749 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3748 3750
3749 for (int i = 0; i < blocks.Count; i++) 3751 for (int i = 0; i < blocks.Count; i++)
3750 packet.ObjectData[i] = blocks[i]; 3752 packet.ObjectData[i] = blocks[i];
3751 3753
3752 OutPacket(packet, ThrottleOutPacketType.Task, true); 3754 OutPacket(packet, ThrottleOutPacketType.Task, true);
3753 }
3754 } 3755 }
3755 3756
3756 #endregion Packet Sending 3757 #endregion Packet Sending