aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs158
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs16
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs35
3 files changed, 147 insertions, 62 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 59d1c69..06f1301 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -358,7 +358,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
358// protected HashSet<uint> m_attachmentsSent; 358// protected HashSet<uint> m_attachmentsSent;
359 359
360 private bool m_deliverPackets = true; 360 private bool m_deliverPackets = true;
361 private int m_animationSequenceNumber = 1; 361
362 private bool m_SendLogoutPacketWhenClosing = true; 362 private bool m_SendLogoutPacketWhenClosing = true;
363 363
364 /// <summary> 364 /// <summary>
@@ -419,6 +419,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
419 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } 419 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
420 public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } 420 public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); }
421 421
422 public int PingTimeMS
423 {
424 get
425 {
426 if (UDPClient != null)
427 return UDPClient.PingTimeMS;
428 return 0;
429 }
430 }
431
422 /// <summary> 432 /// <summary>
423 /// Entity update queues 433 /// Entity update queues
424 /// </summary> 434 /// </summary>
@@ -440,7 +450,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
440 public string Name { get { return FirstName + " " + LastName; } } 450 public string Name { get { return FirstName + " " + LastName; } }
441 451
442 public uint CircuitCode { get { return m_circuitCode; } } 452 public uint CircuitCode { get { return m_circuitCode; } }
443 public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } 453 public int NextAnimationSequenceNumber
454 {
455 get { return m_udpServer.NextAnimationSequenceNumber; }
456 }
444 457
445 /// <summary> 458 /// <summary>
446 /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to 459 /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to
@@ -461,6 +474,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
461 set { m_disableFacelights = value; } 474 set { m_disableFacelights = value; }
462 } 475 }
463 476
477
464 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } 478 public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
465 479
466 480
@@ -1638,6 +1652,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1638 pc.PingID.OldestUnacked = 0; 1652 pc.PingID.OldestUnacked = 0;
1639 1653
1640 OutPacket(pc, ThrottleOutPacketType.Unknown); 1654 OutPacket(pc, ThrottleOutPacketType.Unknown);
1655 UDPClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount();
1641 } 1656 }
1642 1657
1643 public void SendKillObject(List<uint> localIDs) 1658 public void SendKillObject(List<uint> localIDs)
@@ -3813,8 +3828,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3813 { 3828 {
3814 SceneObjectPart e = (SceneObjectPart)entity; 3829 SceneObjectPart e = (SceneObjectPart)entity;
3815 SceneObjectGroup g = e.ParentGroup; 3830 SceneObjectGroup g = e.ParentGroup;
3816 if (g.RootPart.Shape.State > 30 && g.RootPart.Shape.State < 39) // HUD 3831 if (g.HasPrivateAttachmentPoint && g.OwnerID != AgentId)
3817 if (g.OwnerID != AgentId)
3818 return; // Don't send updates for other people's HUDs 3832 return; // Don't send updates for other people's HUDs
3819 } 3833 }
3820 3834
@@ -3824,47 +3838,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3824 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); 3838 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
3825 } 3839 }
3826 3840
3827 /// <summary> 3841 /* dont use this
3828 /// Requeue an EntityUpdate when it was not acknowledged by the client. 3842 udp packet resent must be done at udp level only
3829 /// We will update the priority and put it in the correct queue, merging update flags 3843 re map from a packet to original updates just doesnt work
3830 /// with any other updates that may be queued for the same entity.
3831 /// The original update time is used for the merged update.
3832 /// </summary>
3833 private void ResendPrimUpdate(EntityUpdate update)
3834 {
3835 // If the update exists in priority queue, it will be updated.
3836 // If it does not exist then it will be added with the current (rather than its original) priority
3837 uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
3838 3844
3839 lock (m_entityUpdates.SyncRoot) 3845 /// <summary>
3840 m_entityUpdates.Enqueue(priority, update); 3846 /// Requeue an EntityUpdate when it was not acknowledged by the client.
3841 } 3847 /// We will update the priority and put it in the correct queue, merging update flags
3848 /// with any other updates that may be queued for the same entity.
3849 /// The original update time is used for the merged update.
3850 /// </summary>
3851 private void ResendPrimUpdate(EntityUpdate update)
3852 {
3853 // If the update exists in priority queue, it will be updated.
3854 // If it does not exist then it will be added with the current (rather than its original) priority
3855 uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
3842 3856
3843 /// <summary> 3857 lock (m_entityUpdates.SyncRoot)
3844 /// Requeue a list of EntityUpdates when they were not acknowledged by the client. 3858 m_entityUpdates.Enqueue(priority, update);
3845 /// We will update the priority and put it in the correct queue, merging update flags 3859 }
3846 /// with any other updates that may be queued for the same entity.
3847 /// The original update time is used for the merged update.
3848 /// </summary>
3849 private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
3850 {
3851 // m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber);
3852 3860
3853 // Remove the update packet from the list of packets waiting for acknowledgement
3854 // because we are requeuing the list of updates. They will be resent in new packets
3855 // with the most recent state and priority.
3856 m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
3857 3861
3858 // Count this as a resent packet since we are going to requeue all of the updates contained in it 3862 /// <summary>
3859 Interlocked.Increment(ref m_udpClient.PacketsResent); 3863 /// Requeue a list of EntityUpdates when they were not acknowledged by the client.
3864 /// We will update the priority and put it in the correct queue, merging update flags
3865 /// with any other updates that may be queued for the same entity.
3866 /// The original update time is used for the merged update.
3867 /// </summary>
3868 private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
3869 {
3870 // m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber);
3860 3871
3861 // We're not going to worry about interlock yet since its not currently critical that this total count 3872 // Remove the update packet from the list of packets waiting for acknowledgement
3862 // is 100% correct 3873 // because we are requeuing the list of updates. They will be resent in new packets
3863 m_udpServer.PacketsResentCount++; 3874 // with the most recent state and priority.
3875 m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
3864 3876
3865 foreach (EntityUpdate update in updates) 3877 // Count this as a resent packet since we are going to requeue all of the updates contained in it
3866 ResendPrimUpdate(update); 3878 Interlocked.Increment(ref m_udpClient.PacketsResent);
3867 } 3879
3880 // We're not going to worry about interlock yet since its not currently critical that this total count
3881 // is 100% correct
3882 m_udpServer.PacketsResentCount++;
3883
3884 foreach (EntityUpdate update in updates)
3885 ResendPrimUpdate(update);
3886 }
3887 */
3868 3888
3869// OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3889// OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
3870// OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>(); 3890// OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
@@ -3932,8 +3952,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3932 3952
3933 if (part.ParentGroup.IsAttachment) 3953 if (part.ParentGroup.IsAttachment)
3934 { // Someone else's HUD, why are we getting these? 3954 { // Someone else's HUD, why are we getting these?
3935 if (part.ParentGroup.OwnerID != AgentId && 3955 if (part.ParentGroup.OwnerID != AgentId && part.ParentGroup.HasPrivateAttachmentPoint)
3936 part.ParentGroup.RootPart.Shape.State > 30 && part.ParentGroup.RootPart.Shape.State < 39)
3937 continue; 3956 continue;
3938 ScenePresence sp; 3957 ScenePresence sp;
3939 // Owner is not in the sim, don't update it to 3958 // Owner is not in the sim, don't update it to
@@ -4184,12 +4203,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4184 for (int i = 0; i < blocks.Count; i++) 4203 for (int i = 0; i < blocks.Count; i++)
4185 packet.ObjectData[i] = blocks[i]; 4204 packet.ObjectData[i] = blocks[i];
4186 4205
4187 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4206// OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4207 // use default udp retry
4208 OutPacket(packet, ThrottleOutPacketType.Task, true);
4188 } 4209 }
4189 4210
4211
4212
4190 #endregion Packet Sending 4213 #endregion Packet Sending
4214
4191 } 4215 }
4192 4216
4217 // hack.. dont use
4218 public void SendPartFullUpdate(ISceneEntity ent, uint? parentID)
4219 {
4220 if (ent is SceneObjectPart)
4221 {
4222 SceneObjectPart part = (SceneObjectPart)ent;
4223 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4224 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4225 packet.RegionData.TimeDilation = 1;
4226 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
4227
4228 ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, this.m_agentId);
4229 if (parentID.HasValue)
4230 {
4231 blk.ParentID = parentID.Value;
4232 }
4233
4234 packet.ObjectData[0] = blk;
4235
4236 OutPacket(packet, ThrottleOutPacketType.Task, true);
4237 }
4238 }
4239
4193 public void ReprioritizeUpdates() 4240 public void ReprioritizeUpdates()
4194 { 4241 {
4195 lock (m_entityUpdates.SyncRoot) 4242 lock (m_entityUpdates.SyncRoot)
@@ -5278,16 +5325,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5278 5325
5279 byte[] objectData = new byte[76]; 5326 byte[] objectData = new byte[76];
5280 5327
5281 data.CollisionPlane.ToBytes(objectData, 0);
5282 offsetPosition.ToBytes(objectData, 16);
5283 Vector3 velocity = new Vector3(0, 0, 0); 5328 Vector3 velocity = new Vector3(0, 0, 0);
5284 Vector3 acceleration = new Vector3(0, 0, 0); 5329 Vector3 acceleration = new Vector3(0, 0, 0);
5330 rotation.Normalize();
5331 Vector3 vrot = new Vector3(rotation.X, rotation.Y, rotation.Z);
5332
5333 data.CollisionPlane.ToBytes(objectData, 0);
5334 offsetPosition.ToBytes(objectData, 16);
5285 velocity.ToBytes(objectData, 28); 5335 velocity.ToBytes(objectData, 28);
5286 acceleration.ToBytes(objectData, 40); 5336 acceleration.ToBytes(objectData, 40);
5287// data.Velocity.ToBytes(objectData, 28); 5337 vrot.ToBytes(objectData, 52);
5288// data.Acceleration.ToBytes(objectData, 40); 5338 data.AngularVelocity.ToBytes(objectData, 64);
5289 rotation.ToBytes(objectData, 52);
5290 //data.AngularVelocity.ToBytes(objectData, 64);
5291 5339
5292 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5340 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
5293 5341
@@ -5343,15 +5391,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5343 data.RelativePosition.ToBytes(objectData, 0); 5391 data.RelativePosition.ToBytes(objectData, 0);
5344 data.Velocity.ToBytes(objectData, 12); 5392 data.Velocity.ToBytes(objectData, 12);
5345 data.Acceleration.ToBytes(objectData, 24); 5393 data.Acceleration.ToBytes(objectData, 24);
5346 try 5394
5347 { 5395 Quaternion rotation = data.RotationOffset;
5348 data.RotationOffset.ToBytes(objectData, 36); 5396 rotation.Normalize();
5349 } 5397 Vector3 vrot = new Vector3(rotation.X, rotation.Y, rotation.Z);
5350 catch (Exception e) 5398 vrot.ToBytes(objectData, 36);
5351 {
5352 m_log.Warn("[LLClientView]: exception converting quaternion to bytes, using Quaternion.Identity. Exception: " + e.ToString());
5353 OpenMetaverse.Quaternion.Identity.ToBytes(objectData, 36);
5354 }
5355 data.AngularVelocity.ToBytes(objectData, 48); 5399 data.AngularVelocity.ToBytes(objectData, 48);
5356 5400
5357 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5401 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index bd4e617..fe31bd9 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -163,6 +163,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
163 private int m_maxRTO = 60000; 163 private int m_maxRTO = 60000;
164 public bool m_deliverPackets = true; 164 public bool m_deliverPackets = true;
165 165
166 public int m_lastStartpingTimeMS;
167 public int m_pingMS;
168
169 public int PingTimeMS
170 {
171 get
172 {
173 if (m_pingMS < 10)
174 return 10;
175 if(m_pingMS > 2000)
176 return 2000;
177 return m_pingMS;
178 }
179 }
180
166 /// <summary> 181 /// <summary>
167 /// This is the percentage of the udp texture queue to add to the task queue since 182 /// This is the percentage of the udp texture queue to add to the task queue since
168 /// textures are now generally handled through http. 183 /// textures are now generally handled through http.
@@ -225,6 +240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
225 240
226 // Initialize this to a sane value to prevent early disconnects 241 // Initialize this to a sane value to prevent early disconnects
227 TickLastPacketReceived = Environment.TickCount & Int32.MaxValue; 242 TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
243 m_pingMS = (int)(3.0 * server.TickCountResolution); // so filter doesnt start at 0;
228 } 244 }
229 245
230 /// <summary> 246 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index fe79f87..3b0312d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -293,6 +293,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
293 /// <summary>Flag to signal when clients should send pings</summary> 293 /// <summary>Flag to signal when clients should send pings</summary>
294 protected bool m_sendPing; 294 protected bool m_sendPing;
295 295
296 private int m_animationSequenceNumber;
297
298 public int NextAnimationSequenceNumber
299 {
300 get
301 {
302 m_animationSequenceNumber++;
303 if (m_animationSequenceNumber > 2147482624)
304 m_animationSequenceNumber = 1;
305 return m_animationSequenceNumber;
306 }
307 }
308
309
310
296 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); 311 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
297 312
298 /// <summary> 313 /// <summary>
@@ -369,16 +384,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
369 384
370 // Measure the resolution of Environment.TickCount 385 // Measure the resolution of Environment.TickCount
371 TickCountResolution = 0f; 386 TickCountResolution = 0f;
372 for (int i = 0; i < 5; i++) 387 for (int i = 0; i < 10; i++)
373 { 388 {
374 int start = Environment.TickCount; 389 int start = Environment.TickCount;
375 int now = start; 390 int now = start;
376 while (now == start) 391 while (now == start)
377 now = Environment.TickCount; 392 now = Environment.TickCount;
378 TickCountResolution += (float)(now - start) * 0.2f; 393 TickCountResolution += (float)(now - start) * 0.1f;
379 } 394 }
380 m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms");
381 TickCountResolution = (float)Math.Ceiling(TickCountResolution); 395 TickCountResolution = (float)Math.Ceiling(TickCountResolution);
396 m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms");
382 397
383 #endregion Environment.TickCount Measurement 398 #endregion Environment.TickCount Measurement
384 399
@@ -386,6 +401,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
386 int sceneThrottleBps = 0; 401 int sceneThrottleBps = 0;
387 bool usePools = false; 402 bool usePools = false;
388 403
404
405
389 IConfig config = configSource.Configs["ClientStack.LindenUDP"]; 406 IConfig config = configSource.Configs["ClientStack.LindenUDP"];
390 if (config != null) 407 if (config != null)
391 { 408 {
@@ -435,6 +452,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
435 m_throttle = new TokenBucket(null, sceneThrottleBps); 452 m_throttle = new TokenBucket(null, sceneThrottleBps);
436 ThrottleRates = new ThrottleRates(configSource); 453 ThrottleRates = new ThrottleRates(configSource);
437 454
455 Random rnd = new Random(Util.EnvironmentTickCount());
456 m_animationSequenceNumber = rnd.Next(11474826);
457
438 if (usePools) 458 if (usePools)
439 EnablePools(); 459 EnablePools();
440 } 460 }
@@ -1128,6 +1148,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1128 pc.PingID.OldestUnacked = 0; 1148 pc.PingID.OldestUnacked = 0;
1129 1149
1130 SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null); 1150 SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null);
1151 udpClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount();
1131 } 1152 }
1132 1153
1133 public void CompletePing(LLUDPClient udpClient, byte pingID) 1154 public void CompletePing(LLUDPClient udpClient, byte pingID)
@@ -1567,7 +1588,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1567 // We don't need to do anything else with ping checks 1588 // We don't need to do anything else with ping checks
1568 StartPingCheckPacket startPing = (StartPingCheckPacket)packet; 1589 StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
1569 CompletePing(udpClient, startPing.PingID.PingID); 1590 CompletePing(udpClient, startPing.PingID.PingID);
1570 1591
1571 if ((Environment.TickCount - m_elapsedMSSinceLastStatReport) >= 3000) 1592 if ((Environment.TickCount - m_elapsedMSSinceLastStatReport) >= 3000)
1572 { 1593 {
1573 udpClient.SendPacketStats(); 1594 udpClient.SendPacketStats();
@@ -1577,7 +1598,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1577 } 1598 }
1578 else if (packet.Type == PacketType.CompletePingCheck) 1599 else if (packet.Type == PacketType.CompletePingCheck)
1579 { 1600 {
1580 // We don't currently track client ping times 1601 int t = Util.EnvironmentTickCountSubtract(udpClient.m_lastStartpingTimeMS);
1602 int c = udpClient.m_pingMS;
1603 c = 800 * c + 200 * t;
1604 c /= 1000;
1605 udpClient.m_pingMS = c;
1581 return; 1606 return;
1582 } 1607 }
1583 1608