aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs627
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs18
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs36
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs29
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs34
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs14
7 files changed, 360 insertions, 412 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 1f3582c..6154da4 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
@@ -463,9 +435,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
463 435
464 m_scene = scene; 436 m_scene = scene;
465 437
466 m_avatarTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); 438 m_entityUpdates = new PriorityQueue<double, EntityUpdate>(m_scene.Entities.Count);
467 m_primTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
468 m_primFullUpdates = new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(m_scene.Entities.Count);
469 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 439 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
470 m_killRecord = new HashSet<uint>(); 440 m_killRecord = new HashSet<uint>();
471 441
@@ -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,71 +3389,24 @@ 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 3406
3433 OutPacket(objupdate, ThrottleOutPacketType.Task); 3407 OutPacket(objupdate, ThrottleOutPacketType.Task);
3434 } 3408 }
3435 3409
3436 /// <summary>
3437 /// Send a terse positional/rotation/velocity update about an avatar
3438 /// to the client. This avatar can be that of the client itself.
3439 /// </summary>
3440 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
3441 {
3442 if (data.Priority == double.NaN)
3443 {
3444 m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update");
3445 return;
3446 }
3447
3448 Quaternion rotation = data.Rotation;
3449 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
3450 rotation = Quaternion.Identity;
3451
3452 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data);
3453
3454 lock (m_avatarTerseUpdates.SyncRoot)
3455 m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID);
3456
3457 // If we received an update about our own avatar, process the avatar update priority queue immediately
3458 if (data.AgentID == m_agentId)
3459 ProcessAvatarTerseUpdates();
3460 }
3461
3462 protected void ProcessAvatarTerseUpdates()
3463 {
3464 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3465 terse.Header.Reliable = false;
3466 terse.Header.Zerocoded = true;
3467
3468 //terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
3469 terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
3470 terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3471
3472 lock (m_avatarTerseUpdates.SyncRoot)
3473 {
3474 int count = Math.Min(m_avatarTerseUpdates.Count, m_udpServer.AvatarTerseUpdatesPerPacket);
3475 if (count == 0)
3476 return;
3477
3478 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
3479 for (int i = 0; i < count; i++)
3480 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3481 }
3482
3483 // HACK: Using the task category until the tiered reprioritization code is in
3484 OutPacket(terse, ThrottleOutPacketType.Task);
3485 }
3486
3487 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 3410 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
3488 { 3411 {
3489 if (!IsActive) return; // We don't need to update inactive clients. 3412 if (!IsActive) return; // We don't need to update inactive clients.
@@ -3528,172 +3451,188 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3528 3451
3529 #region Primitive Packet/Data Sending Methods 3452 #region Primitive Packet/Data Sending Methods
3530 3453
3531 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)
3532 { 3459 {
3533// string text = data.text; 3460 double priority;
3534// if (text.IndexOf("\n") >= 0)
3535// text = text.Remove(text.IndexOf("\n"));
3536// m_log.DebugFormat(
3537// "[CLIENT]: Placing request to send full info about prim {0} text {1} to client {2}",
3538// data.localID, text, Name);
3539
3540 if (data.priority == double.NaN)
3541 {
3542 m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update");
3543 return;
3544 }
3545
3546 Quaternion rotation = data.rotation;
3547 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
3548 rotation = Quaternion.Identity;
3549
3550 if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD
3551 return;
3552 if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9)
3553 return;
3554 3461
3555 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;
3556 3468
3557 lock (m_primFullUpdates.SyncRoot) 3469 lock (m_entityUpdates.SyncRoot)
3558 m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); 3470 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId);
3559 } 3471 }
3560 3472
3561 void ProcessPrimFullUpdates() 3473 private void ProcessEntityUpdates(int maxUpdates)
3562 { 3474 {
3563 ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3475 Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
3564 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>>();
3565 3478
3566 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; 3479 int updatesThisCall = 0;
3567 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3568 3480
3569 lock (m_primFullUpdates.SyncRoot) 3481 lock (m_entityUpdates.SyncRoot)
3570 { 3482 {
3571 int count = Math.Min(m_primFullUpdates.Count, m_udpServer.PrimFullUpdatesPerPacket); 3483 EntityUpdate update;
3572 if (count == 0) 3484 while (m_entityUpdates.TryDequeue(out update))
3573 return;
3574
3575 m_fullUpdateDataBlocksBuilder.Clear();
3576
3577 for (int i = 0; i < count; i++)
3578 { 3485 {
3579 ObjectUpdatePacket.ObjectDataBlock block = m_primFullUpdates.Dequeue(); 3486 #region UpdateFlags to packet type conversion
3487
3488 PrimUpdateFlags updateFlags = update.Flags;
3580 3489
3581 if (!m_killRecord.Contains(block.ID)) 3490 bool canUseCompressed = true;
3491 bool canUseImproved = true;
3492
3493 // Compressed object updates only make sense for LL primitives
3494 if (!(update.Entity is SceneObjectPart))
3495 canUseCompressed = false;
3496
3497 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3582 { 3498 {
3583 m_fullUpdateDataBlocksBuilder.Add(block); 3499 canUseCompressed = false;
3584 3500 canUseImproved = false;
3585// string text = Util.FieldToString(outPacket.ObjectData[i].Text); 3501 }
3586// if (text.IndexOf("\n") >= 0) 3502 else
3587// text = text.Remove(text.IndexOf("\n")); 3503 {
3588// m_log.DebugFormat( 3504 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3589// "[CLIENT]: Sending full info about prim {0} text {1} to client {2}", 3505 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3590// outPacket.ObjectData[i].ID, text, Name); 3506 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3507 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3508 {
3509 canUseCompressed = false;
3510 }
3511
3512 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3513 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3514 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3515 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3516 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3517 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3518 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3519 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3520 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3521 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3522 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3523 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3524 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3525 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3526 {
3527 canUseImproved = false;
3528 }
3529 }
3530
3531 #endregion UpdateFlags to packet type conversion
3532
3533 #region Block Construction
3534
3535 // TODO: Remove this once we can build compressed updates
3536 canUseCompressed = false;
3537
3538 if (!canUseImproved && !canUseCompressed)
3539 {
3540 if (update.Entity is ScenePresence)
3541 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3542 else
3543 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3591 } 3544 }
3592// else 3545 else if (!canUseImproved)
3593// { 3546 {
3594// m_log.WarnFormat( 3547 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3595// "[CLIENT]: Preventing full update for {0} after kill to {1}", block.ID, Name); 3548 }
3596// } 3549 else
3550 {
3551 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3552 }
3553
3554 #endregion Block Construction
3555
3556 ++updatesThisCall;
3557 if (maxUpdates > 0 && updatesThisCall >= maxUpdates)
3558 break;
3597 } 3559 }
3560 }
3598 3561
3599 outPacket.ObjectData = m_fullUpdateDataBlocksBuilder.ToArray(); 3562 #region Packet Sending
3600
3601 OutPacket(outPacket, ThrottleOutPacketType.State);
3602 }
3603 }
3604 3563
3605 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 3564 const float TIME_DILATION = 1.0f;
3606 { 3565 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
3607 if (data.Priority == double.NaN) 3566
3567 if (objectUpdateBlocks.IsValueCreated)
3608 { 3568 {
3609 m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); 3569 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3610 return;
3611 }
3612 3570
3613 Quaternion rotation = data.Rotation; 3571 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3614 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) 3572 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3615 rotation = Quaternion.Identity; 3573 packet.RegionData.TimeDilation = timeDilation;
3574 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3616 3575
3617 if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD 3576 for (int i = 0; i < blocks.Count; i++)
3618 return; 3577 packet.ObjectData[i] = blocks[i];
3578
3579 OutPacket(packet, ThrottleOutPacketType.Task, true);
3580 }
3619 3581
3620 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data); 3582 if (compressedUpdateBlocks.IsValueCreated)
3583 {
3584 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3621 3585
3622 lock (m_primTerseUpdates.SyncRoot) 3586 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3623 m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID); 3587 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3624 } 3588 packet.RegionData.TimeDilation = timeDilation;
3589 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3625 3590
3626 void ProcessPrimTerseUpdates() 3591 for (int i = 0; i < blocks.Count; i++)
3627 { 3592 packet.ObjectData[i] = blocks[i];
3628 ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3629 outPacket.Header.Reliable = false;
3630 outPacket.Header.Zerocoded = true;
3631 3593
3632 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; 3594 OutPacket(packet, ThrottleOutPacketType.Task, true);
3633 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); 3595 }
3634 3596
3635 lock (m_primTerseUpdates.SyncRoot) 3597 if (terseUpdateBlocks.IsValueCreated)
3636 { 3598 {
3637 int count = Math.Min(m_primTerseUpdates.Count, m_udpServer.PrimTerseUpdatesPerPacket); 3599 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3638 if (count == 0) 3600
3639 return; 3601 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3602 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3603 packet.RegionData.TimeDilation = timeDilation;
3604 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3640 3605
3641 outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; 3606 for (int i = 0; i < blocks.Count; i++)
3642 for (int i = 0; i < count; i++) 3607 packet.ObjectData[i] = blocks[i];
3643 outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue(); 3608
3609 OutPacket(packet, ThrottleOutPacketType.Task, true);
3644 } 3610 }
3645 3611
3646 OutPacket(outPacket, ThrottleOutPacketType.State); 3612 #endregion Packet Sending
3647 } 3613 }
3648 3614
3649 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 3615 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
3650 { 3616 {
3651 PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler = 3617 //m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName);
3652 delegate(ref double priority, uint local_id) 3618
3653 { 3619 PriorityQueue<double, EntityUpdate>.UpdatePriorityHandler update_priority_handler =
3654 priority = handler(new UpdatePriorityData(priority, local_id));
3655 return priority != double.NaN;
3656 };
3657 PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler =
3658 delegate(ref double priority, uint local_id) 3620 delegate(ref double priority, uint local_id)
3659 { 3621 {
3660 priority = handler(new UpdatePriorityData(priority, local_id)); 3622 priority = handler(new UpdatePriorityData(priority, local_id));
3661 return priority != double.NaN; 3623 return priority != double.NaN;
3662 }; 3624 };
3663 3625
3664 if ((type & StateUpdateTypes.AvatarTerse) != 0) 3626 lock (m_entityUpdates.SyncRoot)
3665 { 3627 m_entityUpdates.Reprioritize(update_priority_handler);
3666 lock (m_avatarTerseUpdates.SyncRoot)
3667 m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler);
3668 }
3669
3670 if ((type & StateUpdateTypes.PrimitiveFull) != 0)
3671 {
3672 lock (m_primFullUpdates.SyncRoot)
3673 m_primFullUpdates.Reprioritize(update_priority_handler);
3674 }
3675
3676 if ((type & StateUpdateTypes.PrimitiveTerse) != 0)
3677 {
3678 lock (m_primTerseUpdates.SyncRoot)
3679 m_primTerseUpdates.Reprioritize(terse_update_priority_handler);
3680 }
3681 } 3628 }
3682 3629
3683 public void FlushPrimUpdates() 3630 public void FlushPrimUpdates()
3684 { 3631 {
3685 while (m_primFullUpdates.Count > 0) 3632 m_log.Debug("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName);
3686 { 3633
3687 ProcessPrimFullUpdates(); 3634 while (m_entityUpdates.Count > 0)
3688 } 3635 ProcessEntityUpdates(-1);
3689 while (m_primTerseUpdates.Count > 0)
3690 {
3691 ProcessPrimTerseUpdates();
3692 }
3693 while (m_avatarTerseUpdates.Count > 0)
3694 {
3695 ProcessAvatarTerseUpdates();
3696 }
3697 } 3636 }
3698 3637
3699 #endregion Primitive Packet/Data Sending Methods 3638 #endregion Primitive Packet/Data Sending Methods
@@ -3726,26 +3665,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3726 { 3665 {
3727 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) 3666 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
3728 { 3667 {
3729 lock (m_avatarTerseUpdates.SyncRoot) 3668 if (m_entityUpdates.Count > 0)
3730 { 3669 ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback);
3731 if (m_avatarTerseUpdates.Count > 0)
3732 ProcessAvatarTerseUpdates();
3733 }
3734 }
3735
3736 if ((categories & ThrottleOutPacketTypeFlags.State) != 0)
3737 {
3738 lock (m_primFullUpdates.SyncRoot)
3739 {
3740 if (m_primFullUpdates.Count > 0)
3741 ProcessPrimFullUpdates();
3742 }
3743
3744 lock (m_primTerseUpdates.SyncRoot)
3745 {
3746 if (m_primTerseUpdates.Count > 0)
3747 ProcessPrimTerseUpdates();
3748 }
3749 } 3670 }
3750 3671
3751 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) 3672 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
@@ -4403,22 +4324,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4403 4324
4404 #region Helper Methods 4325 #region Helper Methods
4405 4326
4406 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data) 4327 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture)
4407 { 4328 {
4408 return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity, 4329 #region ScenePresence/SOP Handling
4409 data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry);
4410 }
4411 4330
4412 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data) 4331 bool avatar = (entity is ScenePresence);
4413 { 4332 uint localID = entity.LocalId;
4414 return CreateImprovedTerseBlock(false, data.LocalID, data.AttachPoint, Vector4.Zero, data.Position, data.Velocity, 4333 uint attachPoint;
4415 data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry); 4334 Vector4 collisionPlane;
4416 } 4335 Vector3 position, velocity, acceleration, angularVelocity;
4336 Quaternion rotation;
4337 byte[] textureEntry;
4338
4339 if (entity is ScenePresence)
4340 {
4341 ScenePresence presence = (ScenePresence)entity;
4342
4343 attachPoint = 0;
4344 collisionPlane = presence.CollisionPlane;
4345 position = presence.OffsetPosition;
4346 velocity = presence.Velocity;
4347 acceleration = Vector3.Zero;
4348 angularVelocity = Vector3.Zero;
4349 rotation = presence.Rotation;
4350
4351 if (sendTexture)
4352 textureEntry = presence.Appearance.Texture.GetBytes();
4353 else
4354 textureEntry = null;
4355 }
4356 else
4357 {
4358 SceneObjectPart part = (SceneObjectPart)entity;
4359
4360 attachPoint = part.AttachmentPoint;
4361 collisionPlane = Vector4.Zero;
4362 position = part.RelativePosition;
4363 velocity = part.Velocity;
4364 acceleration = part.Acceleration;
4365 angularVelocity = part.AngularVelocity;
4366 rotation = part.RotationOffset;
4367 textureEntry = part.Shape.TextureEntry;
4368 }
4369
4370 #endregion ScenePresence/SOP Handling
4417 4371
4418 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, int attachPoint,
4419 Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation,
4420 Vector3 angularVelocity, byte[] textureEntry)
4421 {
4422 int pos = 0; 4372 int pos = 0;
4423 byte[] data = new byte[(avatar ? 60 : 44)]; 4373 byte[] data = new byte[(avatar ? 60 : 44)];
4424 4374
@@ -4490,12 +4440,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4490 return block; 4440 return block;
4491 } 4441 }
4492 4442
4493 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data) 4443 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4494 { 4444 {
4495 byte[] objectData = new byte[76]; 4445 byte[] objectData = new byte[76];
4496 4446
4497 Vector4.UnitW.ToBytes(objectData, 0); // TODO: Collision plane support 4447 data.CollisionPlane.ToBytes(objectData, 0);
4498 data.Position.ToBytes(objectData, 16); 4448 data.OffsetPosition.ToBytes(objectData, 16);
4499 //data.Velocity.ToBytes(objectData, 28); 4449 //data.Velocity.ToBytes(objectData, 28);
4500 //data.Acceleration.ToBytes(objectData, 40); 4450 //data.Acceleration.ToBytes(objectData, 40);
4501 data.Rotation.ToBytes(objectData, 52); 4451 data.Rotation.ToBytes(objectData, 52);
@@ -4505,12 +4455,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4505 4455
4506 update.Data = Utils.EmptyBytes; 4456 update.Data = Utils.EmptyBytes;
4507 update.ExtraParams = new byte[1]; 4457 update.ExtraParams = new byte[1];
4508 update.FullID = data.AvatarID; 4458 update.FullID = data.UUID;
4509 update.ID = data.AvatarLocalID; 4459 update.ID = data.LocalId;
4510 update.Material = (byte)Material.Flesh; 4460 update.Material = (byte)Material.Flesh;
4511 update.MediaURL = Utils.EmptyBytes; 4461 update.MediaURL = Utils.EmptyBytes;
4512 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " + 4462 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4513 data.LastName + "\nTitle STRING RW SV " + data.GroupTitle); 4463 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4514 update.ObjectData = objectData; 4464 update.ObjectData = objectData;
4515 update.ParentID = data.ParentID; 4465 update.ParentID = data.ParentID;
4516 update.PathCurve = 16; 4466 update.PathCurve = 16;
@@ -4519,102 +4469,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4519 update.PCode = (byte)PCode.Avatar; 4469 update.PCode = (byte)PCode.Avatar;
4520 update.ProfileCurve = 1; 4470 update.ProfileCurve = 1;
4521 update.PSBlock = Utils.EmptyBytes; 4471 update.PSBlock = Utils.EmptyBytes;
4522 update.Scale = new Vector3(0.45f,0.6f,1.9f); 4472 update.Scale = new Vector3(0.45f, 0.6f, 1.9f);
4523 update.Text = Utils.EmptyBytes; 4473 update.Text = Utils.EmptyBytes;
4524 update.TextColor = new byte[4]; 4474 update.TextColor = new byte[4];
4525 update.TextureAnim = Utils.EmptyBytes; 4475 update.TextureAnim = Utils.EmptyBytes;
4526 update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes; 4476 update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
4527 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 4477 update.UpdateFlags = (uint)(
4478 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
4479 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
4480 PrimFlags.ObjectOwnerModify);
4528 4481
4529 return update; 4482 return update;
4530 } 4483 }
4531 4484
4532 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data) 4485 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
4533 { 4486 {
4534 byte[] objectData = new byte[60]; 4487 byte[] objectData = new byte[60];
4535 data.pos.ToBytes(objectData, 0); 4488 data.RelativePosition.ToBytes(objectData, 0);
4536 data.vel.ToBytes(objectData, 12); 4489 data.Velocity.ToBytes(objectData, 12);
4537 data.acc.ToBytes(objectData, 24); 4490 data.Acceleration.ToBytes(objectData, 24);
4538 data.rotation.ToBytes(objectData, 36); 4491 data.RotationOffset.ToBytes(objectData, 36);
4539 data.rvel.ToBytes(objectData, 48); 4492 data.AngularVelocity.ToBytes(objectData, 48);
4540 4493
4541 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 4494 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
4542 update.ClickAction = (byte)data.clickAction; 4495 update.ClickAction = (byte)data.ClickAction;
4543 update.CRC = 0; 4496 update.CRC = 0;
4544 update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes; 4497 update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes;
4545 update.FullID = data.objectID; 4498 update.FullID = data.UUID;
4546 update.ID = data.localID; 4499 update.ID = data.LocalId;
4547 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated 4500 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
4548 //update.JointPivot = Vector3.Zero; 4501 //update.JointPivot = Vector3.Zero;
4549 //update.JointType = 0; 4502 //update.JointType = 0;
4550 update.Material = data.material; 4503 update.Material = data.Material;
4551 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim 4504 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
4552 if (data.attachment) 4505 if (data.IsAttachment)
4553 { 4506 {
4554 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId); 4507 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
4555 update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); 4508 update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16));
4556 } 4509 }
4557 else 4510 else
4558 { 4511 {
4559 update.NameValue = Utils.EmptyBytes; 4512 update.NameValue = Utils.EmptyBytes;
4560 update.State = data.primShape.State; 4513 update.State = data.Shape.State;
4561 } 4514 }
4515
4562 update.ObjectData = objectData; 4516 update.ObjectData = objectData;
4563 update.ParentID = data.parentID; 4517 update.ParentID = data.ParentID;
4564 update.PathBegin = data.primShape.PathBegin; 4518 update.PathBegin = data.Shape.PathBegin;
4565 update.PathCurve = data.primShape.PathCurve; 4519 update.PathCurve = data.Shape.PathCurve;
4566 update.PathEnd = data.primShape.PathEnd; 4520 update.PathEnd = data.Shape.PathEnd;
4567 update.PathRadiusOffset = data.primShape.PathRadiusOffset; 4521 update.PathRadiusOffset = data.Shape.PathRadiusOffset;
4568 update.PathRevolutions = data.primShape.PathRevolutions; 4522 update.PathRevolutions = data.Shape.PathRevolutions;
4569 update.PathScaleX = data.primShape.PathScaleX; 4523 update.PathScaleX = data.Shape.PathScaleX;
4570 update.PathScaleY = data.primShape.PathScaleY; 4524 update.PathScaleY = data.Shape.PathScaleY;
4571 update.PathShearX = data.primShape.PathShearX; 4525 update.PathShearX = data.Shape.PathShearX;
4572 update.PathShearY = data.primShape.PathShearY; 4526 update.PathShearY = data.Shape.PathShearY;
4573 update.PathSkew = data.primShape.PathSkew; 4527 update.PathSkew = data.Shape.PathSkew;
4574 update.PathTaperX = data.primShape.PathTaperX; 4528 update.PathTaperX = data.Shape.PathTaperX;
4575 update.PathTaperY = data.primShape.PathTaperY; 4529 update.PathTaperY = data.Shape.PathTaperY;
4576 update.PathTwist = data.primShape.PathTwist; 4530 update.PathTwist = data.Shape.PathTwist;
4577 update.PathTwistBegin = data.primShape.PathTwistBegin; 4531 update.PathTwistBegin = data.Shape.PathTwistBegin;
4578 update.PCode = data.primShape.PCode; 4532 update.PCode = data.Shape.PCode;
4579 update.ProfileBegin = data.primShape.ProfileBegin; 4533 update.ProfileBegin = data.Shape.ProfileBegin;
4580 update.ProfileCurve = data.primShape.ProfileCurve; 4534 update.ProfileCurve = data.Shape.ProfileCurve;
4581 update.ProfileEnd = data.primShape.ProfileEnd; 4535 update.ProfileEnd = data.Shape.ProfileEnd;
4582 update.ProfileHollow = data.primShape.ProfileHollow; 4536 update.ProfileHollow = data.Shape.ProfileHollow;
4583 update.PSBlock = data.particleSystem ?? Utils.EmptyBytes; 4537 update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes;
4584 update.TextColor = data.color ?? Color4.Black.GetBytes(true); 4538 update.TextColor = data.GetTextColor().GetBytes(false);
4585 update.TextureAnim = data.textureanim ?? Utils.EmptyBytes; 4539 update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes;
4586 update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes; 4540 update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
4587 update.Scale = data.primShape.Scale; 4541 update.Scale = data.Shape.Scale;
4588 update.Text = Util.StringToBytes256(data.text); 4542 update.Text = Util.StringToBytes256(data.Text);
4589 update.UpdateFlags = (uint)data.flags; 4543
4590 4544 #region PrimFlags
4591 if (data.SoundId != UUID.Zero) 4545
4592 { 4546 PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID);
4593 update.Sound = data.SoundId; 4547
4594 update.OwnerID = data.ownerID; 4548 // Don't send the CreateSelected flag to everyone
4595 update.Gain = (float)data.SoundVolume; 4549 flags &= ~PrimFlags.CreateSelected;
4550
4551 if (recipientID == data.OwnerID)
4552 {
4553 if ((data.Flags & PrimFlags.CreateSelected) != 0)
4554 {
4555 // Only send this flag once, then unset it
4556 flags |= PrimFlags.CreateSelected;
4557 data.Flags &= ~PrimFlags.CreateSelected;
4558 }
4559 }
4560
4561 update.UpdateFlags = (uint)flags;
4562
4563 #endregion PrimFlags
4564
4565 if (data.Sound != UUID.Zero)
4566 {
4567 update.Sound = data.Sound;
4568 update.OwnerID = data.OwnerID;
4569 update.Gain = (float)data.SoundGain;
4596 update.Radius = (float)data.SoundRadius; 4570 update.Radius = (float)data.SoundRadius;
4597 update.Flags = data.SoundFlags; 4571 update.Flags = data.SoundFlags;
4598 } 4572 }
4599 4573
4600 switch ((PCode)data.primShape.PCode) 4574 switch ((PCode)data.Shape.PCode)
4601 { 4575 {
4602 case PCode.Grass: 4576 case PCode.Grass:
4603 case PCode.Tree: 4577 case PCode.Tree:
4604 case PCode.NewTree: 4578 case PCode.NewTree:
4605 update.Data = new byte[] { data.primShape.State }; 4579 update.Data = new byte[] { data.Shape.State };
4606 break; 4580 break;
4607 default: 4581 default:
4608 // TODO: Support ScratchPad
4609 //if (prim.ScratchPad != null)
4610 //{
4611 // update.Data = new byte[prim.ScratchPad.Length];
4612 // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length);
4613 //}
4614 //else
4615 //{
4616 // update.Data = Utils.EmptyBytes;
4617 //}
4618 update.Data = Utils.EmptyBytes; 4582 update.Data = Utils.EmptyBytes;
4619 break; 4583 break;
4620 } 4584 }
@@ -4622,6 +4586,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4622 return update; 4586 return update;
4623 } 4587 }
4624 4588
4589 protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags)
4590 {
4591 // TODO: Implement this
4592 return null;
4593 }
4594
4625 public void SendNameReply(UUID profileId, string firstname, string lastname) 4595 public void SendNameReply(UUID profileId, string firstname, string lastname)
4626 { 4596 {
4627 UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply); 4597 UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply);
@@ -11644,7 +11614,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11644 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 11614 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
11645 } 11615 }
11646 11616
11647 internal TValue Dequeue() 11617 internal bool TryDequeue(out TValue value)
11648 { 11618 {
11649 for (int i = 0; i < m_heaps.Length; ++i) 11619 for (int i = 0; i < m_heaps.Length; ++i)
11650 { 11620 {
@@ -11652,10 +11622,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11652 { 11622 {
11653 MinHeapItem item = m_heaps[i].RemoveMin(); 11623 MinHeapItem item = m_heaps[i].RemoveMin();
11654 m_lookupTable.Remove(item.LocalID); 11624 m_lookupTable.Remove(item.LocalID);
11655 return item.Value; 11625 value = item.Value;
11626 return true;
11656 } 11627 }
11657 } 11628 }
11658 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 11629
11630 value = default(TValue);
11631 return false;
11659 } 11632 }
11660 11633
11661 internal void Reprioritize(UpdatePriorityHandler handler) 11634 internal void Reprioritize(UpdatePriorityHandler handler)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 41e41e4..1b81105 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
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 09611af..aac47d1 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -528,14 +528,6 @@ namespace OpenSim.Region.Examples.SimpleModule
528 { 528 {
529 } 529 }
530 530
531 public virtual void SendAvatarData(SendAvatarData data)
532 {
533 }
534
535 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
536 {
537 }
538
539 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 531 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
540 { 532 {
541 } 533 }
@@ -548,15 +540,15 @@ namespace OpenSim.Region.Examples.SimpleModule
548 { 540 {
549 } 541 }
550 542
551 public virtual void SendPrimitiveToClient(SendPrimitiveData data) 543 public void SendAvatarDataImmediate(ISceneEntity avatar)
552 { 544 {
553 } 545 }
554 546
555 public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) 547 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
556 { 548 {
557 } 549 }
558 550
559 public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 551 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
560 { 552 {
561 } 553 }
562 554
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 46eadee..71c8018 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -104,7 +104,7 @@ namespace OpenSim.Region.Framework.Scenes
104 104
105 #endregion Enumerations 105 #endregion Enumerations
106 106
107 public class SceneObjectPart : IScriptHost 107 public class SceneObjectPart : IScriptHost, ISceneEntity
108 { 108 {
109 /// <value> 109 /// <value>
110 /// Denote all sides of the prim 110 /// Denote all sides of the prim
@@ -712,6 +712,24 @@ namespace OpenSim.Region.Framework.Scenes
712 } 712 }
713 } 713 }
714 714
715 public Vector3 RelativePosition
716 {
717 get
718 {
719 if (IsRoot)
720 {
721 if (IsAttachment)
722 return AttachedPos;
723 else
724 return AbsolutePosition;
725 }
726 else
727 {
728 return OffsetPosition;
729 }
730 }
731 }
732
715 public Quaternion RotationOffset 733 public Quaternion RotationOffset
716 { 734 {
717 get 735 get
@@ -973,7 +991,6 @@ namespace OpenSim.Region.Framework.Scenes
973 get { return AggregateScriptEvents; } 991 get { return AggregateScriptEvents; }
974 } 992 }
975 993
976
977 public Quaternion SitTargetOrientation 994 public Quaternion SitTargetOrientation
978 { 995 {
979 get { return m_sitTargetOrientation; } 996 get { return m_sitTargetOrientation; }
@@ -2925,11 +2942,7 @@ namespace OpenSim.Region.Framework.Scenes
2925 //if (LocalId != ParentGroup.RootPart.LocalId) 2942 //if (LocalId != ParentGroup.RootPart.LocalId)
2926 //isattachment = ParentGroup.RootPart.IsAttachment; 2943 //isattachment = ParentGroup.RootPart.IsAttachment;
2927 2944
2928 byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; 2945 remoteClient.SendPrimUpdate(this, PrimUpdateFlags.FullUpdate);
2929 remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape,
2930 lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID,
2931 m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment,
2932 AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient)));
2933 } 2946 }
2934 2947
2935 /// <summary> 2948 /// <summary>
@@ -4640,11 +4653,7 @@ namespace OpenSim.Region.Framework.Scenes
4640 4653
4641 // Causes this thread to dig into the Client Thread Data. 4654 // Causes this thread to dig into the Client Thread Data.
4642 // Remember your locking here! 4655 // Remember your locking here!
4643 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, 4656 remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
4644 m_parentGroup.GetTimeDilation(), LocalId, lPos,
4645 RotationOffset, Velocity, Acceleration,
4646 AngularVelocity, FromItemID,
4647 OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient)));
4648 } 4657 }
4649 4658
4650 public void AddScriptLPS(int count) 4659 public void AddScriptLPS(int count)
@@ -4694,7 +4703,8 @@ namespace OpenSim.Region.Framework.Scenes
4694 4703
4695 public Color4 GetTextColor() 4704 public Color4 GetTextColor()
4696 { 4705 {
4697 return new Color4((byte)Color.R, (byte)Color.G, (byte)Color.B, (byte)(0xFF - Color.A)); 4706 Color color = Color;
4707 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4698 } 4708 }
4699 } 4709 }
4700} 4710}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 30eafd7..ee0eb07 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.Framework.Scenes
67 67
68 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence); 68 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence);
69 69
70 public class ScenePresence : EntityBase 70 public class ScenePresence : EntityBase, ISceneEntity
71 { 71 {
72// ~ScenePresence() 72// ~ScenePresence()
73// { 73// {
@@ -478,6 +478,12 @@ namespace OpenSim.Region.Framework.Scenes
478 } 478 }
479 } 479 }
480 480
481 public Vector3 OffsetPosition
482 {
483 get { return m_pos; }
484 set { m_pos = value; }
485 }
486
481 /// <summary> 487 /// <summary>
482 /// Current velocity of the avatar. 488 /// Current velocity of the avatar.
483 /// </summary> 489 /// </summary>
@@ -1036,8 +1042,9 @@ namespace OpenSim.Region.Framework.Scenes
1036 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1042 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1037 } 1043 }
1038 1044
1039 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1045 ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position);
1040 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1046 //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1047 // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1041 } 1048 }
1042 1049
1043 public void AddNeighbourRegion(ulong regionHandle, string cap) 1050 public void AddNeighbourRegion(ulong regionHandle, string cap)
@@ -2360,8 +2367,7 @@ namespace OpenSim.Region.Framework.Scenes
2360 2367
2361 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); 2368 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity);
2362 2369
2363 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 2370 remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
2364 pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient)));
2365 2371
2366 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2372 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2367 m_scene.StatsReporter.AddAgentUpdates(1); 2373 m_scene.StatsReporter.AddAgentUpdates(1);
@@ -2457,9 +2463,7 @@ namespace OpenSim.Region.Framework.Scenes
2457 Vector3 pos = m_pos; 2463 Vector3 pos = m_pos;
2458 pos.Z += m_appearance.HipOffset; 2464 pos.Z += m_appearance.HipOffset;
2459 2465
2460 remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, 2466 remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this);
2461 LocalId, pos, m_appearance.Texture.GetBytes(),
2462 m_parentID, m_bodyRot));
2463 m_scene.StatsReporter.AddAgentUpdates(1); 2467 m_scene.StatsReporter.AddAgentUpdates(1);
2464 } 2468 }
2465 2469
@@ -2527,8 +2531,7 @@ namespace OpenSim.Region.Framework.Scenes
2527 Vector3 pos = m_pos; 2531 Vector3 pos = m_pos;
2528 pos.Z += m_appearance.HipOffset; 2532 pos.Z += m_appearance.HipOffset;
2529 2533
2530 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, 2534 m_controllingClient.SendAvatarDataImmediate(this);
2531 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot));
2532 2535
2533 SendInitialFullUpdateToAllClients(); 2536 SendInitialFullUpdateToAllClients();
2534 SendAppearanceToAllOtherAgents(); 2537 SendAppearanceToAllOtherAgents();
@@ -2638,9 +2641,7 @@ namespace OpenSim.Region.Framework.Scenes
2638 Vector3 pos = m_pos; 2641 Vector3 pos = m_pos;
2639 pos.Z += m_appearance.HipOffset; 2642 pos.Z += m_appearance.HipOffset;
2640 2643
2641 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, 2644 m_controllingClient.SendAvatarDataImmediate(this);
2642 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot));
2643
2644 } 2645 }
2645 2646
2646 public void SetWearable(int wearableId, AvatarWearable wearable) 2647 public void SetWearable(int wearableId, AvatarWearable wearable)
@@ -3906,7 +3907,7 @@ namespace OpenSim.Region.Framework.Scenes
3906 3907
3907 private void Reprioritize(object sender, ElapsedEventArgs e) 3908 private void Reprioritize(object sender, ElapsedEventArgs e)
3908 { 3909 {
3909 m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority); 3910 m_controllingClient.ReprioritizeUpdates(UpdatePriority);
3910 3911
3911 lock (m_reprioritization_timer) 3912 lock (m_reprioritization_timer)
3912 { 3913 {
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 69e78b3..84faac0 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -1045,16 +1045,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1045 1045
1046 } 1046 }
1047 1047
1048 public void SendAvatarData(SendAvatarData data)
1049 {
1050
1051 }
1052
1053 public void SendAvatarTerseUpdate(SendAvatarTerseData data)
1054 {
1055
1056 }
1057
1058 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 1048 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
1059 { 1049 {
1060 1050
@@ -1065,32 +1055,27 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1065 1055
1066 } 1056 }
1067 1057
1068 public void SetChildAgentThrottle(byte[] throttle) 1058 public void SendAvatarDataImmediate(ISceneEntity avatar)
1069 { 1059 {
1070
1071 }
1072 1060
1073 public void SendPrimitiveToClient(SendPrimitiveData data)
1074 {
1075
1076 } 1061 }
1077 1062
1078 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 1063 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
1079 { 1064 {
1080 1065
1081 } 1066 }
1082 1067
1083 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 1068 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
1084 { 1069 {
1085 1070
1086 } 1071 }
1087 1072
1088 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems) 1073 public void FlushPrimUpdates()
1089 { 1074 {
1090 1075
1091 } 1076 }
1092 1077
1093 public void FlushPrimUpdates() 1078 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems)
1094 { 1079 {
1095 1080
1096 } 1081 }
@@ -1420,6 +1405,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1420 1405
1421 } 1406 }
1422 1407
1408 public virtual void SetChildAgentThrottle(byte[] throttle)
1409 {
1410
1411 }
1412
1423 public byte[] GetThrottlesPacked(float multiplier) 1413 public byte[] GetThrottlesPacked(float multiplier)
1424 { 1414 {
1425 return new byte[0]; 1415 return new byte[0];
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 6360c99..9066691 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -618,14 +618,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
618 { 618 {
619 } 619 }
620 620
621 public virtual void SendAvatarData(SendAvatarData data)
622 {
623 }
624
625 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
626 {
627 }
628
629 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 621 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
630 { 622 {
631 } 623 }
@@ -638,15 +630,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
638 { 630 {
639 } 631 }
640 632
641 public virtual void SendPrimitiveToClient(SendPrimitiveData data) 633 public void SendAvatarDataImmediate(ISceneEntity avatar)
642 { 634 {
643 } 635 }
644 636
645 public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) 637 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
646 { 638 {
647 } 639 }
648 640
649 public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 641 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
650 { 642 {
651 } 643 }
652 644