diff options
Merge branch 'master' into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 630 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 18 |
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 | ||
51 | namespace OpenSim.Region.ClientStack.LindenUDP | 51 | namespace 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 | ||