aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs137
1 files changed, 114 insertions, 23 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 803114f..cd438d6 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3596,6 +3596,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3596 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); 3596 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
3597 } 3597 }
3598 3598
3599 /// <summary>
3600 /// Requeue an EntityUpdate when it was not acknowledged by the client.
3601 /// We will update the priority and put it in the correct queue, merging update flags
3602 /// with any other updates that may be queued for the same entity.
3603 /// The original update time is used for the merged update.
3604 /// </summary>
3605 private void ResendPrimUpdate(EntityUpdate update)
3606 {
3607 // If the update exists in priority queue, it will be updated.
3608 // If it does not exist then it will be added with the current (rather than its original) priority
3609 uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
3610
3611 lock (m_entityUpdates.SyncRoot)
3612 m_entityUpdates.Enqueue(priority, update);
3613 }
3614
3615 /// <summary>
3616 /// Requeue a list of EntityUpdates when they were not acknowledged by the client.
3617 /// We will update the priority and put it in the correct queue, merging update flags
3618 /// with any other updates that may be queued for the same entity.
3619 /// The original update time is used for the merged update.
3620 /// </summary>
3621 private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
3622 {
3623 // m_log.WarnFormat("[CLIENT] resending prim update {0}",updates[0].UpdateTime);
3624
3625 // Remove the update packet from the list of packets waiting for acknowledgement
3626 // because we are requeuing the list of updates. They will be resent in new packets
3627 // with the most recent state and priority.
3628 m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber, 0, true);
3629 foreach (EntityUpdate update in updates)
3630 ResendPrimUpdate(update);
3631 }
3632
3599 private void ProcessEntityUpdates(int maxUpdates) 3633 private void ProcessEntityUpdates(int maxUpdates)
3600 { 3634 {
3601 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3635 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
@@ -3603,6 +3637,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3603 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); 3637 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3604 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); 3638 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3605 3639
3640 OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3641 OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3642 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3643 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3644
3606 // Check to see if this is a flush 3645 // Check to see if this is a flush
3607 if (maxUpdates <= 0) 3646 if (maxUpdates <= 0)
3608 { 3647 {
@@ -4027,7 +4066,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4027 { 4066 {
4028 SendFamilyProps = SendFamilyProps || update.SendFamilyProps; 4067 SendFamilyProps = SendFamilyProps || update.SendFamilyProps;
4029 SendObjectProps = SendObjectProps || update.SendObjectProps; 4068 SendObjectProps = SendObjectProps || update.SendObjectProps;
4030 Flags |= update.Flags; 4069 // other properties may need to be updated by base class
4070 base.Update(update);
4031 } 4071 }
4032 } 4072 }
4033 4073
@@ -4038,6 +4078,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4038 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false)); 4078 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false));
4039 } 4079 }
4040 4080
4081 private void ResendPropertyUpdate(ObjectPropertyUpdate update)
4082 {
4083 uint priority = 0;
4084 lock (m_entityProps.SyncRoot)
4085 m_entityProps.Enqueue(priority, update);
4086 }
4087
4088 private void ResendPropertyUpdates(List<ObjectPropertyUpdate> updates, OutgoingPacket oPacket)
4089 {
4090 // m_log.WarnFormat("[CLIENT] resending object property {0}",updates[0].UpdateTime);
4091
4092 // Remove the update packet from the list of packets waiting for acknowledgement
4093 // because we are requeuing the list of updates. They will be resent in new packets
4094 // with the most recent state.
4095 m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber, 0, true);
4096 foreach (ObjectPropertyUpdate update in updates)
4097 ResendPropertyUpdate(update);
4098 }
4099
4041 public void SendObjectPropertiesReply(ISceneEntity entity) 4100 public void SendObjectPropertiesReply(ISceneEntity entity)
4042 { 4101 {
4043 uint priority = 0; // time based ordering only 4102 uint priority = 0; // time based ordering only
@@ -4053,6 +4112,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4053 OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks = 4112 OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks =
4054 new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>(); 4113 new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>();
4055 4114
4115 OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates =
4116 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4117
4118 OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
4119 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4120
4056 IEntityUpdate iupdate; 4121 IEntityUpdate iupdate;
4057 Int32 timeinqueue; // this is just debugging code & can be dropped later 4122 Int32 timeinqueue; // this is just debugging code & can be dropped later
4058 4123
@@ -4071,6 +4136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4071 SceneObjectPart sop = (SceneObjectPart)update.Entity; 4136 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4072 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); 4137 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
4073 objectFamilyBlocks.Value.Add(objPropDB); 4138 objectFamilyBlocks.Value.Add(objPropDB);
4139 familyUpdates.Value.Add(update);
4074 } 4140 }
4075 } 4141 }
4076 4142
@@ -4081,6 +4147,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4081 SceneObjectPart sop = (SceneObjectPart)update.Entity; 4147 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4082 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); 4148 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
4083 objectPropertiesBlocks.Value.Add(objPropDB); 4149 objectPropertiesBlocks.Value.Add(objPropDB);
4150 propertyUpdates.Value.Add(update);
4084 } 4151 }
4085 } 4152 }
4086 4153
@@ -4088,12 +4155,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4088 } 4155 }
4089 4156
4090 4157
4091 Int32 ppcnt = 0; 4158 // Int32 ppcnt = 0;
4092 Int32 pbcnt = 0; 4159 // Int32 pbcnt = 0;
4093 4160
4094 if (objectPropertiesBlocks.IsValueCreated) 4161 if (objectPropertiesBlocks.IsValueCreated)
4095 { 4162 {
4096 List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value; 4163 List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
4164 List<ObjectPropertyUpdate> updates = propertyUpdates.Value;
4097 4165
4098 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 4166 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
4099 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count]; 4167 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count];
@@ -4101,28 +4169,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4101 packet.ObjectData[i] = blocks[i]; 4169 packet.ObjectData[i] = blocks[i];
4102 4170
4103 packet.Header.Zerocoded = true; 4171 packet.Header.Zerocoded = true;
4104 OutPacket(packet, ThrottleOutPacketType.Task, true);
4105 4172
4106 pbcnt += blocks.Count; 4173 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4107 ppcnt++; 4174 // of the object rather than the properties when the packet was created
4175 OutPacket(packet, ThrottleOutPacketType.Task, true,
4176 delegate(OutgoingPacket oPacket)
4177 {
4178 ResendPropertyUpdates(updates, oPacket);
4179 });
4180
4181 // pbcnt += blocks.Count;
4182 // ppcnt++;
4108 } 4183 }
4109 4184
4110 Int32 fpcnt = 0; 4185 // Int32 fpcnt = 0;
4111 Int32 fbcnt = 0; 4186 // Int32 fbcnt = 0;
4112 4187
4113 if (objectFamilyBlocks.IsValueCreated) 4188 if (objectFamilyBlocks.IsValueCreated)
4114 { 4189 {
4115 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value; 4190 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
4116 4191
4117 // ObjectPropertiesFamilyPacket objPropFamilyPack =
4118 // (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
4119 //
4120 // objPropFamilyPack.ObjectData = new ObjectPropertiesFamilyPacket.ObjectDataBlock[blocks.Count];
4121 // for (int i = 0; i < blocks.Count; i++)
4122 // objPropFamilyPack.ObjectData[i] = blocks[i];
4123 //
4124 // OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task, true);
4125
4126 // one packet per object block... uggh... 4192 // one packet per object block... uggh...
4127 for (int i = 0; i < blocks.Count; i++) 4193 for (int i = 0; i < blocks.Count; i++)
4128 { 4194 {
@@ -4131,10 +4197,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4131 4197
4132 packet.ObjectData = blocks[i]; 4198 packet.ObjectData = blocks[i];
4133 packet.Header.Zerocoded = true; 4199 packet.Header.Zerocoded = true;
4134 OutPacket(packet, ThrottleOutPacketType.Task);
4135 4200
4136 fpcnt++; 4201 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4137 fbcnt++; 4202 // of the object rather than the properties when the packet was created
4203 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4204 updates.Add(familyUpdates.Value[i]);
4205 OutPacket(packet, ThrottleOutPacketType.Task, true,
4206 delegate(OutgoingPacket oPacket)
4207 {
4208 ResendPropertyUpdates(updates, oPacket);
4209 });
4210
4211 // fpcnt++;
4212 // fbcnt++;
4138 } 4213 }
4139 4214
4140 } 4215 }
@@ -4171,7 +4246,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4171 4246
4172 return block; 4247 return block;
4173 } 4248 }
4174 4249
4175 private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop) 4250 private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop)
4176 { 4251 {
4177 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 4252 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
@@ -11473,6 +11548,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11473 /// handles splitting manually</param> 11548 /// handles splitting manually</param>
11474 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting) 11549 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting)
11475 { 11550 {
11551 OutPacket(packet, throttlePacketType, doAutomaticSplitting, null);
11552 }
11553
11554 /// <summary>
11555 /// This is the starting point for sending a simulator packet out to the client
11556 /// </summary>
11557 /// <param name="packet">Packet to send</param>
11558 /// <param name="throttlePacketType">Throttling category for the packet</param>
11559 /// <param name="doAutomaticSplitting">True to automatically split oversized
11560 /// packets (the default), or false to disable splitting if the calling code
11561 /// handles splitting manually</param>
11562 /// <param name="method">The method to be called in the event this packet is reliable
11563 /// and unacknowledged. The server will provide normal resend capability if you do not
11564 /// provide your own method.</param>
11565 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
11566 {
11476 if (m_debugPacketLevel > 0) 11567 if (m_debugPacketLevel > 0)
11477 { 11568 {
11478 bool logPacket = true; 11569 bool logPacket = true;
@@ -11498,7 +11589,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11498 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); 11589 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type);
11499 } 11590 }
11500 11591
11501 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); 11592 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
11502 } 11593 }
11503 11594
11504 public bool AddMoney(int debit) 11595 public bool AddMoney(int debit)