diff options
Merge branch 'master' into careminster-presence-refactor
Diffstat (limited to '')
15 files changed, 504 insertions, 419 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 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs index 6c01927..83c8eac 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs | |||
@@ -56,7 +56,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser | |||
56 | // But we could trigger the position update more often | 56 | // But we could trigger the position update more often |
57 | scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; | 57 | scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; |
58 | scene.EventManager.OnNewClient += OnNewClient; | 58 | scene.EventManager.OnNewClient += OnNewClient; |
59 | scene.EventManager.OnAvatarEnteringNewParcel += OnEnteringNewParcel; | ||
60 | 59 | ||
61 | if (m_aScene == null) | 60 | if (m_aScene == null) |
62 | m_aScene = scene; | 61 | m_aScene = scene; |
@@ -105,12 +104,5 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser | |||
105 | 104 | ||
106 | } | 105 | } |
107 | 106 | ||
108 | void OnEnteringNewParcel(ScenePresence sp, int localLandID, UUID regionID) | ||
109 | { | ||
110 | // TODO: grab the parcel ID from ILandModule | ||
111 | // and send that along | ||
112 | m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); | ||
113 | } | ||
114 | |||
115 | } | 107 | } |
116 | } | 108 | } |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs index 1fbc733..1ad4db2 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs | |||
@@ -154,6 +154,22 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
154 | m_landManagementModule.UpdateLandObject(localID, data); | 154 | m_landManagementModule.UpdateLandObject(localID, data); |
155 | } | 155 | } |
156 | } | 156 | } |
157 | |||
158 | public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) | ||
159 | { | ||
160 | if (m_landManagementModule != null) | ||
161 | { | ||
162 | m_landManagementModule.Join(start_x, start_y, end_x, end_y, attempting_user_id); | ||
163 | } | ||
164 | } | ||
165 | |||
166 | public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) | ||
167 | { | ||
168 | if (m_landManagementModule != null) | ||
169 | { | ||
170 | m_landManagementModule.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id); | ||
171 | } | ||
172 | } | ||
157 | 173 | ||
158 | public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) | 174 | public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) |
159 | { | 175 | { |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index d05235e..9d6c9a9 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -956,6 +956,16 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
956 | masterLandObject.SendLandUpdateToAvatarsOverMe(); | 956 | masterLandObject.SendLandUpdateToAvatarsOverMe(); |
957 | } | 957 | } |
958 | 958 | ||
959 | public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) | ||
960 | { | ||
961 | join(start_x, start_y, end_x, end_y, attempting_user_id); | ||
962 | } | ||
963 | |||
964 | public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) | ||
965 | { | ||
966 | subdivide(start_x, start_y, end_x, end_y, attempting_user_id); | ||
967 | } | ||
968 | |||
959 | #endregion | 969 | #endregion |
960 | 970 | ||
961 | #region Parcel Updating | 971 | #region Parcel Updating |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index c454d1f..b6b25ea 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/Interfaces/ILandChannel.cs b/OpenSim/Region/Framework/Interfaces/ILandChannel.cs index f71e31d..20b8ab6 100644 --- a/OpenSim/Region/Framework/Interfaces/ILandChannel.cs +++ b/OpenSim/Region/Framework/Interfaces/ILandChannel.cs | |||
@@ -76,5 +76,8 @@ namespace OpenSim.Region.Framework.Interfaces | |||
76 | void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel); | 76 | void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel); |
77 | void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel); | 77 | void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel); |
78 | void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime); | 78 | void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime); |
79 | |||
80 | void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id); | ||
81 | void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id); | ||
79 | } | 82 | } |
80 | } | 83 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 48e65a5..d174d04 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 |
@@ -714,6 +714,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
714 | } | 714 | } |
715 | } | 715 | } |
716 | 716 | ||
717 | public Vector3 RelativePosition | ||
718 | { | ||
719 | get | ||
720 | { | ||
721 | if (IsRoot) | ||
722 | { | ||
723 | if (IsAttachment) | ||
724 | return AttachedPos; | ||
725 | else | ||
726 | return AbsolutePosition; | ||
727 | } | ||
728 | else | ||
729 | { | ||
730 | return OffsetPosition; | ||
731 | } | ||
732 | } | ||
733 | } | ||
734 | |||
717 | public Quaternion RotationOffset | 735 | public Quaternion RotationOffset |
718 | { | 736 | { |
719 | get | 737 | get |
@@ -985,7 +1003,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
985 | get { return AggregateScriptEvents; } | 1003 | get { return AggregateScriptEvents; } |
986 | } | 1004 | } |
987 | 1005 | ||
988 | |||
989 | public Quaternion SitTargetOrientation | 1006 | public Quaternion SitTargetOrientation |
990 | { | 1007 | { |
991 | get { return m_sitTargetOrientation; } | 1008 | get { return m_sitTargetOrientation; } |
@@ -2911,11 +2928,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2911 | //if (LocalId != ParentGroup.RootPart.LocalId) | 2928 | //if (LocalId != ParentGroup.RootPart.LocalId) |
2912 | //isattachment = ParentGroup.RootPart.IsAttachment; | 2929 | //isattachment = ParentGroup.RootPart.IsAttachment; |
2913 | 2930 | ||
2914 | byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; | 2931 | remoteClient.SendPrimUpdate(this, PrimUpdateFlags.FullUpdate); |
2915 | remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape, | ||
2916 | lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID, | ||
2917 | m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, | ||
2918 | AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient))); | ||
2919 | } | 2932 | } |
2920 | 2933 | ||
2921 | /// <summary> | 2934 | /// <summary> |
@@ -4627,11 +4640,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4627 | 4640 | ||
4628 | // Causes this thread to dig into the Client Thread Data. | 4641 | // Causes this thread to dig into the Client Thread Data. |
4629 | // Remember your locking here! | 4642 | // Remember your locking here! |
4630 | remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, | 4643 | remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); |
4631 | m_parentGroup.GetTimeDilation(), LocalId, lPos, | ||
4632 | RotationOffset, Velocity, Acceleration, | ||
4633 | AngularVelocity, FromItemID, | ||
4634 | OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient))); | ||
4635 | } | 4644 | } |
4636 | 4645 | ||
4637 | public void AddScriptLPS(int count) | 4646 | public void AddScriptLPS(int count) |
@@ -4681,7 +4690,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4681 | 4690 | ||
4682 | public Color4 GetTextColor() | 4691 | public Color4 GetTextColor() |
4683 | { | 4692 | { |
4684 | return new Color4((byte)Color.R, (byte)Color.G, (byte)Color.B, (byte)(0xFF - Color.A)); | 4693 | Color color = Color; |
4694 | return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); | ||
4685 | } | 4695 | } |
4686 | 4696 | ||
4687 | public void ResetOwnerChangeFlag() | 4697 | public void ResetOwnerChangeFlag() |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ad66273..179ecdc 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -68,7 +68,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
68 | 68 | ||
69 | public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence); | 69 | public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence); |
70 | 70 | ||
71 | public class ScenePresence : EntityBase | 71 | public class ScenePresence : EntityBase, ISceneEntity |
72 | { | 72 | { |
73 | // ~ScenePresence() | 73 | // ~ScenePresence() |
74 | // { | 74 | // { |
@@ -491,6 +491,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
491 | } | 491 | } |
492 | } | 492 | } |
493 | 493 | ||
494 | public Vector3 OffsetPosition | ||
495 | { | ||
496 | get { return m_pos; } | ||
497 | set { m_pos = value; } | ||
498 | } | ||
499 | |||
494 | /// <summary> | 500 | /// <summary> |
495 | /// Current velocity of the avatar. | 501 | /// Current velocity of the avatar. |
496 | /// </summary> | 502 | /// </summary> |
@@ -1120,8 +1126,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1120 | 1126 | ||
1121 | m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim. | 1127 | m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim. |
1122 | 1128 | ||
1123 | ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, | 1129 | ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position); |
1124 | AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); | 1130 | //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, |
1131 | // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); | ||
1125 | } | 1132 | } |
1126 | 1133 | ||
1127 | public void AddNeighbourRegion(ulong regionHandle, string cap) | 1134 | public void AddNeighbourRegion(ulong regionHandle, string cap) |
@@ -2604,8 +2611,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); | |||
2604 | 2611 | ||
2605 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); | 2612 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); |
2606 | 2613 | ||
2607 | remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, | 2614 | remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); |
2608 | pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient))); | ||
2609 | 2615 | ||
2610 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2616 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2611 | m_scene.StatsReporter.AddAgentUpdates(1); | 2617 | m_scene.StatsReporter.AddAgentUpdates(1); |
@@ -2701,9 +2707,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); | |||
2701 | Vector3 pos = m_pos; | 2707 | Vector3 pos = m_pos; |
2702 | pos.Z += m_appearance.HipOffset; | 2708 | pos.Z += m_appearance.HipOffset; |
2703 | 2709 | ||
2704 | remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, | 2710 | remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); |
2705 | LocalId, pos, m_appearance.Texture.GetBytes(), | ||
2706 | m_parentID, m_bodyRot)); | ||
2707 | m_scene.StatsReporter.AddAgentUpdates(1); | 2711 | m_scene.StatsReporter.AddAgentUpdates(1); |
2708 | } | 2712 | } |
2709 | 2713 | ||
@@ -2771,8 +2775,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); | |||
2771 | Vector3 pos = m_pos; | 2775 | Vector3 pos = m_pos; |
2772 | pos.Z += m_appearance.HipOffset; | 2776 | pos.Z += m_appearance.HipOffset; |
2773 | 2777 | ||
2774 | m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2778 | m_controllingClient.SendAvatarDataImmediate(this); |
2775 | pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); | ||
2776 | 2779 | ||
2777 | SendInitialFullUpdateToAllClients(); | 2780 | SendInitialFullUpdateToAllClients(); |
2778 | SendAppearanceToAllOtherAgents(); | 2781 | SendAppearanceToAllOtherAgents(); |
@@ -2882,9 +2885,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); | |||
2882 | Vector3 pos = m_pos; | 2885 | Vector3 pos = m_pos; |
2883 | pos.Z += m_appearance.HipOffset; | 2886 | pos.Z += m_appearance.HipOffset; |
2884 | 2887 | ||
2885 | m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2888 | m_controllingClient.SendAvatarDataImmediate(this); |
2886 | pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); | ||
2887 | |||
2888 | } | 2889 | } |
2889 | 2890 | ||
2890 | public void SetWearable(int wearableId, AvatarWearable wearable) | 2891 | public void SetWearable(int wearableId, AvatarWearable wearable) |
@@ -4219,7 +4220,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); | |||
4219 | 4220 | ||
4220 | private void Reprioritize(object sender, ElapsedEventArgs e) | 4221 | private void Reprioritize(object sender, ElapsedEventArgs e) |
4221 | { | 4222 | { |
4222 | m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority); | 4223 | m_controllingClient.ReprioritizeUpdates(UpdatePriority); |
4223 | 4224 | ||
4224 | lock (m_reprioritization_timer) | 4225 | lock (m_reprioritization_timer) |
4225 | { | 4226 | { |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index cab640b..fb8543b 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -1054,16 +1054,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1054 | 1054 | ||
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | public void SendAvatarData(SendAvatarData data) | ||
1058 | { | ||
1059 | |||
1060 | } | ||
1061 | |||
1062 | public void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||
1063 | { | ||
1064 | |||
1065 | } | ||
1066 | |||
1067 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | 1057 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) |
1068 | { | 1058 | { |
1069 | 1059 | ||
@@ -1074,32 +1064,27 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1074 | 1064 | ||
1075 | } | 1065 | } |
1076 | 1066 | ||
1077 | public void SetChildAgentThrottle(byte[] throttle) | 1067 | public void SendAvatarDataImmediate(ISceneEntity avatar) |
1078 | { | 1068 | { |
1079 | |||
1080 | } | ||
1081 | 1069 | ||
1082 | public void SendPrimitiveToClient(SendPrimitiveData data) | ||
1083 | { | ||
1084 | |||
1085 | } | 1070 | } |
1086 | 1071 | ||
1087 | public void SendPrimTerseUpdate(SendPrimitiveTerseData data) | 1072 | public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) |
1088 | { | 1073 | { |
1089 | 1074 | ||
1090 | } | 1075 | } |
1091 | 1076 | ||
1092 | public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | 1077 | public void ReprioritizeUpdates(UpdatePriorityHandler handler) |
1093 | { | 1078 | { |
1094 | 1079 | ||
1095 | } | 1080 | } |
1096 | 1081 | ||
1097 | public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems) | 1082 | public void FlushPrimUpdates() |
1098 | { | 1083 | { |
1099 | 1084 | ||
1100 | } | 1085 | } |
1101 | 1086 | ||
1102 | public void FlushPrimUpdates() | 1087 | public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems) |
1103 | { | 1088 | { |
1104 | 1089 | ||
1105 | } | 1090 | } |
@@ -1429,6 +1414,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1429 | 1414 | ||
1430 | } | 1415 | } |
1431 | 1416 | ||
1417 | public virtual void SetChildAgentThrottle(byte[] throttle) | ||
1418 | { | ||
1419 | |||
1420 | } | ||
1421 | |||
1432 | public byte[] GetThrottlesPacked(float multiplier) | 1422 | public byte[] GetThrottlesPacked(float multiplier) |
1433 | { | 1423 | { |
1434 | return new byte[0]; | 1424 | return new byte[0]; |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index b828357..3cbc538 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 | ||
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs index 9da818a..33ff707 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs | |||
@@ -140,6 +140,16 @@ public class RegionCombinerLargeLandChannel : ILandChannel | |||
140 | RootRegionLandChannel.UpdateLandObject(localID, data); | 140 | RootRegionLandChannel.UpdateLandObject(localID, data); |
141 | } | 141 | } |
142 | 142 | ||
143 | public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) | ||
144 | { | ||
145 | RootRegionLandChannel.Join(start_x, start_y, end_x, end_y, attempting_user_id); | ||
146 | } | ||
147 | |||
148 | public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) | ||
149 | { | ||
150 | RootRegionLandChannel.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id); | ||
151 | } | ||
152 | |||
143 | public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) | 153 | public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) |
144 | { | 154 | { |
145 | RootRegionLandChannel.ReturnObjectsInParcel(localID, returnType, agentIDs, taskIDs, remoteClient); | 155 | RootRegionLandChannel.ReturnObjectsInParcel(localID, returnType, agentIDs, taskIDs, remoteClient); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 9474bab..942e4ef 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -1127,7 +1127,89 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1127 | return 0.0f; | 1127 | return 0.0f; |
1128 | } | 1128 | } |
1129 | 1129 | ||
1130 | // Routines for creating and managing parcels programmatically | ||
1131 | public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2) | ||
1132 | { | ||
1133 | CheckThreatLevel(ThreatLevel.High, "osParcelJoin"); | ||
1134 | m_host.AddScriptLPS(1); | ||
1135 | |||
1136 | int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); | ||
1137 | int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); | ||
1138 | int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x); | ||
1139 | int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y); | ||
1140 | |||
1141 | World.LandChannel.Join(startx,starty,endx,endy,m_host.OwnerID); | ||
1142 | } | ||
1143 | |||
1144 | public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2) | ||
1145 | { | ||
1146 | CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide"); | ||
1147 | m_host.AddScriptLPS(1); | ||
1148 | |||
1149 | int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); | ||
1150 | int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); | ||
1151 | int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x); | ||
1152 | int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y); | ||
1130 | 1153 | ||
1154 | World.LandChannel.Subdivide(startx,starty,endx,endy,m_host.OwnerID); | ||
1155 | } | ||
1156 | |||
1157 | public void osParcelSetDetails(LSL_Vector pos, LSL_List rules) | ||
1158 | { | ||
1159 | CheckThreatLevel(ThreatLevel.High, "osParcelSetDetails"); | ||
1160 | m_host.AddScriptLPS(1); | ||
1161 | |||
1162 | // Get a reference to the land data and make sure the owner of the script | ||
1163 | // can modify it | ||
1164 | |||
1165 | ILandObject startLandObject = World.LandChannel.GetLandObject((int)pos.x, (int)pos.y); | ||
1166 | if (startLandObject == null) | ||
1167 | { | ||
1168 | OSSLShoutError("There is no land at that location"); | ||
1169 | return; | ||
1170 | } | ||
1171 | |||
1172 | if (! World.Permissions.CanEditParcel(m_host.OwnerID, startLandObject)) | ||
1173 | { | ||
1174 | OSSLShoutError("You do not have permission to modify the parcel"); | ||
1175 | return; | ||
1176 | } | ||
1177 | |||
1178 | // Create a new land data object we can modify | ||
1179 | LandData newLand = startLandObject.LandData.Copy(); | ||
1180 | UUID uuid; | ||
1181 | |||
1182 | // Process the rules, not sure what the impact would be of changing owner or group | ||
1183 | for (int idx = 0; idx < rules.Length; ) | ||
1184 | { | ||
1185 | int code = rules.GetLSLIntegerItem(idx++); | ||
1186 | string arg = rules.GetLSLStringItem(idx++); | ||
1187 | switch (code) | ||
1188 | { | ||
1189 | case 0: | ||
1190 | newLand.Name = arg; | ||
1191 | break; | ||
1192 | |||
1193 | case 1: | ||
1194 | newLand.Description = arg; | ||
1195 | break; | ||
1196 | |||
1197 | case 2: | ||
1198 | CheckThreatLevel(ThreatLevel.VeryHigh, "osParcelSetDetails"); | ||
1199 | if (UUID.TryParse(arg , out uuid)) | ||
1200 | newLand.OwnerID = uuid; | ||
1201 | break; | ||
1202 | |||
1203 | case 3: | ||
1204 | CheckThreatLevel(ThreatLevel.VeryHigh, "osParcelSetDetails"); | ||
1205 | if (UUID.TryParse(arg , out uuid)) | ||
1206 | newLand.GroupID = uuid; | ||
1207 | break; | ||
1208 | } | ||
1209 | } | ||
1210 | |||
1211 | World.LandChannel.UpdateLandObject(newLand.LocalID,newLand); | ||
1212 | } | ||
1131 | 1213 | ||
1132 | public double osList2Double(LSL_Types.list src, int index) | 1214 | public double osList2Double(LSL_Types.list src, int index) |
1133 | { | 1215 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index f5921e1..9dbd369 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | |||
@@ -123,6 +123,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
123 | void osWindParamSet(string plugin, string param, float value); | 123 | void osWindParamSet(string plugin, string param, float value); |
124 | float osWindParamGet(string plugin, string param); | 124 | float osWindParamGet(string plugin, string param); |
125 | 125 | ||
126 | // Parcel commands | ||
127 | void osParcelJoin(vector pos1, vector pos2); | ||
128 | void osParcelSubdivide(vector pos1, vector pos2); | ||
129 | void osParcelSetDetails(vector pos, LSL_List rules); | ||
126 | 130 | ||
127 | string osGetScriptEngineName(); | 131 | string osGetScriptEngineName(); |
128 | string osGetSimulatorVersion(); | 132 | string osGetSimulatorVersion(); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 3870af3..fd9309a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | |||
@@ -106,6 +106,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
106 | // return m_OSSL_Functions.osWindParamGet(plugin, param); | 106 | // return m_OSSL_Functions.osWindParamGet(plugin, param); |
107 | // } | 107 | // } |
108 | 108 | ||
109 | public void osParcelJoin(vector pos1, vector pos2) | ||
110 | { | ||
111 | m_OSSL_Functions.osParcelJoin(pos1,pos2); | ||
112 | } | ||
113 | |||
114 | public void osParcelSubdivide(vector pos1, vector pos2) | ||
115 | { | ||
116 | m_OSSL_Functions.osParcelSubdivide(pos1, pos2); | ||
117 | } | ||
118 | |||
119 | public void osParcelSetDetails(vector pos, LSL_List rules) | ||
120 | { | ||
121 | m_OSSL_Functions.osParcelSetDetails(pos,rules); | ||
122 | } | ||
123 | |||
109 | public double osList2Double(LSL_Types.list src, int index) | 124 | public double osList2Double(LSL_Types.list src, int index) |
110 | { | 125 | { |
111 | return m_OSSL_Functions.osList2Double(src, index); | 126 | return m_OSSL_Functions.osList2Double(src, index); |