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