aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs306
1 files changed, 169 insertions, 137 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 612c0d9..6a76069 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3589,129 +3589,142 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3589 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3589 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
3590 OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>(); 3590 OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
3591 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); 3591 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3592 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3592 3593
3593 if (maxUpdates <= 0) maxUpdates = Int32.MaxValue; 3594 if (maxUpdates <= 0) maxUpdates = Int32.MaxValue;
3594 int updatesThisCall = 0; 3595 int updatesThisCall = 0;
3595 3596
3596 lock (m_entityUpdates.SyncRoot) 3597 EntityUpdate update;
3598 while (updatesThisCall < maxUpdates)
3597 { 3599 {
3598 EntityUpdate update; 3600 lock (m_entityUpdates.SyncRoot)
3599 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update)) 3601 if (!m_entityUpdates.TryDequeue(out update))
3600 { 3602 break;
3601 if (update.Entity is SceneObjectPart)
3602 {
3603 SceneObjectPart part = (SceneObjectPart)update.Entity;
3604 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3605 continue;
3606 3603
3607 if (m_killRecord.Contains(part.LocalId)) 3604 if (update.Entity is SceneObjectPart)
3605 {
3606 SceneObjectPart part = (SceneObjectPart)update.Entity;
3607
3608 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3609 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3610 // safety measure.
3611 //
3612 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3613 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3614 // updates and kills on different threads with different scheduling strategies, hence this protection.
3615 //
3616 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3617 // after the root prim has been deleted.
3618 if (m_killRecord.Contains(part.LocalId))
3619 continue;
3620 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3621 continue;
3622
3623 if (part.ParentGroup.IsDeleted)
3624 continue;
3625
3626 if (part.ParentGroup.IsAttachment)
3627 { // Someone else's HUD, why are we getting these?
3628 if (part.ParentGroup.OwnerID != AgentId &&
3629 part.ParentGroup.RootPart.Shape.State >= 30)
3608 continue; 3630 continue;
3609 3631 ScenePresence sp;
3610 if (part.ParentGroup.IsDeleted) 3632 // Owner is not in the sim, don't update it to
3633 // anyone
3634 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3611 continue; 3635 continue;
3612 3636
3613 if (part.ParentGroup.IsAttachment) 3637 List<SceneObjectGroup> atts = sp.Attachments;
3614 { // Someone else's HUD, why are we getting these? 3638 bool found = false;
3615 if (part.ParentGroup.OwnerID != AgentId && 3639 foreach (SceneObjectGroup att in atts)
3616 part.ParentGroup.RootPart.Shape.State >= 30) 3640 {
3617 continue; 3641 if (att == part.ParentGroup)
3618 ScenePresence sp;
3619 // Owner is not in the sim, don't update it to
3620 // anyone
3621 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3622 continue;
3623
3624 List<SceneObjectGroup> atts = sp.Attachments;
3625 bool found = false;
3626 foreach (SceneObjectGroup att in atts)
3627 { 3642 {
3628 if (att == part.ParentGroup) 3643 found = true;
3629 { 3644 break;
3630 found = true;
3631 break;
3632 }
3633 } 3645 }
3634
3635 // It's an attachment of a valid avatar, but
3636 // doesn't seem to be attached, skip
3637 if (!found)
3638 continue;
3639 } 3646 }
3640 3647
3641 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3648 // It's an attachment of a valid avatar, but
3649 // doesn't seem to be attached, skip
3650 if (!found)
3651 continue;
3652 }
3653
3654 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3655 {
3656 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3657 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3642 { 3658 {
3643 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3659 part.Shape.LightEntry = false;
3644 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3645 {
3646 part.Shape.LightEntry = false;
3647 }
3648 } 3660 }
3649 } 3661 }
3662 }
3650 3663
3651 ++updatesThisCall; 3664 ++updatesThisCall;
3652 3665
3653 #region UpdateFlags to packet type conversion 3666 #region UpdateFlags to packet type conversion
3654 3667
3655 PrimUpdateFlags updateFlags = update.Flags; 3668 PrimUpdateFlags updateFlags = update.Flags;
3656 3669
3657 bool canUseCompressed = true; 3670 bool canUseCompressed = true;
3658 bool canUseImproved = true; 3671 bool canUseImproved = true;
3659 3672
3660 // Compressed object updates only make sense for LL primitives 3673 // Compressed object updates only make sense for LL primitives
3661 if (!(update.Entity is SceneObjectPart)) 3674 if (!(update.Entity is SceneObjectPart))
3675 {
3676 canUseCompressed = false;
3677 }
3678
3679 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3680 {
3681 canUseCompressed = false;
3682 canUseImproved = false;
3683 }
3684 else
3685 {
3686 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3687 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3688 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3689 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3662 { 3690 {
3663 canUseCompressed = false; 3691 canUseCompressed = false;
3664 } 3692 }
3665 3693
3666 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3694 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3695 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3696 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3697 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3698 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3699 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3700 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3701 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3702 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3703 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3704 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3705 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3706 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3707 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3667 { 3708 {
3668 canUseCompressed = false;
3669 canUseImproved = false; 3709 canUseImproved = false;
3670 } 3710 }
3671 else 3711 }
3672 {
3673 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3674 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3675 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3676 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3677 {
3678 canUseCompressed = false;
3679 }
3680
3681 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3682 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3683 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3684 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3685 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3686 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3687 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3688 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3689 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3690 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3691 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3692 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3693 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3694 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3695 {
3696 canUseImproved = false;
3697 }
3698 }
3699 3712
3700 #endregion UpdateFlags to packet type conversion 3713 #endregion UpdateFlags to packet type conversion
3701 3714
3702 #region Block Construction 3715 #region Block Construction
3703 3716
3704 // TODO: Remove this once we can build compressed updates 3717 // TODO: Remove this once we can build compressed updates
3705 canUseCompressed = false; 3718 canUseCompressed = false;
3706 3719
3707 if (!canUseImproved && !canUseCompressed) 3720 if (!canUseImproved && !canUseCompressed)
3721 {
3722 if (update.Entity is ScenePresence)
3723 {
3724 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3725 }
3726 else
3708 { 3727 {
3709 if (update.Entity is ScenePresence)
3710 {
3711 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3712 }
3713 else
3714 {
3715// if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment) 3728// if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment)
3716// { 3729// {
3717// SceneObjectPart sop = (SceneObjectPart)update.Entity; 3730// SceneObjectPart sop = (SceneObjectPart)update.Entity;
@@ -3740,71 +3753,90 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3740// } 3753// }
3741// else 3754// else
3742// { 3755// {
3743 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3756 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3744// } 3757// }
3745 }
3746 }
3747 else if (!canUseImproved)
3748 {
3749 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3750 } 3758 }
3759 }
3760 else if (!canUseImproved)
3761 {
3762 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3763 }
3764 else
3765 {
3766 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3767 // Self updates go into a special list
3768 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3751 else 3769 else
3752 { 3770 // Everything else goes here
3753 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); 3771 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3754 }
3755
3756 #endregion Block Construction
3757 } 3772 }
3758 3773
3759 #region Packet Sending 3774 #endregion Block Construction
3760 3775 }
3761 const float TIME_DILATION = 1.0f; 3776
3762 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); 3777 #region Packet Sending
3763 3778
3764 if (objectUpdateBlocks.IsValueCreated) 3779 const float TIME_DILATION = 1.0f;
3765 { 3780 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
3766 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3781
3782 if (terseAgentUpdateBlocks.IsValueCreated)
3783 {
3784 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3785
3786 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3787 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3788 packet.RegionData.TimeDilation = timeDilation;
3789 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3790
3791 for (int i = 0; i < blocks.Count; i++)
3792 packet.ObjectData[i] = blocks[i];
3793
3794 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3795 }
3796
3797 if (objectUpdateBlocks.IsValueCreated)
3798 {
3799 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3767 3800
3768 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3801 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3769 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3802 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3770 packet.RegionData.TimeDilation = timeDilation; 3803 packet.RegionData.TimeDilation = timeDilation;
3771 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3804 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3772 3805
3773 for (int i = 0; i < blocks.Count; i++) 3806 for (int i = 0; i < blocks.Count; i++)
3774 packet.ObjectData[i] = blocks[i]; 3807 packet.ObjectData[i] = blocks[i];
3775 3808
3776 OutPacket(packet, ThrottleOutPacketType.Task, true); 3809 OutPacket(packet, ThrottleOutPacketType.Task, true);
3777 } 3810 }
3778 3811
3779 if (compressedUpdateBlocks.IsValueCreated) 3812 if (compressedUpdateBlocks.IsValueCreated)
3780 { 3813 {
3781 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3814 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3782 3815
3783 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 3816 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3784 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3817 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3785 packet.RegionData.TimeDilation = timeDilation; 3818 packet.RegionData.TimeDilation = timeDilation;
3786 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 3819 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3787 3820
3788 for (int i = 0; i < blocks.Count; i++) 3821 for (int i = 0; i < blocks.Count; i++)
3789 packet.ObjectData[i] = blocks[i]; 3822 packet.ObjectData[i] = blocks[i];
3790 3823
3791 OutPacket(packet, ThrottleOutPacketType.Task, true); 3824 OutPacket(packet, ThrottleOutPacketType.Task, true);
3792 } 3825 }
3793 3826
3794 if (terseUpdateBlocks.IsValueCreated) 3827 if (terseUpdateBlocks.IsValueCreated)
3795 { 3828 {
3796 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3829 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3797 3830
3798 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3831 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3799 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3832 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3800 packet.RegionData.TimeDilation = timeDilation; 3833 packet.RegionData.TimeDilation = timeDilation;
3801 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3834 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3802 3835
3803 for (int i = 0; i < blocks.Count; i++) 3836 for (int i = 0; i < blocks.Count; i++)
3804 packet.ObjectData[i] = blocks[i]; 3837 packet.ObjectData[i] = blocks[i];
3805 3838
3806 OutPacket(packet, ThrottleOutPacketType.Task, true); 3839 OutPacket(packet, ThrottleOutPacketType.Task, true);
3807 }
3808 } 3840 }
3809 3841
3810 #endregion Packet Sending 3842 #endregion Packet Sending