diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 306 |
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 |