diff options
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 287 |
1 files changed, 122 insertions, 165 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 5b2484d..4abb6e2 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -3703,209 +3703,166 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3703 | 3703 | ||
3704 | int updatesThisCall = 0; | 3704 | int updatesThisCall = 0; |
3705 | 3705 | ||
3706 | //<MIC> | ||
3707 | // DEBUGGING CODE... REMOVE | ||
3708 | // LogQueueProcessEvent(this.m_agentId,m_entityUpdates,m_maxUpdates); | ||
3709 | //</MIC> | ||
3710 | // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race | 3706 | // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race |
3711 | // condition where a kill can be processed before an out-of-date update for the same object. | 3707 | // condition where a kill can be processed before an out-of-date update for the same object. |
3712 | float avgTimeDilation = 1.0f; | 3708 | float avgTimeDilation = 1.0f; |
3713 | 3709 | ||
3714 | lock (m_killRecord) | 3710 | EntityUpdate update; |
3711 | Int32 timeinqueue; // this is just debugging code & can be dropped later | ||
3712 | |||
3713 | while (updatesThisCall < m_maxUpdates) | ||
3715 | { | 3714 | { |
3716 | EntityUpdate update; | 3715 | lock (m_entityUpdates.SyncRoot) |
3717 | Int32 timeinqueue; // this is just debugging code & can be dropped later | 3716 | if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) |
3718 | 3717 | break; | |
3719 | while (updatesThisCall < m_maxUpdates) | 3718 | avgTimeDilation += update.TimeDilation; |
3720 | { | 3719 | avgTimeDilation *= 0.5f; |
3721 | lock (m_entityUpdates.SyncRoot) | 3720 | |
3722 | if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) | 3721 | if (update.Entity is SceneObjectPart) |
3723 | break; | 3722 | { |
3724 | avgTimeDilation += update.TimeDilation; | 3723 | SceneObjectPart part = (SceneObjectPart)update.Entity; |
3725 | avgTimeDilation *= 0.5f; | 3724 | |
3726 | 3725 | // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client | |
3727 | if (update.Entity is SceneObjectPart) | 3726 | // will never receive an update after a prim kill. Even then, keeping the kill record may be a good |
3727 | // safety measure. | ||
3728 | // | ||
3729 | // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update | ||
3730 | // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs | ||
3731 | // updates and kills on different threads with different scheduling strategies, hence this protection. | ||
3732 | // | ||
3733 | // This doesn't appear to apply to child prims - a client will happily ignore these updates | ||
3734 | // after the root prim has been deleted. | ||
3735 | lock (m_killRecord) | ||
3728 | { | 3736 | { |
3729 | SceneObjectPart part = (SceneObjectPart)update.Entity; | 3737 | if (m_killRecord.Contains(part.LocalId)) |
3730 | 3738 | continue; | |
3731 | // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client | 3739 | if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId)) |
3732 | // will never receive an update after a prim kill. Even then, keeping the kill record may be a good | 3740 | continue; |
3733 | // safety measure. | 3741 | } |
3734 | // | ||
3735 | // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update | ||
3736 | // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs | ||
3737 | // updates and kills on different threads with different scheduling strategies, hence this protection. | ||
3738 | // | ||
3739 | // This doesn't appear to apply to child prims - a client will happily ignore these updates | ||
3740 | // after the root prim has been deleted. | ||
3741 | lock (m_killRecord) | ||
3742 | { | ||
3743 | if (m_killRecord.Contains(part.LocalId)) | ||
3744 | continue; | ||
3745 | if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId)) | ||
3746 | continue; | ||
3747 | } | ||
3748 | 3742 | ||
3749 | if (part.ParentGroup.IsDeleted) | 3743 | if (part.ParentGroup.IsDeleted) |
3744 | continue; | ||
3745 | |||
3746 | if (part.ParentGroup.IsAttachment) | ||
3747 | { // Someone else's HUD, why are we getting these? | ||
3748 | if (part.ParentGroup.OwnerID != AgentId && | ||
3749 | part.ParentGroup.RootPart.Shape.State >= 30) | ||
3750 | continue; | ||
3751 | ScenePresence sp; | ||
3752 | // Owner is not in the sim, don't update it to | ||
3753 | // anyone | ||
3754 | if (!m_scene.TryGetScenePresence(part.OwnerID, out sp)) | ||
3750 | continue; | 3755 | continue; |
3751 | 3756 | ||
3752 | if (part.ParentGroup.IsAttachment) | 3757 | List<SceneObjectGroup> atts = sp.Attachments; |
3753 | { // Someone else's HUD, why are we getting these? | 3758 | bool found = false; |
3754 | if (part.ParentGroup.OwnerID != AgentId && | 3759 | foreach (SceneObjectGroup att in atts) |
3755 | part.ParentGroup.RootPart.Shape.State >= 30) | 3760 | { |
3756 | continue; | 3761 | if (att == part.ParentGroup) |
3757 | ScenePresence sp; | ||
3758 | // Owner is not in the sim, don't update it to | ||
3759 | // anyone | ||
3760 | if (!m_scene.TryGetScenePresence(part.OwnerID, out sp)) | ||
3761 | continue; | ||
3762 | |||
3763 | List<SceneObjectGroup> atts = sp.Attachments; | ||
3764 | bool found = false; | ||
3765 | foreach (SceneObjectGroup att in atts) | ||
3766 | { | 3762 | { |
3767 | if (att == part.ParentGroup) | 3763 | found = true; |
3768 | { | 3764 | break; |
3769 | found = true; | ||
3770 | break; | ||
3771 | } | ||
3772 | } | 3765 | } |
3773 | |||
3774 | // It's an attachment of a valid avatar, but | ||
3775 | // doesn't seem to be attached, skip | ||
3776 | if (!found) | ||
3777 | continue; | ||
3778 | } | 3766 | } |
3779 | 3767 | ||
3780 | if (part.ParentGroup.IsAttachment && m_disableFacelights) | 3768 | // It's an attachment of a valid avatar, but |
3769 | // doesn't seem to be attached, skip | ||
3770 | if (!found) | ||
3771 | continue; | ||
3772 | } | ||
3773 | |||
3774 | if (part.ParentGroup.IsAttachment && m_disableFacelights) | ||
3775 | { | ||
3776 | if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && | ||
3777 | part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand) | ||
3781 | { | 3778 | { |
3782 | if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && | 3779 | part.Shape.LightEntry = false; |
3783 | part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand) | ||
3784 | { | ||
3785 | part.Shape.LightEntry = false; | ||
3786 | } | ||
3787 | } | 3780 | } |
3788 | } | 3781 | } |
3782 | } | ||
3783 | |||
3784 | ++updatesThisCall; | ||
3789 | 3785 | ||
3790 | ++updatesThisCall; | 3786 | #region UpdateFlags to packet type conversion |
3791 | 3787 | ||
3792 | #region UpdateFlags to packet type conversion | 3788 | PrimUpdateFlags updateFlags = update.Flags; |
3793 | 3789 | ||
3794 | PrimUpdateFlags updateFlags = update.Flags; | 3790 | bool canUseCompressed = true; |
3791 | bool canUseImproved = true; | ||
3795 | 3792 | ||
3796 | bool canUseCompressed = true; | 3793 | // Compressed object updates only make sense for LL primitives |
3797 | bool canUseImproved = true; | 3794 | if (!(update.Entity is SceneObjectPart)) |
3795 | { | ||
3796 | canUseCompressed = false; | ||
3797 | } | ||
3798 | 3798 | ||
3799 | // Compressed object updates only make sense for LL primitives | 3799 | if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) |
3800 | if (!(update.Entity is SceneObjectPart)) | 3800 | { |
3801 | canUseCompressed = false; | ||
3802 | canUseImproved = false; | ||
3803 | } | ||
3804 | else | ||
3805 | { | ||
3806 | if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || | ||
3807 | updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || | ||
3808 | updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) || | ||
3809 | updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||
3801 | { | 3810 | { |
3802 | canUseCompressed = false; | 3811 | canUseCompressed = false; |
3803 | } | 3812 | } |
3804 | 3813 | ||
3805 | if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) | 3814 | if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) || |
3815 | updateFlags.HasFlag(PrimUpdateFlags.ParentID) || | ||
3816 | updateFlags.HasFlag(PrimUpdateFlags.Scale) || | ||
3817 | updateFlags.HasFlag(PrimUpdateFlags.PrimData) || | ||
3818 | updateFlags.HasFlag(PrimUpdateFlags.Text) || | ||
3819 | updateFlags.HasFlag(PrimUpdateFlags.NameValue) || | ||
3820 | updateFlags.HasFlag(PrimUpdateFlags.ExtraData) || | ||
3821 | updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) || | ||
3822 | updateFlags.HasFlag(PrimUpdateFlags.Sound) || | ||
3823 | updateFlags.HasFlag(PrimUpdateFlags.Particles) || | ||
3824 | updateFlags.HasFlag(PrimUpdateFlags.Material) || | ||
3825 | updateFlags.HasFlag(PrimUpdateFlags.ClickAction) || | ||
3826 | updateFlags.HasFlag(PrimUpdateFlags.MediaURL) || | ||
3827 | updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||
3806 | { | 3828 | { |
3807 | canUseCompressed = false; | ||
3808 | canUseImproved = false; | 3829 | canUseImproved = false; |
3809 | } | 3830 | } |
3810 | else | 3831 | } |
3811 | { | ||
3812 | if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || | ||
3813 | updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || | ||
3814 | updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) || | ||
3815 | updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||
3816 | { | ||
3817 | if (update.Entity is ScenePresence) | ||
3818 | { | ||
3819 | objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); | ||
3820 | } | ||
3821 | else | ||
3822 | { | ||
3823 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); | ||
3824 | } | ||
3825 | } | ||
3826 | |||
3827 | if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) || | ||
3828 | updateFlags.HasFlag(PrimUpdateFlags.ParentID) || | ||
3829 | updateFlags.HasFlag(PrimUpdateFlags.Scale) || | ||
3830 | updateFlags.HasFlag(PrimUpdateFlags.PrimData) || | ||
3831 | updateFlags.HasFlag(PrimUpdateFlags.Text) || | ||
3832 | updateFlags.HasFlag(PrimUpdateFlags.NameValue) || | ||
3833 | updateFlags.HasFlag(PrimUpdateFlags.ExtraData) || | ||
3834 | updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) || | ||
3835 | updateFlags.HasFlag(PrimUpdateFlags.Sound) || | ||
3836 | updateFlags.HasFlag(PrimUpdateFlags.Particles) || | ||
3837 | updateFlags.HasFlag(PrimUpdateFlags.Material) || | ||
3838 | updateFlags.HasFlag(PrimUpdateFlags.ClickAction) || | ||
3839 | updateFlags.HasFlag(PrimUpdateFlags.MediaURL) || | ||
3840 | updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||
3841 | { | ||
3842 | canUseImproved = false; | ||
3843 | } | ||
3844 | } | ||
3845 | 3832 | ||
3846 | #endregion UpdateFlags to packet type conversion | 3833 | #endregion UpdateFlags to packet type conversion |
3847 | 3834 | ||
3848 | #region Block Construction | 3835 | #region Block Construction |
3849 | 3836 | ||
3850 | // TODO: Remove this once we can build compressed updates | 3837 | // TODO: Remove this once we can build compressed updates |
3851 | canUseCompressed = false; | 3838 | canUseCompressed = false; |
3852 | 3839 | ||
3853 | if (!canUseImproved && !canUseCompressed) | 3840 | if (!canUseImproved && !canUseCompressed) |
3854 | { | 3841 | { |
3855 | if (update.Entity is ScenePresence) | 3842 | if (update.Entity is ScenePresence) |
3856 | { | ||
3857 | objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); | ||
3858 | } | ||
3859 | else | ||
3860 | { | ||
3861 | // if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment) | ||
3862 | // { | ||
3863 | // SceneObjectPart sop = (SceneObjectPart)update.Entity; | ||
3864 | // string text = sop.Text; | ||
3865 | // if (text.IndexOf("\n") >= 0) | ||
3866 | // text = text.Remove(text.IndexOf("\n")); | ||
3867 | // | ||
3868 | // if (m_attachmentsSent.Contains(sop.ParentID)) | ||
3869 | // { | ||
3870 | //// m_log.DebugFormat( | ||
3871 | //// "[CLIENT]: Sending full info about attached prim {0} text {1}", | ||
3872 | //// sop.LocalId, text); | ||
3873 | // | ||
3874 | // objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock(sop, this.m_agentId)); | ||
3875 | // | ||
3876 | // m_attachmentsSent.Add(sop.LocalId); | ||
3877 | // } | ||
3878 | // else | ||
3879 | // { | ||
3880 | // m_log.DebugFormat( | ||
3881 | // "[CLIENT]: Requeueing full update of prim {0} text {1} since we haven't sent its parent {2} yet", | ||
3882 | // sop.LocalId, text, sop.ParentID); | ||
3883 | // | ||
3884 | // m_entityUpdates.Enqueue(double.MaxValue, update, sop.LocalId); | ||
3885 | // } | ||
3886 | // } | ||
3887 | // else | ||
3888 | // { | ||
3889 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); | ||
3890 | // } | ||
3891 | } | ||
3892 | } | ||
3893 | else if (!canUseImproved) | ||
3894 | { | 3843 | { |
3895 | compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); | 3844 | objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); |
3896 | } | 3845 | } |
3897 | else | 3846 | else |
3898 | { | 3847 | { |
3899 | if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) | 3848 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); |
3900 | // Self updates go into a special list | ||
3901 | terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); | ||
3902 | else | ||
3903 | // Everything else goes here | ||
3904 | terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); | ||
3905 | } | 3849 | } |
3906 | |||
3907 | #endregion Block Construction | ||
3908 | } | 3850 | } |
3851 | else if (!canUseImproved) | ||
3852 | { | ||
3853 | compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); | ||
3854 | } | ||
3855 | else | ||
3856 | { | ||
3857 | if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) | ||
3858 | // Self updates go into a special list | ||
3859 | terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); | ||
3860 | else | ||
3861 | // Everything else goes here | ||
3862 | terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); | ||
3863 | } | ||
3864 | |||
3865 | #endregion Block Construction | ||
3909 | } | 3866 | } |
3910 | 3867 | ||
3911 | #region Packet Sending | 3868 | #region Packet Sending |