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