aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs630
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs18
2 files changed, 308 insertions, 340 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 5b1aa86..e29ae2a 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -50,43 +50,17 @@ using Nini.Config;
50 50
51namespace OpenSim.Region.ClientStack.LindenUDP 51namespace OpenSim.Region.ClientStack.LindenUDP
52{ 52{
53 #region Enums 53 public class EntityUpdate
54
55 /// <summary>
56 /// Specifies the fields that have been changed when sending a prim or
57 /// avatar update
58 /// </summary>
59 [Flags]
60 public enum PrimUpdateFlags : uint
61 { 54 {
62 None = 0, 55 public ISceneEntity Entity;
63 AttachmentPoint = 1 << 0, 56 public PrimUpdateFlags Flags;
64 Material = 1 << 1,
65 ClickAction = 1 << 2,
66 Scale = 1 << 3,
67 ParentID = 1 << 4,
68 PrimFlags = 1 << 5,
69 PrimData = 1 << 6,
70 MediaURL = 1 << 7,
71 ScratchPad = 1 << 8,
72 Textures = 1 << 9,
73 TextureAnim = 1 << 10,
74 NameValue = 1 << 11,
75 Position = 1 << 12,
76 Rotation = 1 << 13,
77 Velocity = 1 << 14,
78 Acceleration = 1 << 15,
79 AngularVelocity = 1 << 16,
80 CollisionPlane = 1 << 17,
81 Text = 1 << 18,
82 Particles = 1 << 19,
83 ExtraData = 1 << 20,
84 Sound = 1 << 21,
85 Joint = 1 << 22,
86 FullUpdate = UInt32.MaxValue
87 }
88 57
89 #endregion Enums 58 public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags)
59 {
60 Entity = entity;
61 Flags = flags;
62 }
63 }
90 64
91 public delegate bool PacketMethod(IClientAPI simClient, Packet packet); 65 public delegate bool PacketMethod(IClientAPI simClient, Packet packet);
92 66
@@ -350,9 +324,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
350 private readonly IGroupsModule m_GroupsModule; 324 private readonly IGroupsModule m_GroupsModule;
351 325
352 private int m_cachedTextureSerial; 326 private int m_cachedTextureSerial;
353 protected PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates; 327 private PriorityQueue<double, EntityUpdate> m_entityUpdates;
354 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates;
355 private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates;
356 328
357 /// <value> 329 /// <value>
358 /// List used in construction of data blocks for an object update packet. This is to stop us having to 330 /// List used in construction of data blocks for an object update packet. This is to stop us having to
@@ -466,9 +438,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
466 438
467 m_scene = scene; 439 m_scene = scene;
468 440
469 m_avatarTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); 441 m_entityUpdates = new PriorityQueue<double, EntityUpdate>(m_scene.Entities.Count);
470 m_primTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
471 m_primFullUpdates = new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(m_scene.Entities.Count);
472 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 442 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
473 m_killRecord = new HashSet<uint>(); 443 m_killRecord = new HashSet<uint>();
474 444
@@ -1519,7 +1489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1519 kill.Header.Reliable = true; 1489 kill.Header.Reliable = true;
1520 kill.Header.Zerocoded = true; 1490 kill.Header.Zerocoded = true;
1521 1491
1522 lock (m_primFullUpdates.SyncRoot) 1492 lock (m_entityUpdates.SyncRoot)
1523 { 1493 {
1524 m_killRecord.Add(localID); 1494 m_killRecord.Add(localID);
1525 OutPacket(kill, ThrottleOutPacketType.State); 1495 OutPacket(kill, ThrottleOutPacketType.State);
@@ -3419,67 +3389,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3419 /// <summary> 3389 /// <summary>
3420 /// Send an ObjectUpdate packet with information about an avatar 3390 /// Send an ObjectUpdate packet with information about an avatar
3421 /// </summary> 3391 /// </summary>
3422 public void SendAvatarData(SendAvatarData data) 3392 public void SendAvatarDataImmediate(ISceneEntity avatar)
3423 { 3393 {
3394 ScenePresence presence = avatar as ScenePresence;
3395 if (presence == null)
3396 return;
3397
3424 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3398 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3425 objupdate.Header.Zerocoded = true; 3399 objupdate.Header.Zerocoded = true;
3426 3400
3427 objupdate.RegionData.RegionHandle = data.RegionHandle; 3401 objupdate.RegionData.RegionHandle = presence.RegionHandle;
3428 objupdate.RegionData.TimeDilation = ushort.MaxValue; 3402 objupdate.RegionData.TimeDilation = ushort.MaxValue;
3429 3403
3430 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3404 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3431 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); 3405 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence);
3432 OutPacket(objupdate, ThrottleOutPacketType.Task);
3433 }
3434
3435 /// <summary>
3436 /// Send a terse positional/rotation/velocity update about an avatar
3437 /// to the client. This avatar can be that of the client itself.
3438 /// </summary>
3439 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
3440 {
3441 if (data.Priority == double.NaN)
3442 {
3443 m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update");
3444 return;
3445 }
3446
3447 Quaternion rotation = data.Rotation;
3448 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
3449 rotation = Quaternion.Identity;
3450 3406
3451 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data); 3407 OutPacket(objupdate, ThrottleOutPacketType.Task);
3452
3453 lock (m_avatarTerseUpdates.SyncRoot)
3454 m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID);
3455
3456 // If we received an update about our own avatar, process the avatar update priority queue immediately
3457 if (data.AgentID == m_agentId)
3458 ProcessAvatarTerseUpdates();
3459 }
3460
3461 protected void ProcessAvatarTerseUpdates()
3462 {
3463 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3464 terse.Header.Reliable = false;
3465 terse.Header.Zerocoded = true;
3466
3467 //terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
3468 terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
3469 terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3470
3471 lock (m_avatarTerseUpdates.SyncRoot)
3472 {
3473 int count = Math.Min(m_avatarTerseUpdates.Count, m_udpServer.AvatarTerseUpdatesPerPacket);
3474 if (count == 0)
3475 return;
3476
3477 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
3478 for (int i = 0; i < count; i++)
3479 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3480 }
3481
3482 OutPacket(terse, ThrottleOutPacketType.State);
3483 } 3408 }
3484 3409
3485 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 3410 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
@@ -3526,172 +3451,187 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3526 3451
3527 #region Primitive Packet/Data Sending Methods 3452 #region Primitive Packet/Data Sending Methods
3528 3453
3529 public void SendPrimitiveToClient(SendPrimitiveData data) 3454 /// <summary>
3455 /// Generate one of the object update packets based on PrimUpdateFlags
3456 /// and broadcast the packet to clients
3457 /// </summary>
3458 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3530 { 3459 {
3531// string text = data.text; 3460 double priority;
3532// if (text.IndexOf("\n") >= 0)
3533// text = text.Remove(text.IndexOf("\n"));
3534// m_log.DebugFormat(
3535// "[CLIENT]: Placing request to send full info about prim {0} text {1} to client {2}",
3536// data.localID, text, Name);
3537
3538 if (data.priority == double.NaN)
3539 {
3540 m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update");
3541 return;
3542 }
3543
3544 Quaternion rotation = data.rotation;
3545 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
3546 rotation = Quaternion.Identity;
3547
3548 if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD
3549 return;
3550 if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9)
3551 return;
3552 3461
3553 ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data); 3462 if (entity is SceneObjectPart)
3463 priority = ((SceneObjectPart)entity).ParentGroup.GetUpdatePriority(this);
3464 else if (entity is ScenePresence)
3465 priority = ((ScenePresence)entity).GetUpdatePriority(this);
3466 else
3467 priority = 0.0d;
3554 3468
3555 lock (m_primFullUpdates.SyncRoot) 3469 lock (m_entityUpdates.SyncRoot)
3556 m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); 3470 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId);
3557 } 3471 }
3558 3472
3559 void ProcessPrimFullUpdates() 3473 private void ProcessEntityUpdates(int maxUpdates)
3560 { 3474 {
3561 ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3475 Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
3562 outPacket.Header.Zerocoded = true; 3476 Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
3477 Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3563 3478
3564 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; 3479 if (maxUpdates <= 0) maxUpdates = Int32.MaxValue;
3565 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); 3480 int updatesThisCall = 0;
3566 3481
3567 lock (m_primFullUpdates.SyncRoot) 3482 lock (m_entityUpdates.SyncRoot)
3568 { 3483 {
3569 int count = Math.Min(m_primFullUpdates.Count, m_udpServer.PrimFullUpdatesPerPacket); 3484 EntityUpdate update;
3570 if (count == 0) 3485 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update))
3571 return;
3572
3573 m_fullUpdateDataBlocksBuilder.Clear();
3574
3575 for (int i = 0; i < count; i++)
3576 { 3486 {
3577 ObjectUpdatePacket.ObjectDataBlock block = m_primFullUpdates.Dequeue(); 3487 ++updatesThisCall;
3488
3489 #region UpdateFlags to packet type conversion
3578 3490
3579 if (!m_killRecord.Contains(block.ID)) 3491 PrimUpdateFlags updateFlags = update.Flags;
3492
3493 bool canUseCompressed = true;
3494 bool canUseImproved = true;
3495
3496 // Compressed object updates only make sense for LL primitives
3497 if (!(update.Entity is SceneObjectPart))
3498 canUseCompressed = false;
3499
3500 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3580 { 3501 {
3581 m_fullUpdateDataBlocksBuilder.Add(block); 3502 canUseCompressed = false;
3582 3503 canUseImproved = false;
3583// string text = Util.FieldToString(outPacket.ObjectData[i].Text); 3504 }
3584// if (text.IndexOf("\n") >= 0) 3505 else
3585// text = text.Remove(text.IndexOf("\n")); 3506 {
3586// m_log.DebugFormat( 3507 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3587// "[CLIENT]: Sending full info about prim {0} text {1} to client {2}", 3508 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3588// outPacket.ObjectData[i].ID, text, Name); 3509 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3510 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3511 {
3512 canUseCompressed = false;
3513 }
3514
3515 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3516 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3517 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3518 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3519 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3520 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3521 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3522 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3523 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3524 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3525 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3526 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3527 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3528 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3529 {
3530 canUseImproved = false;
3531 }
3532 }
3533
3534 #endregion UpdateFlags to packet type conversion
3535
3536 #region Block Construction
3537
3538 // TODO: Remove this once we can build compressed updates
3539 canUseCompressed = false;
3540
3541 if (!canUseImproved && !canUseCompressed)
3542 {
3543 if (update.Entity is ScenePresence)
3544 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3545 else
3546 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3547 }
3548 else if (!canUseImproved)
3549 {
3550 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3589 } 3551 }
3590// else 3552 else
3591// { 3553 {
3592// m_log.WarnFormat( 3554 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3593// "[CLIENT]: Preventing full update for {0} after kill to {1}", block.ID, Name); 3555 }
3594// } 3556
3557 #endregion Block Construction
3595 } 3558 }
3559 }
3596 3560
3597 outPacket.ObjectData = m_fullUpdateDataBlocksBuilder.ToArray(); 3561 #region Packet Sending
3598
3599 OutPacket(outPacket, ThrottleOutPacketType.State);
3600 }
3601 }
3602 3562
3603 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 3563 const float TIME_DILATION = 1.0f;
3604 { 3564 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
3605 if (data.Priority == double.NaN) 3565
3566 if (objectUpdateBlocks.IsValueCreated)
3606 { 3567 {
3607 m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); 3568 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3608 return;
3609 }
3610 3569
3611 Quaternion rotation = data.Rotation; 3570 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3612 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) 3571 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3613 rotation = Quaternion.Identity; 3572 packet.RegionData.TimeDilation = timeDilation;
3573 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3614 3574
3615 if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD 3575 for (int i = 0; i < blocks.Count; i++)
3616 return; 3576 packet.ObjectData[i] = blocks[i];
3617 3577
3618 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data); 3578 OutPacket(packet, ThrottleOutPacketType.Task, true);
3579 }
3619 3580
3620 lock (m_primTerseUpdates.SyncRoot) 3581 if (compressedUpdateBlocks.IsValueCreated)
3621 m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID); 3582 {
3622 } 3583 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3623 3584
3624 void ProcessPrimTerseUpdates() 3585 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3625 { 3586 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3626 ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 3587 packet.RegionData.TimeDilation = timeDilation;
3627 outPacket.Header.Reliable = false; 3588 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3628 outPacket.Header.Zerocoded = true;
3629 3589
3630 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; 3590 for (int i = 0; i < blocks.Count; i++)
3631 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); 3591 packet.ObjectData[i] = blocks[i];
3632 3592
3633 lock (m_primTerseUpdates.SyncRoot) 3593 OutPacket(packet, ThrottleOutPacketType.Task, true);
3594 }
3595
3596 if (terseUpdateBlocks.IsValueCreated)
3634 { 3597 {
3635 int count = Math.Min(m_primTerseUpdates.Count, m_udpServer.PrimTerseUpdatesPerPacket); 3598 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3636 if (count == 0)
3637 return;
3638 3599
3639 outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; 3600 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3640 for (int i = 0; i < count; i++) 3601 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3641 outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue(); 3602 packet.RegionData.TimeDilation = timeDilation;
3603 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3604
3605 for (int i = 0; i < blocks.Count; i++)
3606 packet.ObjectData[i] = blocks[i];
3607
3608 OutPacket(packet, ThrottleOutPacketType.Task, true);
3642 } 3609 }
3643 3610
3644 OutPacket(outPacket, ThrottleOutPacketType.State); 3611 #endregion Packet Sending
3645 } 3612 }
3646 3613
3647 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 3614 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
3648 { 3615 {
3649 PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler = 3616 //m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName);
3650 delegate(ref double priority, uint local_id) 3617
3651 { 3618 PriorityQueue<double, EntityUpdate>.UpdatePriorityHandler update_priority_handler =
3652 priority = handler(new UpdatePriorityData(priority, local_id));
3653 return priority != double.NaN;
3654 };
3655 PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler =
3656 delegate(ref double priority, uint local_id) 3619 delegate(ref double priority, uint local_id)
3657 { 3620 {
3658 priority = handler(new UpdatePriorityData(priority, local_id)); 3621 priority = handler(new UpdatePriorityData(priority, local_id));
3659 return priority != double.NaN; 3622 return priority != double.NaN;
3660 }; 3623 };
3661 3624
3662 if ((type & StateUpdateTypes.AvatarTerse) != 0) 3625 lock (m_entityUpdates.SyncRoot)
3663 { 3626 m_entityUpdates.Reprioritize(update_priority_handler);
3664 lock (m_avatarTerseUpdates.SyncRoot)
3665 m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler);
3666 }
3667
3668 if ((type & StateUpdateTypes.PrimitiveFull) != 0)
3669 {
3670 lock (m_primFullUpdates.SyncRoot)
3671 m_primFullUpdates.Reprioritize(update_priority_handler);
3672 }
3673
3674 if ((type & StateUpdateTypes.PrimitiveTerse) != 0)
3675 {
3676 lock (m_primTerseUpdates.SyncRoot)
3677 m_primTerseUpdates.Reprioritize(terse_update_priority_handler);
3678 }
3679 } 3627 }
3680 3628
3681 public void FlushPrimUpdates() 3629 public void FlushPrimUpdates()
3682 { 3630 {
3683 while (m_primFullUpdates.Count > 0) 3631 m_log.Debug("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName);
3684 { 3632
3685 ProcessPrimFullUpdates(); 3633 while (m_entityUpdates.Count > 0)
3686 } 3634 ProcessEntityUpdates(-1);
3687 while (m_primTerseUpdates.Count > 0)
3688 {
3689 ProcessPrimTerseUpdates();
3690 }
3691 while (m_avatarTerseUpdates.Count > 0)
3692 {
3693 ProcessAvatarTerseUpdates();
3694 }
3695 } 3635 }
3696 3636
3697 #endregion Primitive Packet/Data Sending Methods 3637 #endregion Primitive Packet/Data Sending Methods
@@ -3724,26 +3664,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3724 { 3664 {
3725 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) 3665 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
3726 { 3666 {
3727 lock (m_avatarTerseUpdates.SyncRoot) 3667 if (m_entityUpdates.Count > 0)
3728 { 3668 ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback);
3729 if (m_avatarTerseUpdates.Count > 0)
3730 ProcessAvatarTerseUpdates();
3731 }
3732 }
3733
3734 if ((categories & ThrottleOutPacketTypeFlags.State) != 0)
3735 {
3736 lock (m_primFullUpdates.SyncRoot)
3737 {
3738 if (m_primFullUpdates.Count > 0)
3739 ProcessPrimFullUpdates();
3740 }
3741
3742 lock (m_primTerseUpdates.SyncRoot)
3743 {
3744 if (m_primTerseUpdates.Count > 0)
3745 ProcessPrimTerseUpdates();
3746 }
3747 } 3669 }
3748 3670
3749 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) 3671 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
@@ -4404,22 +4326,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4404 4326
4405 #region Helper Methods 4327 #region Helper Methods
4406 4328
4407 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data) 4329 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture)
4408 { 4330 {
4409 return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity, 4331 #region ScenePresence/SOP Handling
4410 data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry);
4411 }
4412 4332
4413 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data) 4333 bool avatar = (entity is ScenePresence);
4414 { 4334 uint localID = entity.LocalId;
4415 return CreateImprovedTerseBlock(false, data.LocalID, data.AttachPoint, Vector4.Zero, data.Position, data.Velocity, 4335 uint attachPoint;
4416 data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry); 4336 Vector4 collisionPlane;
4417 } 4337 Vector3 position, velocity, acceleration, angularVelocity;
4338 Quaternion rotation;
4339 byte[] textureEntry;
4340
4341 if (entity is ScenePresence)
4342 {
4343 ScenePresence presence = (ScenePresence)entity;
4344
4345 attachPoint = 0;
4346 collisionPlane = presence.CollisionPlane;
4347 position = presence.OffsetPosition;
4348 velocity = presence.Velocity;
4349 acceleration = Vector3.Zero;
4350 angularVelocity = Vector3.Zero;
4351 rotation = presence.Rotation;
4352
4353 if (sendTexture)
4354 textureEntry = presence.Appearance.Texture.GetBytes();
4355 else
4356 textureEntry = null;
4357 }
4358 else
4359 {
4360 SceneObjectPart part = (SceneObjectPart)entity;
4361
4362 attachPoint = part.AttachmentPoint;
4363 collisionPlane = Vector4.Zero;
4364 position = part.RelativePosition;
4365 velocity = part.Velocity;
4366 acceleration = part.Acceleration;
4367 angularVelocity = part.AngularVelocity;
4368 rotation = part.RotationOffset;
4369
4370 if (sendTexture)
4371 textureEntry = part.Shape.TextureEntry;
4372 else
4373 textureEntry = null;
4374 }
4375
4376 #endregion ScenePresence/SOP Handling
4418 4377
4419 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, int attachPoint,
4420 Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation,
4421 Vector3 angularVelocity, byte[] textureEntry)
4422 {
4423 int pos = 0; 4378 int pos = 0;
4424 byte[] data = new byte[(avatar ? 60 : 44)]; 4379 byte[] data = new byte[(avatar ? 60 : 44)];
4425 4380
@@ -4491,12 +4446,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4491 return block; 4446 return block;
4492 } 4447 }
4493 4448
4494 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data) 4449 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4495 { 4450 {
4496 byte[] objectData = new byte[76]; 4451 byte[] objectData = new byte[76];
4497 4452
4498 Vector4.UnitW.ToBytes(objectData, 0); // TODO: Collision plane support 4453 data.CollisionPlane.ToBytes(objectData, 0);
4499 data.Position.ToBytes(objectData, 16); 4454 data.OffsetPosition.ToBytes(objectData, 16);
4500 //data.Velocity.ToBytes(objectData, 28); 4455 //data.Velocity.ToBytes(objectData, 28);
4501 //data.Acceleration.ToBytes(objectData, 40); 4456 //data.Acceleration.ToBytes(objectData, 40);
4502 data.Rotation.ToBytes(objectData, 52); 4457 data.Rotation.ToBytes(objectData, 52);
@@ -4506,12 +4461,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4506 4461
4507 update.Data = Utils.EmptyBytes; 4462 update.Data = Utils.EmptyBytes;
4508 update.ExtraParams = new byte[1]; 4463 update.ExtraParams = new byte[1];
4509 update.FullID = data.AvatarID; 4464 update.FullID = data.UUID;
4510 update.ID = data.AvatarLocalID; 4465 update.ID = data.LocalId;
4511 update.Material = (byte)Material.Flesh; 4466 update.Material = (byte)Material.Flesh;
4512 update.MediaURL = Utils.EmptyBytes; 4467 update.MediaURL = Utils.EmptyBytes;
4513 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " + 4468 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4514 data.LastName + "\nTitle STRING RW SV " + data.GroupTitle); 4469 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4515 update.ObjectData = objectData; 4470 update.ObjectData = objectData;
4516 update.ParentID = data.ParentID; 4471 update.ParentID = data.ParentID;
4517 update.PathCurve = 16; 4472 update.PathCurve = 16;
@@ -4520,102 +4475,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4520 update.PCode = (byte)PCode.Avatar; 4475 update.PCode = (byte)PCode.Avatar;
4521 update.ProfileCurve = 1; 4476 update.ProfileCurve = 1;
4522 update.PSBlock = Utils.EmptyBytes; 4477 update.PSBlock = Utils.EmptyBytes;
4523 update.Scale = new Vector3(0.45f,0.6f,1.9f); 4478 update.Scale = new Vector3(0.45f, 0.6f, 1.9f);
4524 update.Text = Utils.EmptyBytes; 4479 update.Text = Utils.EmptyBytes;
4525 update.TextColor = new byte[4]; 4480 update.TextColor = new byte[4];
4526 update.TextureAnim = Utils.EmptyBytes; 4481 update.TextureAnim = Utils.EmptyBytes;
4527 update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes; 4482 update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
4528 update.UpdateFlags = (uint)(PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | PrimFlags.ObjectOwnerModify);//61 + (9 << 8) + (130 << 16) + (16 << 24); // TODO: Replace these numbers with PrimFlags 4483 update.UpdateFlags = (uint)(
4484 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
4485 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
4486 PrimFlags.ObjectOwnerModify);
4529 4487
4530 return update; 4488 return update;
4531 } 4489 }
4532 4490
4533 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data) 4491 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
4534 { 4492 {
4535 byte[] objectData = new byte[60]; 4493 byte[] objectData = new byte[60];
4536 data.pos.ToBytes(objectData, 0); 4494 data.RelativePosition.ToBytes(objectData, 0);
4537 data.vel.ToBytes(objectData, 12); 4495 data.Velocity.ToBytes(objectData, 12);
4538 data.acc.ToBytes(objectData, 24); 4496 data.Acceleration.ToBytes(objectData, 24);
4539 data.rotation.ToBytes(objectData, 36); 4497 data.RotationOffset.ToBytes(objectData, 36);
4540 data.rvel.ToBytes(objectData, 48); 4498 data.AngularVelocity.ToBytes(objectData, 48);
4541 4499
4542 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 4500 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
4543 update.ClickAction = (byte)data.clickAction; 4501 update.ClickAction = (byte)data.ClickAction;
4544 update.CRC = 0; 4502 update.CRC = 0;
4545 update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes; 4503 update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes;
4546 update.FullID = data.objectID; 4504 update.FullID = data.UUID;
4547 update.ID = data.localID; 4505 update.ID = data.LocalId;
4548 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated 4506 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
4549 //update.JointPivot = Vector3.Zero; 4507 //update.JointPivot = Vector3.Zero;
4550 //update.JointType = 0; 4508 //update.JointType = 0;
4551 update.Material = data.material; 4509 update.Material = data.Material;
4552 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim 4510 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
4553 if (data.attachment) 4511 if (data.IsAttachment)
4554 { 4512 {
4555 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId); 4513 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
4556 update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); 4514 update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16));
4557 } 4515 }
4558 else 4516 else
4559 { 4517 {
4560 update.NameValue = Utils.EmptyBytes; 4518 update.NameValue = Utils.EmptyBytes;
4561 update.State = data.primShape.State; 4519 update.State = data.Shape.State;
4562 } 4520 }
4521
4563 update.ObjectData = objectData; 4522 update.ObjectData = objectData;
4564 update.ParentID = data.parentID; 4523 update.ParentID = data.ParentID;
4565 update.PathBegin = data.primShape.PathBegin; 4524 update.PathBegin = data.Shape.PathBegin;
4566 update.PathCurve = data.primShape.PathCurve; 4525 update.PathCurve = data.Shape.PathCurve;
4567 update.PathEnd = data.primShape.PathEnd; 4526 update.PathEnd = data.Shape.PathEnd;
4568 update.PathRadiusOffset = data.primShape.PathRadiusOffset; 4527 update.PathRadiusOffset = data.Shape.PathRadiusOffset;
4569 update.PathRevolutions = data.primShape.PathRevolutions; 4528 update.PathRevolutions = data.Shape.PathRevolutions;
4570 update.PathScaleX = data.primShape.PathScaleX; 4529 update.PathScaleX = data.Shape.PathScaleX;
4571 update.PathScaleY = data.primShape.PathScaleY; 4530 update.PathScaleY = data.Shape.PathScaleY;
4572 update.PathShearX = data.primShape.PathShearX; 4531 update.PathShearX = data.Shape.PathShearX;
4573 update.PathShearY = data.primShape.PathShearY; 4532 update.PathShearY = data.Shape.PathShearY;
4574 update.PathSkew = data.primShape.PathSkew; 4533 update.PathSkew = data.Shape.PathSkew;
4575 update.PathTaperX = data.primShape.PathTaperX; 4534 update.PathTaperX = data.Shape.PathTaperX;
4576 update.PathTaperY = data.primShape.PathTaperY; 4535 update.PathTaperY = data.Shape.PathTaperY;
4577 update.PathTwist = data.primShape.PathTwist; 4536 update.PathTwist = data.Shape.PathTwist;
4578 update.PathTwistBegin = data.primShape.PathTwistBegin; 4537 update.PathTwistBegin = data.Shape.PathTwistBegin;
4579 update.PCode = data.primShape.PCode; 4538 update.PCode = data.Shape.PCode;
4580 update.ProfileBegin = data.primShape.ProfileBegin; 4539 update.ProfileBegin = data.Shape.ProfileBegin;
4581 update.ProfileCurve = data.primShape.ProfileCurve; 4540 update.ProfileCurve = data.Shape.ProfileCurve;
4582 update.ProfileEnd = data.primShape.ProfileEnd; 4541 update.ProfileEnd = data.Shape.ProfileEnd;
4583 update.ProfileHollow = data.primShape.ProfileHollow; 4542 update.ProfileHollow = data.Shape.ProfileHollow;
4584 update.PSBlock = data.particleSystem ?? Utils.EmptyBytes; 4543 update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes;
4585 update.TextColor = data.color ?? Color4.Black.GetBytes(true); 4544 update.TextColor = data.GetTextColor().GetBytes(false);
4586 update.TextureAnim = data.textureanim ?? Utils.EmptyBytes; 4545 update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes;
4587 update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes; 4546 update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
4588 update.Scale = data.primShape.Scale; 4547 update.Scale = data.Shape.Scale;
4589 update.Text = Util.StringToBytes256(data.text); 4548 update.Text = Util.StringToBytes256(data.Text);
4590 update.UpdateFlags = (uint)data.flags; 4549
4591 4550 #region PrimFlags
4592 if (data.SoundId != UUID.Zero) 4551
4593 { 4552 PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID);
4594 update.Sound = data.SoundId; 4553
4595 update.OwnerID = data.ownerID; 4554 // Don't send the CreateSelected flag to everyone
4596 update.Gain = (float)data.SoundVolume; 4555 flags &= ~PrimFlags.CreateSelected;
4556
4557 if (recipientID == data.OwnerID)
4558 {
4559 if ((data.Flags & PrimFlags.CreateSelected) != 0)
4560 {
4561 // Only send this flag once, then unset it
4562 flags |= PrimFlags.CreateSelected;
4563 data.Flags &= ~PrimFlags.CreateSelected;
4564 }
4565 }
4566
4567 update.UpdateFlags = (uint)flags;
4568
4569 #endregion PrimFlags
4570
4571 if (data.Sound != UUID.Zero)
4572 {
4573 update.Sound = data.Sound;
4574 update.OwnerID = data.OwnerID;
4575 update.Gain = (float)data.SoundGain;
4597 update.Radius = (float)data.SoundRadius; 4576 update.Radius = (float)data.SoundRadius;
4598 update.Flags = data.SoundFlags; 4577 update.Flags = data.SoundFlags;
4599 } 4578 }
4600 4579
4601 switch ((PCode)data.primShape.PCode) 4580 switch ((PCode)data.Shape.PCode)
4602 { 4581 {
4603 case PCode.Grass: 4582 case PCode.Grass:
4604 case PCode.Tree: 4583 case PCode.Tree:
4605 case PCode.NewTree: 4584 case PCode.NewTree:
4606 update.Data = new byte[] { data.primShape.State }; 4585 update.Data = new byte[] { data.Shape.State };
4607 break; 4586 break;
4608 default: 4587 default:
4609 // TODO: Support ScratchPad
4610 //if (prim.ScratchPad != null)
4611 //{
4612 // update.Data = new byte[prim.ScratchPad.Length];
4613 // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length);
4614 //}
4615 //else
4616 //{
4617 // update.Data = Utils.EmptyBytes;
4618 //}
4619 update.Data = Utils.EmptyBytes; 4588 update.Data = Utils.EmptyBytes;
4620 break; 4589 break;
4621 } 4590 }
@@ -4623,6 +4592,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4623 return update; 4592 return update;
4624 } 4593 }
4625 4594
4595 protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags)
4596 {
4597 // TODO: Implement this
4598 return null;
4599 }
4600
4626 public void SendNameReply(UUID profileId, string firstname, string lastname) 4601 public void SendNameReply(UUID profileId, string firstname, string lastname)
4627 { 4602 {
4628 UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply); 4603 UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply);
@@ -11672,7 +11647,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11672 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 11647 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
11673 } 11648 }
11674 11649
11675 internal TValue Dequeue() 11650 internal bool TryDequeue(out TValue value)
11676 { 11651 {
11677 for (int i = 0; i < m_heaps.Length; ++i) 11652 for (int i = 0; i < m_heaps.Length; ++i)
11678 { 11653 {
@@ -11680,10 +11655,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11680 { 11655 {
11681 MinHeapItem item = m_heaps[i].RemoveMin(); 11656 MinHeapItem item = m_heaps[i].RemoveMin();
11682 m_lookupTable.Remove(item.LocalID); 11657 m_lookupTable.Remove(item.LocalID);
11683 return item.Value; 11658 value = item.Value;
11659 return true;
11684 } 11660 }
11685 } 11661 }
11686 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 11662
11663 value = default(TValue);
11664 return false;
11687 } 11665 }
11688 11666
11689 internal void Reprioritize(UpdatePriorityHandler handler) 11667 internal void Reprioritize(UpdatePriorityHandler handler)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index d708055..cda461c 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -99,15 +99,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
99 99
100 /// <summary>The measured resolution of Environment.TickCount</summary> 100 /// <summary>The measured resolution of Environment.TickCount</summary>
101 public readonly float TickCountResolution; 101 public readonly float TickCountResolution;
102 /// <summary>Number of terse prim updates to put on the queue each time the 102 /// <summary>Number of prim updates to put on the queue each time the
103 /// OnQueueEmpty event is triggered for updates</summary> 103 /// OnQueueEmpty event is triggered for updates</summary>
104 public readonly int PrimTerseUpdatesPerPacket; 104 public readonly int PrimUpdatesPerCallback;
105 /// <summary>Number of terse avatar updates to put on the queue each time the
106 /// OnQueueEmpty event is triggered for updates</summary>
107 public readonly int AvatarTerseUpdatesPerPacket;
108 /// <summary>Number of full prim updates to put on the queue each time the
109 /// OnQueueEmpty event is triggered for updates</summary>
110 public readonly int PrimFullUpdatesPerPacket;
111 /// <summary>Number of texture packets to put on the queue each time the 105 /// <summary>Number of texture packets to put on the queue each time the
112 /// OnQueueEmpty event is triggered for textures</summary> 106 /// OnQueueEmpty event is triggered for textures</summary>
113 public readonly int TextureSendLimit; 107 public readonly int TextureSendLimit;
@@ -191,9 +185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
191 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); 185 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
192 sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); 186 sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
193 187
194 PrimTerseUpdatesPerPacket = config.GetInt("PrimTerseUpdatesPerPacket", 25); 188 PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100);
195 AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10);
196 PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100);
197 TextureSendLimit = config.GetInt("TextureSendLimit", 20); 189 TextureSendLimit = config.GetInt("TextureSendLimit", 20);
198 190
199 m_defaultRTO = config.GetInt("DefaultRTO", 0); 191 m_defaultRTO = config.GetInt("DefaultRTO", 0);
@@ -201,9 +193,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
201 } 193 }
202 else 194 else
203 { 195 {
204 PrimTerseUpdatesPerPacket = 25; 196 PrimUpdatesPerCallback = 100;
205 AvatarTerseUpdatesPerPacket = 10;
206 PrimFullUpdatesPerPacket = 100;
207 TextureSendLimit = 20; 197 TextureSendLimit = 20;
208 } 198 }
209 199