diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 96 |
1 files changed, 75 insertions, 21 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 1f7e66d..14c5d6c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -3561,6 +3561,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3561 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); | 3561 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); |
3562 | } | 3562 | } |
3563 | 3563 | ||
3564 | /// <summary> | ||
3565 | /// Requeue an EntityUpdate when it was not acknowledged by the client. | ||
3566 | /// We will update the priority and put it in the correct queue, merging update flags | ||
3567 | /// with any other updates that may be queued for the same entity. | ||
3568 | /// The original update time is used for the merged update. | ||
3569 | /// </summary> | ||
3570 | public void ResendPrimUpdate(EntityUpdate update) | ||
3571 | { | ||
3572 | // If the update exists in priority queue, it will be updated. | ||
3573 | // If it does not exist then it will be added with the current (rather than its original) priority | ||
3574 | uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity); | ||
3575 | |||
3576 | lock (m_entityUpdates.SyncRoot) | ||
3577 | m_entityUpdates.Enqueue(priority, update); | ||
3578 | } | ||
3579 | |||
3580 | /// <summary> | ||
3581 | /// Requeue a list of EntityUpdates when they were not acknowledged by the client. | ||
3582 | /// We will update the priority and put it in the correct queue, merging update flags | ||
3583 | /// with any other updates that may be queued for the same entity. | ||
3584 | /// The original update time is used for the merged update. | ||
3585 | /// </summary> | ||
3586 | void ResendPrimUpdates(List<EntityUpdate> updates) | ||
3587 | { | ||
3588 | foreach (EntityUpdate update in updates) | ||
3589 | ResendPrimUpdate(update); | ||
3590 | } | ||
3591 | |||
3564 | private void ProcessEntityUpdates(int maxUpdates) | 3592 | private void ProcessEntityUpdates(int maxUpdates) |
3565 | { | 3593 | { |
3566 | OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); | 3594 | OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); |
@@ -3568,6 +3596,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3568 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | 3596 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); |
3569 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | 3597 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); |
3570 | 3598 | ||
3599 | OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3600 | OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3601 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3602 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3603 | |||
3571 | // Check to see if this is a flush | 3604 | // Check to see if this is a flush |
3572 | if (maxUpdates <= 0) | 3605 | if (maxUpdates <= 0) |
3573 | { | 3606 | { |
@@ -3583,7 +3616,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3583 | float avgTimeDilation = 1.0f; | 3616 | float avgTimeDilation = 1.0f; |
3584 | IEntityUpdate iupdate; | 3617 | IEntityUpdate iupdate; |
3585 | Int32 timeinqueue; // this is just debugging code & can be dropped later | 3618 | Int32 timeinqueue; // this is just debugging code & can be dropped later |
3586 | 3619 | ||
3587 | while (updatesThisCall < maxUpdates) | 3620 | while (updatesThisCall < maxUpdates) |
3588 | { | 3621 | { |
3589 | lock (m_entityUpdates.SyncRoot) | 3622 | lock (m_entityUpdates.SyncRoot) |
@@ -3688,24 +3721,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3688 | if (update.Entity is ScenePresence) | 3721 | if (update.Entity is ScenePresence) |
3689 | { | 3722 | { |
3690 | objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); | 3723 | objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); |
3724 | objectUpdates.Value.Add(update); | ||
3691 | } | 3725 | } |
3692 | else | 3726 | else |
3693 | { | 3727 | { |
3694 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); | 3728 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); |
3729 | objectUpdates.Value.Add(update); | ||
3695 | } | 3730 | } |
3696 | } | 3731 | } |
3697 | else if (!canUseImproved) | 3732 | else if (!canUseImproved) |
3698 | { | 3733 | { |
3699 | compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); | 3734 | compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); |
3735 | compressedUpdates.Value.Add(update); | ||
3700 | } | 3736 | } |
3701 | else | 3737 | else |
3702 | { | 3738 | { |
3703 | if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) | 3739 | if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) |
3740 | { | ||
3704 | // Self updates go into a special list | 3741 | // Self updates go into a special list |
3705 | terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); | 3742 | terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); |
3743 | terseAgentUpdates.Value.Add(update); | ||
3744 | } | ||
3706 | else | 3745 | else |
3746 | { | ||
3707 | // Everything else goes here | 3747 | // Everything else goes here |
3708 | terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); | 3748 | terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); |
3749 | terseUpdates.Value.Add(update); | ||
3750 | } | ||
3709 | } | 3751 | } |
3710 | 3752 | ||
3711 | #endregion Block Construction | 3753 | #endregion Block Construction |
@@ -3713,28 +3755,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3713 | 3755 | ||
3714 | 3756 | ||
3715 | #region Packet Sending | 3757 | #region Packet Sending |
3716 | |||
3717 | //const float TIME_DILATION = 1.0f; | ||
3718 | |||
3719 | |||
3720 | ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); | 3758 | ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); |
3721 | 3759 | ||
3722 | if (terseAgentUpdateBlocks.IsValueCreated) | 3760 | if (terseAgentUpdateBlocks.IsValueCreated) |
3723 | { | 3761 | { |
3724 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; | 3762 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; |
3725 | 3763 | ||
3726 | ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); | 3764 | ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); |
3727 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | 3765 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; |
3728 | packet.RegionData.TimeDilation = timeDilation; | 3766 | packet.RegionData.TimeDilation = timeDilation; |
3729 | packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; | 3767 | packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; |
3730 | 3768 | ||
3731 | for (int i = 0; i < blocks.Count; i++) | 3769 | for (int i = 0; i < blocks.Count; i++) |
3732 | packet.ObjectData[i] = blocks[i]; | 3770 | packet.ObjectData[i] = blocks[i]; |
3733 | 3771 | // If any of the packets created from this call go unacknowledged, all of the updates will be resent | |
3734 | 3772 | OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate() { ResendPrimUpdates(terseAgentUpdates.Value); }); | |
3735 | OutPacket(packet, ThrottleOutPacketType.Unknown, true); | ||
3736 | } | 3773 | } |
3737 | 3774 | ||
3738 | if (objectUpdateBlocks.IsValueCreated) | 3775 | if (objectUpdateBlocks.IsValueCreated) |
3739 | { | 3776 | { |
3740 | List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; | 3777 | List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; |
@@ -3746,8 +3783,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3746 | 3783 | ||
3747 | for (int i = 0; i < blocks.Count; i++) | 3784 | for (int i = 0; i < blocks.Count; i++) |
3748 | packet.ObjectData[i] = blocks[i]; | 3785 | packet.ObjectData[i] = blocks[i]; |
3749 | 3786 | // If any of the packets created from this call go unacknowledged, all of the updates will be resent | |
3750 | OutPacket(packet, ThrottleOutPacketType.Task, true); | 3787 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate() { ResendPrimUpdates(objectUpdates.Value); }); |
3751 | } | 3788 | } |
3752 | 3789 | ||
3753 | if (compressedUpdateBlocks.IsValueCreated) | 3790 | if (compressedUpdateBlocks.IsValueCreated) |
@@ -3761,10 +3798,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3761 | 3798 | ||
3762 | for (int i = 0; i < blocks.Count; i++) | 3799 | for (int i = 0; i < blocks.Count; i++) |
3763 | packet.ObjectData[i] = blocks[i]; | 3800 | packet.ObjectData[i] = blocks[i]; |
3764 | 3801 | // If any of the packets created from this call go unacknowledged, all of the updates will be resent | |
3765 | OutPacket(packet, ThrottleOutPacketType.Task, true); | 3802 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate() { ResendPrimUpdates(compressedUpdates.Value); }); |
3766 | } | 3803 | } |
3767 | 3804 | ||
3768 | if (terseUpdateBlocks.IsValueCreated) | 3805 | if (terseUpdateBlocks.IsValueCreated) |
3769 | { | 3806 | { |
3770 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; | 3807 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; |
@@ -3776,8 +3813,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3776 | 3813 | ||
3777 | for (int i = 0; i < blocks.Count; i++) | 3814 | for (int i = 0; i < blocks.Count; i++) |
3778 | packet.ObjectData[i] = blocks[i]; | 3815 | packet.ObjectData[i] = blocks[i]; |
3779 | 3816 | // If any of the packets created from this call go unacknowledged, all of the updates will be resent | |
3780 | OutPacket(packet, ThrottleOutPacketType.Task, true); | 3817 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate() { ResendPrimUpdates(terseUpdates.Value); }); |
3781 | } | 3818 | } |
3782 | } | 3819 | } |
3783 | 3820 | ||
@@ -3969,7 +4006,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3969 | { | 4006 | { |
3970 | SendFamilyProps = SendFamilyProps || update.SendFamilyProps; | 4007 | SendFamilyProps = SendFamilyProps || update.SendFamilyProps; |
3971 | SendObjectProps = SendObjectProps || update.SendObjectProps; | 4008 | SendObjectProps = SendObjectProps || update.SendObjectProps; |
3972 | Flags |= update.Flags; | 4009 | // other properties may need to be updated by base class |
4010 | base.Update(update); | ||
3973 | } | 4011 | } |
3974 | } | 4012 | } |
3975 | 4013 | ||
@@ -11363,6 +11401,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11363 | /// handles splitting manually</param> | 11401 | /// handles splitting manually</param> |
11364 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting) | 11402 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting) |
11365 | { | 11403 | { |
11404 | OutPacket(packet, throttlePacketType, doAutomaticSplitting, null); | ||
11405 | } | ||
11406 | |||
11407 | /// <summary> | ||
11408 | /// This is the starting point for sending a simulator packet out to the client | ||
11409 | /// </summary> | ||
11410 | /// <param name="packet">Packet to send</param> | ||
11411 | /// <param name="throttlePacketType">Throttling category for the packet</param> | ||
11412 | /// <param name="doAutomaticSplitting">True to automatically split oversized | ||
11413 | /// packets (the default), or false to disable splitting if the calling code | ||
11414 | /// handles splitting manually</param> | ||
11415 | /// <param name="method">The method to be called in the event this packet is reliable | ||
11416 | /// and unacknowledged. The server will provide normal resend capability if you do not | ||
11417 | /// provide your own method.</param> | ||
11418 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) | ||
11419 | { | ||
11366 | if (m_debugPacketLevel > 0) | 11420 | if (m_debugPacketLevel > 0) |
11367 | { | 11421 | { |
11368 | bool logPacket = true; | 11422 | bool logPacket = true; |
@@ -11388,7 +11442,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11388 | m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); | 11442 | m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); |
11389 | } | 11443 | } |
11390 | 11444 | ||
11391 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); | 11445 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method); |
11392 | } | 11446 | } |
11393 | 11447 | ||
11394 | public bool AddMoney(int debit) | 11448 | public bool AddMoney(int debit) |