diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 282 |
1 files changed, 154 insertions, 128 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index f125822..2a59a0c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -3553,111 +3553,114 @@ 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 | if (!m_entityUpdates.TryDequeue(out update)) |
3564 | { | 3566 | break; |
3565 | if (update.Entity is SceneObjectPart) | 3567 | |
3568 | if (update.Entity is SceneObjectPart) | ||
3569 | { | ||
3570 | SceneObjectPart part = (SceneObjectPart)update.Entity; | ||
3571 | |||
3572 | // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client | ||
3573 | // will never receive an update after a prim kill. Even then, keeping the kill record may be a good | ||
3574 | // safety measure. | ||
3575 | // | ||
3576 | // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update | ||
3577 | // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs | ||
3578 | // updates and kills on different threads with different scheduling strategies, hence this protection. | ||
3579 | // | ||
3580 | // This doesn't appear to apply to child prims - a client will happily ignore these updates | ||
3581 | // after the root prim has been deleted. | ||
3582 | if (m_killRecord.Contains(part.LocalId)) | ||
3566 | { | 3583 | { |
3567 | SceneObjectPart part = (SceneObjectPart)update.Entity; | 3584 | // m_log.WarnFormat( |
3568 | 3585 | // "[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 | 3586 | // part.LocalId, Name); |
3570 | // will never receive an update after a prim kill. Even then, keeping the kill record may be a good | 3587 | continue; |
3571 | // safety measure. | 3588 | } |
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 | 3589 | ||
3587 | if (part.ParentGroup.IsAttachment && m_disableFacelights) | 3590 | if (part.ParentGroup.IsAttachment && m_disableFacelights) |
3591 | { | ||
3592 | if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && | ||
3593 | part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand) | ||
3588 | { | 3594 | { |
3589 | if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && | 3595 | part.Shape.LightEntry = false; |
3590 | part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand) | ||
3591 | { | ||
3592 | part.Shape.LightEntry = false; | ||
3593 | } | ||
3594 | } | 3596 | } |
3595 | } | 3597 | } |
3598 | } | ||
3599 | |||
3600 | ++updatesThisCall; | ||
3596 | 3601 | ||
3597 | ++updatesThisCall; | 3602 | #region UpdateFlags to packet type conversion |
3598 | 3603 | ||
3599 | #region UpdateFlags to packet type conversion | 3604 | PrimUpdateFlags updateFlags = update.Flags; |
3600 | 3605 | ||
3601 | PrimUpdateFlags updateFlags = update.Flags; | 3606 | bool canUseCompressed = true; |
3607 | bool canUseImproved = true; | ||
3602 | 3608 | ||
3603 | bool canUseCompressed = true; | 3609 | // Compressed object updates only make sense for LL primitives |
3604 | bool canUseImproved = true; | 3610 | if (!(update.Entity is SceneObjectPart)) |
3611 | { | ||
3612 | canUseCompressed = false; | ||
3613 | } | ||
3605 | 3614 | ||
3606 | // Compressed object updates only make sense for LL primitives | 3615 | if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) |
3607 | if (!(update.Entity is SceneObjectPart)) | 3616 | { |
3617 | canUseCompressed = false; | ||
3618 | canUseImproved = false; | ||
3619 | } | ||
3620 | else | ||
3621 | { | ||
3622 | if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || | ||
3623 | updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || | ||
3624 | updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) || | ||
3625 | updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||
3608 | { | 3626 | { |
3609 | canUseCompressed = false; | 3627 | canUseCompressed = false; |
3610 | } | 3628 | } |
3611 | 3629 | ||
3612 | if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) | 3630 | if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) || |
3631 | updateFlags.HasFlag(PrimUpdateFlags.ParentID) || | ||
3632 | updateFlags.HasFlag(PrimUpdateFlags.Scale) || | ||
3633 | updateFlags.HasFlag(PrimUpdateFlags.PrimData) || | ||
3634 | updateFlags.HasFlag(PrimUpdateFlags.Text) || | ||
3635 | updateFlags.HasFlag(PrimUpdateFlags.NameValue) || | ||
3636 | updateFlags.HasFlag(PrimUpdateFlags.ExtraData) || | ||
3637 | updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) || | ||
3638 | updateFlags.HasFlag(PrimUpdateFlags.Sound) || | ||
3639 | updateFlags.HasFlag(PrimUpdateFlags.Particles) || | ||
3640 | updateFlags.HasFlag(PrimUpdateFlags.Material) || | ||
3641 | updateFlags.HasFlag(PrimUpdateFlags.ClickAction) || | ||
3642 | updateFlags.HasFlag(PrimUpdateFlags.MediaURL) || | ||
3643 | updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||
3613 | { | 3644 | { |
3614 | canUseCompressed = false; | ||
3615 | canUseImproved = false; | 3645 | canUseImproved = false; |
3616 | } | 3646 | } |
3617 | else | 3647 | } |
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 | 3648 | ||
3646 | #endregion UpdateFlags to packet type conversion | 3649 | #endregion UpdateFlags to packet type conversion |
3647 | 3650 | ||
3648 | #region Block Construction | 3651 | #region Block Construction |
3649 | 3652 | ||
3650 | // TODO: Remove this once we can build compressed updates | 3653 | // TODO: Remove this once we can build compressed updates |
3651 | canUseCompressed = false; | 3654 | canUseCompressed = false; |
3652 | 3655 | ||
3653 | if (!canUseImproved && !canUseCompressed) | 3656 | if (!canUseImproved && !canUseCompressed) |
3657 | { | ||
3658 | if (update.Entity is ScenePresence) | ||
3659 | { | ||
3660 | objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); | ||
3661 | } | ||
3662 | else | ||
3654 | { | 3663 | { |
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) | 3664 | // if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment) |
3662 | // { | 3665 | // { |
3663 | // SceneObjectPart sop = (SceneObjectPart)update.Entity; | 3666 | // SceneObjectPart sop = (SceneObjectPart)update.Entity; |
@@ -3686,71 +3689,90 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3686 | // } | 3689 | // } |
3687 | // else | 3690 | // else |
3688 | // { | 3691 | // { |
3689 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); | 3692 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); |
3690 | // } | 3693 | // } |
3691 | } | ||
3692 | } | ||
3693 | else if (!canUseImproved) | ||
3694 | { | ||
3695 | compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); | ||
3696 | } | 3694 | } |
3695 | } | ||
3696 | else if (!canUseImproved) | ||
3697 | { | ||
3698 | compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); | ||
3699 | } | ||
3700 | else | ||
3701 | { | ||
3702 | if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) | ||
3703 | // Self updates go into a special list | ||
3704 | terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); | ||
3697 | else | 3705 | else |
3698 | { | 3706 | // Everything else goes here |
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 | 3714 | ||
3710 | if (objectUpdateBlocks.IsValueCreated) | 3715 | const float TIME_DILATION = 1.0f; |
3711 | { | 3716 | ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); |
3712 | List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.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.Unknown, true); | ||
3731 | } | ||
3732 | |||
3733 | if (objectUpdateBlocks.IsValueCreated) | ||
3734 | { | ||
3735 | List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; | ||
3713 | 3736 | ||
3714 | ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 3737 | ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
3715 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | 3738 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; |
3716 | packet.RegionData.TimeDilation = timeDilation; | 3739 | packet.RegionData.TimeDilation = timeDilation; |
3717 | packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; | 3740 | packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; |
3718 | 3741 | ||
3719 | for (int i = 0; i < blocks.Count; i++) | 3742 | for (int i = 0; i < blocks.Count; i++) |
3720 | packet.ObjectData[i] = blocks[i]; | 3743 | packet.ObjectData[i] = blocks[i]; |
3721 | 3744 | ||
3722 | OutPacket(packet, ThrottleOutPacketType.Task, true); | 3745 | OutPacket(packet, ThrottleOutPacketType.Task, true); |
3723 | } | 3746 | } |
3724 | 3747 | ||
3725 | if (compressedUpdateBlocks.IsValueCreated) | 3748 | if (compressedUpdateBlocks.IsValueCreated) |
3726 | { | 3749 | { |
3727 | List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; | 3750 | List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; |
3728 | 3751 | ||
3729 | ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); | 3752 | ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); |
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 ObjectUpdateCompressedPacket.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 (terseUpdateBlocks.IsValueCreated) |
3741 | { | 3764 | { |
3742 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; | 3765 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; |
3743 | 3766 | ||
3744 | ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); | 3767 | ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); |
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 ImprovedTerseObjectUpdatePacket.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 |
@@ -8239,7 +8261,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8239 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); | 8261 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); |
8240 | entry.AgentID = block.ID; | 8262 | entry.AgentID = block.ID; |
8241 | entry.Flags = (AccessList)block.Flags; | 8263 | entry.Flags = (AccessList)block.Flags; |
8242 | entry.Time = new DateTime(); | 8264 | entry.Time = Util.ToDateTime(block.Time); |
8243 | entries.Add(entry); | 8265 | entries.Add(entry); |
8244 | } | 8266 | } |
8245 | 8267 | ||
@@ -8247,8 +8269,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8247 | if (handlerParcelAccessListUpdateRequest != null) | 8269 | if (handlerParcelAccessListUpdateRequest != null) |
8248 | { | 8270 | { |
8249 | handlerParcelAccessListUpdateRequest(updatePacket.AgentData.AgentID, | 8271 | handlerParcelAccessListUpdateRequest(updatePacket.AgentData.AgentID, |
8250 | updatePacket.AgentData.SessionID, updatePacket.Data.Flags, | 8272 | updatePacket.Data.Flags, |
8251 | updatePacket.Data.LocalID, entries, this); | 8273 | updatePacket.Data.LocalID, |
8274 | updatePacket.Data.TransactionID, | ||
8275 | updatePacket.Data.SequenceID, | ||
8276 | updatePacket.Data.Sections, | ||
8277 | entries, this); | ||
8252 | } | 8278 | } |
8253 | return true; | 8279 | return true; |
8254 | } | 8280 | } |