aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
diff options
context:
space:
mode:
authorDan Lake2011-04-29 15:49:49 -0700
committerDan Lake2011-04-29 15:49:49 -0700
commit8f14c3f04f6f4ddeafdfc83c1719ec5cddfe7dfe (patch)
treebe718fbb3ab2e404b5cb650d544eec86abb0bb42 /OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
parentFix crash when [Mesh] section is missing from configuration files (diff)
parentMinor correction to yesterday's changes. Make normal prim crossing (no attach... (diff)
downloadopensim-SC_OLD-8f14c3f04f6f4ddeafdfc83c1719ec5cddfe7dfe.zip
opensim-SC_OLD-8f14c3f04f6f4ddeafdfc83c1719ec5cddfe7dfe.tar.gz
opensim-SC_OLD-8f14c3f04f6f4ddeafdfc83c1719ec5cddfe7dfe.tar.bz2
opensim-SC_OLD-8f14c3f04f6f4ddeafdfc83c1719ec5cddfe7dfe.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs206
1 files changed, 161 insertions, 45 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 1f7e66d..43903ce 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -385,6 +385,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
385 public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } 385 public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); }
386 386
387 /// <summary> 387 /// <summary>
388 /// Entity update queues
389 /// </summary>
390 public PriorityQueue EntityUpdateQueue { get { return m_entityUpdates; } }
391
392 /// <summary>
388 /// First name of the agent/avatar represented by the client 393 /// First name of the agent/avatar represented by the client
389 /// </summary> 394 /// </summary>
390 public string FirstName { get { return m_firstName; } } 395 public string FirstName { get { return m_firstName; } }
@@ -3561,6 +3566,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3561 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); 3566 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
3562 } 3567 }
3563 3568
3569 /// <summary>
3570 /// Requeue an EntityUpdate when it was not acknowledged by the client.
3571 /// We will update the priority and put it in the correct queue, merging update flags
3572 /// with any other updates that may be queued for the same entity.
3573 /// The original update time is used for the merged update.
3574 /// </summary>
3575 private void ResendPrimUpdate(EntityUpdate update)
3576 {
3577 // If the update exists in priority queue, it will be updated.
3578 // If it does not exist then it will be added with the current (rather than its original) priority
3579 uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
3580
3581 lock (m_entityUpdates.SyncRoot)
3582 m_entityUpdates.Enqueue(priority, update);
3583 }
3584
3585 /// <summary>
3586 /// Requeue a list of EntityUpdates when they were not acknowledged by the client.
3587 /// We will update the priority and put it in the correct queue, merging update flags
3588 /// with any other updates that may be queued for the same entity.
3589 /// The original update time is used for the merged update.
3590 /// </summary>
3591 private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
3592 {
3593 // m_log.WarnFormat("[CLIENT] resending prim update {0}",updates[0].UpdateTime);
3594
3595 // Remove the update packet from the list of packets waiting for acknowledgement
3596 // because we are requeuing the list of updates. They will be resent in new packets
3597 // with the most recent state and priority.
3598 m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
3599
3600 // Count this as a resent packet since we are going to requeue all of the updates contained in it
3601 Interlocked.Increment(ref m_udpClient.PacketsResent);
3602
3603 foreach (EntityUpdate update in updates)
3604 ResendPrimUpdate(update);
3605 }
3606
3564 private void ProcessEntityUpdates(int maxUpdates) 3607 private void ProcessEntityUpdates(int maxUpdates)
3565 { 3608 {
3566 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3609 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
@@ -3568,6 +3611,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3568 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); 3611 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>>(); 3612 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3570 3613
3614 OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3615 OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3616 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3617 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3618
3571 // Check to see if this is a flush 3619 // Check to see if this is a flush
3572 if (maxUpdates <= 0) 3620 if (maxUpdates <= 0)
3573 { 3621 {
@@ -3583,7 +3631,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3583 float avgTimeDilation = 1.0f; 3631 float avgTimeDilation = 1.0f;
3584 IEntityUpdate iupdate; 3632 IEntityUpdate iupdate;
3585 Int32 timeinqueue; // this is just debugging code & can be dropped later 3633 Int32 timeinqueue; // this is just debugging code & can be dropped later
3586 3634
3587 while (updatesThisCall < maxUpdates) 3635 while (updatesThisCall < maxUpdates)
3588 { 3636 {
3589 lock (m_entityUpdates.SyncRoot) 3637 lock (m_entityUpdates.SyncRoot)
@@ -3688,24 +3736,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3688 if (update.Entity is ScenePresence) 3736 if (update.Entity is ScenePresence)
3689 { 3737 {
3690 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3738 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3739 objectUpdates.Value.Add(update);
3691 } 3740 }
3692 else 3741 else
3693 { 3742 {
3694 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3743 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3744 objectUpdates.Value.Add(update);
3695 } 3745 }
3696 } 3746 }
3697 else if (!canUseImproved) 3747 else if (!canUseImproved)
3698 { 3748 {
3699 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3749 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3750 compressedUpdates.Value.Add(update);
3700 } 3751 }
3701 else 3752 else
3702 { 3753 {
3703 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3754 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3755 {
3704 // Self updates go into a special list 3756 // Self updates go into a special list
3705 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); 3757 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3758 terseAgentUpdates.Value.Add(update);
3759 }
3706 else 3760 else
3761 {
3707 // Everything else goes here 3762 // Everything else goes here
3708 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); 3763 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3764 terseUpdates.Value.Add(update);
3765 }
3709 } 3766 }
3710 3767
3711 #endregion Block Construction 3768 #endregion Block Construction
@@ -3713,28 +3770,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3713 3770
3714 3771
3715 #region Packet Sending 3772 #region Packet Sending
3716
3717 //const float TIME_DILATION = 1.0f;
3718
3719
3720 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3773 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3721 3774
3722 if (terseAgentUpdateBlocks.IsValueCreated) 3775 if (terseAgentUpdateBlocks.IsValueCreated)
3723 { 3776 {
3724 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3777 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3725 3778
3726 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3779 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3727 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3780 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3728 packet.RegionData.TimeDilation = timeDilation; 3781 packet.RegionData.TimeDilation = timeDilation;
3729 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3782 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3730 3783
3731 for (int i = 0; i < blocks.Count; i++) 3784 for (int i = 0; i < blocks.Count; i++)
3732 packet.ObjectData[i] = blocks[i]; 3785 packet.ObjectData[i] = blocks[i];
3733 3786 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3734 3787 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3735 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3736 } 3788 }
3737 3789
3738 if (objectUpdateBlocks.IsValueCreated) 3790 if (objectUpdateBlocks.IsValueCreated)
3739 { 3791 {
3740 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3792 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
@@ -3746,8 +3798,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3746 3798
3747 for (int i = 0; i < blocks.Count; i++) 3799 for (int i = 0; i < blocks.Count; i++)
3748 packet.ObjectData[i] = blocks[i]; 3800 packet.ObjectData[i] = blocks[i];
3749 3801 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3750 OutPacket(packet, ThrottleOutPacketType.Task, true); 3802 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3751 } 3803 }
3752 3804
3753 if (compressedUpdateBlocks.IsValueCreated) 3805 if (compressedUpdateBlocks.IsValueCreated)
@@ -3761,10 +3813,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3761 3813
3762 for (int i = 0; i < blocks.Count; i++) 3814 for (int i = 0; i < blocks.Count; i++)
3763 packet.ObjectData[i] = blocks[i]; 3815 packet.ObjectData[i] = blocks[i];
3764 3816 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3765 OutPacket(packet, ThrottleOutPacketType.Task, true); 3817 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3766 } 3818 }
3767 3819
3768 if (terseUpdateBlocks.IsValueCreated) 3820 if (terseUpdateBlocks.IsValueCreated)
3769 { 3821 {
3770 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3822 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
@@ -3776,8 +3828,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3776 3828
3777 for (int i = 0; i < blocks.Count; i++) 3829 for (int i = 0; i < blocks.Count; i++)
3778 packet.ObjectData[i] = blocks[i]; 3830 packet.ObjectData[i] = blocks[i];
3779 3831 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3780 OutPacket(packet, ThrottleOutPacketType.Task, true); 3832 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3781 } 3833 }
3782 } 3834 }
3783 3835
@@ -3969,7 +4021,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3969 { 4021 {
3970 SendFamilyProps = SendFamilyProps || update.SendFamilyProps; 4022 SendFamilyProps = SendFamilyProps || update.SendFamilyProps;
3971 SendObjectProps = SendObjectProps || update.SendObjectProps; 4023 SendObjectProps = SendObjectProps || update.SendObjectProps;
3972 Flags |= update.Flags; 4024 // other properties may need to be updated by base class
4025 base.Update(update);
3973 } 4026 }
3974 } 4027 }
3975 4028
@@ -3980,6 +4033,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3980 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false)); 4033 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false));
3981 } 4034 }
3982 4035
4036 private void ResendPropertyUpdate(ObjectPropertyUpdate update)
4037 {
4038 uint priority = 0;
4039 lock (m_entityProps.SyncRoot)
4040 m_entityProps.Enqueue(priority, update);
4041 }
4042
4043 private void ResendPropertyUpdates(List<ObjectPropertyUpdate> updates, OutgoingPacket oPacket)
4044 {
4045 // m_log.WarnFormat("[CLIENT] resending object property {0}",updates[0].UpdateTime);
4046
4047 // Remove the update packet from the list of packets waiting for acknowledgement
4048 // because we are requeuing the list of updates. They will be resent in new packets
4049 // with the most recent state.
4050 m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
4051
4052 // Count this as a resent packet since we are going to requeue all of the updates contained in it
4053 Interlocked.Increment(ref m_udpClient.PacketsResent);
4054
4055 foreach (ObjectPropertyUpdate update in updates)
4056 ResendPropertyUpdate(update);
4057 }
4058
3983 public void SendObjectPropertiesReply(ISceneEntity entity) 4059 public void SendObjectPropertiesReply(ISceneEntity entity)
3984 { 4060 {
3985 uint priority = 0; // time based ordering only 4061 uint priority = 0; // time based ordering only
@@ -3995,6 +4071,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3995 OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks = 4071 OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks =
3996 new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>(); 4072 new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>();
3997 4073
4074 OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates =
4075 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4076
4077 OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
4078 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4079
3998 IEntityUpdate iupdate; 4080 IEntityUpdate iupdate;
3999 Int32 timeinqueue; // this is just debugging code & can be dropped later 4081 Int32 timeinqueue; // this is just debugging code & can be dropped later
4000 4082
@@ -4013,6 +4095,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4013 SceneObjectPart sop = (SceneObjectPart)update.Entity; 4095 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4014 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); 4096 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
4015 objectFamilyBlocks.Value.Add(objPropDB); 4097 objectFamilyBlocks.Value.Add(objPropDB);
4098 familyUpdates.Value.Add(update);
4016 } 4099 }
4017 } 4100 }
4018 4101
@@ -4023,6 +4106,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4023 SceneObjectPart sop = (SceneObjectPart)update.Entity; 4106 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4024 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); 4107 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
4025 objectPropertiesBlocks.Value.Add(objPropDB); 4108 objectPropertiesBlocks.Value.Add(objPropDB);
4109 propertyUpdates.Value.Add(update);
4026 } 4110 }
4027 } 4111 }
4028 4112
@@ -4030,12 +4114,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4030 } 4114 }
4031 4115
4032 4116
4033 Int32 ppcnt = 0; 4117 // Int32 ppcnt = 0;
4034 Int32 pbcnt = 0; 4118 // Int32 pbcnt = 0;
4035 4119
4036 if (objectPropertiesBlocks.IsValueCreated) 4120 if (objectPropertiesBlocks.IsValueCreated)
4037 { 4121 {
4038 List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value; 4122 List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
4123 List<ObjectPropertyUpdate> updates = propertyUpdates.Value;
4039 4124
4040 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 4125 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
4041 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count]; 4126 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count];
@@ -4043,28 +4128,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4043 packet.ObjectData[i] = blocks[i]; 4128 packet.ObjectData[i] = blocks[i];
4044 4129
4045 packet.Header.Zerocoded = true; 4130 packet.Header.Zerocoded = true;
4046 OutPacket(packet, ThrottleOutPacketType.Task, true);
4047 4131
4048 pbcnt += blocks.Count; 4132 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4049 ppcnt++; 4133 // of the object rather than the properties when the packet was created
4134 OutPacket(packet, ThrottleOutPacketType.Task, true,
4135 delegate(OutgoingPacket oPacket)
4136 {
4137 ResendPropertyUpdates(updates, oPacket);
4138 });
4139
4140 // pbcnt += blocks.Count;
4141 // ppcnt++;
4050 } 4142 }
4051 4143
4052 Int32 fpcnt = 0; 4144 // Int32 fpcnt = 0;
4053 Int32 fbcnt = 0; 4145 // Int32 fbcnt = 0;
4054 4146
4055 if (objectFamilyBlocks.IsValueCreated) 4147 if (objectFamilyBlocks.IsValueCreated)
4056 { 4148 {
4057 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value; 4149 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
4058 4150
4059 // ObjectPropertiesFamilyPacket objPropFamilyPack =
4060 // (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
4061 //
4062 // objPropFamilyPack.ObjectData = new ObjectPropertiesFamilyPacket.ObjectDataBlock[blocks.Count];
4063 // for (int i = 0; i < blocks.Count; i++)
4064 // objPropFamilyPack.ObjectData[i] = blocks[i];
4065 //
4066 // OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task, true);
4067
4068 // one packet per object block... uggh... 4151 // one packet per object block... uggh...
4069 for (int i = 0; i < blocks.Count; i++) 4152 for (int i = 0; i < blocks.Count; i++)
4070 { 4153 {
@@ -4073,10 +4156,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4073 4156
4074 packet.ObjectData = blocks[i]; 4157 packet.ObjectData = blocks[i];
4075 packet.Header.Zerocoded = true; 4158 packet.Header.Zerocoded = true;
4076 OutPacket(packet, ThrottleOutPacketType.Task);
4077 4159
4078 fpcnt++; 4160 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4079 fbcnt++; 4161 // of the object rather than the properties when the packet was created
4162 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4163 updates.Add(familyUpdates.Value[i]);
4164 OutPacket(packet, ThrottleOutPacketType.Task, true,
4165 delegate(OutgoingPacket oPacket)
4166 {
4167 ResendPropertyUpdates(updates, oPacket);
4168 });
4169
4170 // fpcnt++;
4171 // fbcnt++;
4080 } 4172 }
4081 4173
4082 } 4174 }
@@ -4113,7 +4205,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4113 4205
4114 return block; 4206 return block;
4115 } 4207 }
4116 4208
4117 private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop) 4209 private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop)
4118 { 4210 {
4119 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 4211 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
@@ -4764,7 +4856,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4764 data.RelativePosition.ToBytes(objectData, 0); 4856 data.RelativePosition.ToBytes(objectData, 0);
4765 data.Velocity.ToBytes(objectData, 12); 4857 data.Velocity.ToBytes(objectData, 12);
4766 data.Acceleration.ToBytes(objectData, 24); 4858 data.Acceleration.ToBytes(objectData, 24);
4767 data.RotationOffset.ToBytes(objectData, 36); 4859 try
4860 {
4861 data.RotationOffset.ToBytes(objectData, 36);
4862 }
4863 catch (Exception e)
4864 {
4865 m_log.Warn("[LLClientView]: exception converting quaternion to bytes, using Quaternion.Identity. Exception: " + e.ToString());
4866 OpenMetaverse.Quaternion.Identity.ToBytes(objectData, 36);
4867 }
4768 data.AngularVelocity.ToBytes(objectData, 48); 4868 data.AngularVelocity.ToBytes(objectData, 48);
4769 4869
4770 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 4870 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -11328,7 +11428,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11328 /// <returns></returns> 11428 /// <returns></returns>
11329 public byte[] GetThrottlesPacked(float multiplier) 11429 public byte[] GetThrottlesPacked(float multiplier)
11330 { 11430 {
11331 return m_udpClient.GetThrottlesPacked(); 11431 return m_udpClient.GetThrottlesPacked(multiplier);
11332 } 11432 }
11333 11433
11334 /// <summary> 11434 /// <summary>
@@ -11363,6 +11463,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11363 /// handles splitting manually</param> 11463 /// handles splitting manually</param>
11364 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting) 11464 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting)
11365 { 11465 {
11466 OutPacket(packet, throttlePacketType, doAutomaticSplitting, null);
11467 }
11468
11469 /// <summary>
11470 /// This is the starting point for sending a simulator packet out to the client
11471 /// </summary>
11472 /// <param name="packet">Packet to send</param>
11473 /// <param name="throttlePacketType">Throttling category for the packet</param>
11474 /// <param name="doAutomaticSplitting">True to automatically split oversized
11475 /// packets (the default), or false to disable splitting if the calling code
11476 /// handles splitting manually</param>
11477 /// <param name="method">The method to be called in the event this packet is reliable
11478 /// and unacknowledged. The server will provide normal resend capability if you do not
11479 /// provide your own method.</param>
11480 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
11481 {
11366 if (m_debugPacketLevel > 0) 11482 if (m_debugPacketLevel > 0)
11367 { 11483 {
11368 bool logPacket = true; 11484 bool logPacket = true;
@@ -11388,7 +11504,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11388 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); 11504 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type);
11389 } 11505 }
11390 11506
11391 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); 11507 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
11392 } 11508 }
11393 11509
11394 public bool AddMoney(int debit) 11510 public bool AddMoney(int debit)
@@ -11519,7 +11635,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11519 11635
11520 info.userEP = m_userEndPoint; 11636 info.userEP = m_userEndPoint;
11521 info.proxyEP = null; 11637 info.proxyEP = null;
11522 info.agentcircuit = new sAgentCircuitData(RequestClientInfo()); 11638 info.agentcircuit = RequestClientInfo();
11523 11639
11524 return info; 11640 return info;
11525 } 11641 }