aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs278
1 files changed, 128 insertions, 150 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 9398c28..f125822 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3553,116 +3553,111 @@ 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>>();
3557 3556
3558 if (maxUpdates <= 0) maxUpdates = Int32.MaxValue; 3557 if (maxUpdates <= 0) maxUpdates = Int32.MaxValue;
3559 int updatesThisCall = 0; 3558 int updatesThisCall = 0;
3560 3559
3561 EntityUpdate update; 3560 lock (m_entityUpdates.SyncRoot)
3562 while (updatesThisCall < maxUpdates)
3563 { 3561 {
3564 lock (m_entityUpdates.SyncRoot) 3562 EntityUpdate update;
3565 { 3563 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update))
3566 if (!m_entityUpdates.TryDequeue(out update))
3567 break;
3568 }
3569
3570 if (update.Entity is SceneObjectPart)
3571 { 3564 {
3572 SceneObjectPart part = (SceneObjectPart)update.Entity; 3565 if (update.Entity is SceneObjectPart)
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))
3585 { 3566 {
3586 // m_log.WarnFormat( 3567 SceneObjectPart part = (SceneObjectPart)update.Entity;
3587 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3568
3588 // part.LocalId, Name); 3569 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3589 continue; 3570 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3590 } 3571 // safety measure.
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 }
3591 3586
3592 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3587 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)
3596 { 3588 {
3597 part.Shape.LightEntry = false; 3589 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3590 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3591 {
3592 part.Shape.LightEntry = false;
3593 }
3598 } 3594 }
3599 } 3595 }
3600 }
3601 3596
3602 ++updatesThisCall; 3597 ++updatesThisCall;
3603 3598
3604 #region UpdateFlags to packet type conversion 3599 #region UpdateFlags to packet type conversion
3605 3600
3606 PrimUpdateFlags updateFlags = update.Flags; 3601 PrimUpdateFlags updateFlags = update.Flags;
3607 3602
3608 bool canUseCompressed = true; 3603 bool canUseCompressed = true;
3609 bool canUseImproved = true; 3604 bool canUseImproved = true;
3610 3605
3611 // Compressed object updates only make sense for LL primitives 3606 // Compressed object updates only make sense for LL primitives
3612 if (!(update.Entity is SceneObjectPart)) 3607 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))
3628 { 3608 {
3629 canUseCompressed = false; 3609 canUseCompressed = false;
3630 } 3610 }
3631 3611
3632 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) || 3612 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
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))
3646 { 3613 {
3614 canUseCompressed = false;
3647 canUseImproved = false; 3615 canUseImproved = false;
3648 } 3616 }
3649 } 3617 else
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 }
3650 3645
3651 #endregion UpdateFlags to packet type conversion 3646 #endregion UpdateFlags to packet type conversion
3652 3647
3653 #region Block Construction 3648 #region Block Construction
3654 3649
3655 // TODO: Remove this once we can build compressed updates 3650 // TODO: Remove this once we can build compressed updates
3656 canUseCompressed = false; 3651 canUseCompressed = false;
3657 3652
3658 if (!canUseImproved && !canUseCompressed) 3653 if (!canUseImproved && !canUseCompressed)
3659 {
3660 if (update.Entity is ScenePresence)
3661 {
3662 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3663 }
3664 else
3665 { 3654 {
3655 if (update.Entity is ScenePresence)
3656 {
3657 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3658 }
3659 else
3660 {
3666// if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment) 3661// if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment)
3667// { 3662// {
3668// SceneObjectPart sop = (SceneObjectPart)update.Entity; 3663// SceneObjectPart sop = (SceneObjectPart)update.Entity;
@@ -3691,88 +3686,71 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3691// } 3686// }
3692// else 3687// else
3693// { 3688// {
3694 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3689 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3695// } 3690// }
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)));
3706 else 3697 else
3698 {
3707 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); 3699 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3708 } 3700 }
3709 3701
3710 #endregion Block Construction 3702 #endregion Block Construction
3711 } 3703 }
3712 3704
3713 #region Packet Sending 3705 #region Packet Sending
3714 3706
3715 const float TIME_DILATION = 1.0f; 3707 const float TIME_DILATION = 1.0f;
3716 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); 3708 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
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;
3751 3709
3752 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3710 if (objectUpdateBlocks.IsValueCreated)
3753 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3711 {
3754 packet.RegionData.TimeDilation = timeDilation; 3712 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3755 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3756 3713
3757 for (int i = 0; i < blocks.Count; i++) 3714 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3758 packet.ObjectData[i] = blocks[i]; 3715 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3716 packet.RegionData.TimeDilation = timeDilation;
3717 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3759 3718
3760 OutPacket(packet, ThrottleOutPacketType.Task, true); 3719 for (int i = 0; i < blocks.Count; i++)
3761 } 3720 packet.ObjectData[i] = blocks[i];
3762 3721
3763 if (compressedUpdateBlocks.IsValueCreated) 3722 OutPacket(packet, ThrottleOutPacketType.Task, true);
3764 { 3723 }
3765 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3766 3724
3767 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 3725 if (compressedUpdateBlocks.IsValueCreated)
3768 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3726 {
3769 packet.RegionData.TimeDilation = timeDilation; 3727 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3770 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3771 3728
3772 for (int i = 0; i < blocks.Count; i++) 3729 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3773 packet.ObjectData[i] = blocks[i]; 3730 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3731 packet.RegionData.TimeDilation = timeDilation;
3732 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3774 3733
3775 OutPacket(packet, ThrottleOutPacketType.Task, true); 3734 for (int i = 0; i < blocks.Count; i++)
3735 packet.ObjectData[i] = blocks[i];
3736
3737 OutPacket(packet, ThrottleOutPacketType.Task, true);
3738 }
3739
3740 if (terseUpdateBlocks.IsValueCreated)
3741 {
3742 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3743
3744 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3745 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3746 packet.RegionData.TimeDilation = timeDilation;
3747 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3748
3749 for (int i = 0; i < blocks.Count; i++)
3750 packet.ObjectData[i] = blocks[i];
3751
3752 OutPacket(packet, ThrottleOutPacketType.Task, true);
3753 }
3776 } 3754 }
3777 3755
3778 #endregion Packet Sending 3756 #endregion Packet Sending