diff options
Diffstat (limited to 'OpenSim/Region')
15 files changed, 552 insertions, 473 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 1f3582c..11dca8d 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 |
@@ -463,9 +435,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
463 | 435 | ||
464 | m_scene = scene; | 436 | m_scene = scene; |
465 | 437 | ||
466 | m_avatarTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | 438 | m_entityUpdates = new PriorityQueue<double, EntityUpdate>(m_scene.Entities.Count); |
467 | m_primTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
468 | m_primFullUpdates = new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(m_scene.Entities.Count); | ||
469 | m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); | 439 | m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); |
470 | m_killRecord = new HashSet<uint>(); | 440 | m_killRecord = new HashSet<uint>(); |
471 | 441 | ||
@@ -1519,7 +1489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1519 | kill.Header.Reliable = true; | 1489 | kill.Header.Reliable = true; |
1520 | kill.Header.Zerocoded = true; | 1490 | kill.Header.Zerocoded = true; |
1521 | 1491 | ||
1522 | lock (m_primFullUpdates.SyncRoot) | 1492 | lock (m_entityUpdates.SyncRoot) |
1523 | { | 1493 | { |
1524 | m_killRecord.Add(localID); | 1494 | m_killRecord.Add(localID); |
1525 | OutPacket(kill, ThrottleOutPacketType.State); | 1495 | OutPacket(kill, ThrottleOutPacketType.State); |
@@ -3419,71 +3389,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3419 | /// <summary> | 3389 | /// <summary> |
3420 | /// Send an ObjectUpdate packet with information about an avatar | 3390 | /// Send an ObjectUpdate packet with information about an avatar |
3421 | /// </summary> | 3391 | /// </summary> |
3422 | public void SendAvatarData(SendAvatarData data) | 3392 | public void SendAvatarDataImmediate(ISceneEntity avatar) |
3423 | { | 3393 | { |
3394 | ScenePresence presence = avatar as ScenePresence; | ||
3395 | if (presence == null) | ||
3396 | return; | ||
3397 | |||
3424 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 3398 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
3425 | objupdate.Header.Zerocoded = true; | 3399 | objupdate.Header.Zerocoded = true; |
3426 | 3400 | ||
3427 | objupdate.RegionData.RegionHandle = data.RegionHandle; | 3401 | objupdate.RegionData.RegionHandle = presence.RegionHandle; |
3428 | objupdate.RegionData.TimeDilation = ushort.MaxValue; | 3402 | objupdate.RegionData.TimeDilation = ushort.MaxValue; |
3429 | 3403 | ||
3430 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | 3404 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; |
3431 | objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); | 3405 | objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); |
3432 | 3406 | ||
3433 | OutPacket(objupdate, ThrottleOutPacketType.Task); | 3407 | OutPacket(objupdate, ThrottleOutPacketType.Task); |
3434 | } | 3408 | } |
3435 | 3409 | ||
3436 | /// <summary> | ||
3437 | /// Send a terse positional/rotation/velocity update about an avatar | ||
3438 | /// to the client. This avatar can be that of the client itself. | ||
3439 | /// </summary> | ||
3440 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||
3441 | { | ||
3442 | if (data.Priority == double.NaN) | ||
3443 | { | ||
3444 | m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update"); | ||
3445 | return; | ||
3446 | } | ||
3447 | |||
3448 | Quaternion rotation = data.Rotation; | ||
3449 | if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) | ||
3450 | rotation = Quaternion.Identity; | ||
3451 | |||
3452 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data); | ||
3453 | |||
3454 | lock (m_avatarTerseUpdates.SyncRoot) | ||
3455 | m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID); | ||
3456 | |||
3457 | // If we received an update about our own avatar, process the avatar update priority queue immediately | ||
3458 | if (data.AgentID == m_agentId) | ||
3459 | ProcessAvatarTerseUpdates(); | ||
3460 | } | ||
3461 | |||
3462 | protected void ProcessAvatarTerseUpdates() | ||
3463 | { | ||
3464 | ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | ||
3465 | terse.Header.Reliable = false; | ||
3466 | terse.Header.Zerocoded = true; | ||
3467 | |||
3468 | //terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock(); | ||
3469 | terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; | ||
3470 | terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); | ||
3471 | |||
3472 | lock (m_avatarTerseUpdates.SyncRoot) | ||
3473 | { | ||
3474 | int count = Math.Min(m_avatarTerseUpdates.Count, m_udpServer.AvatarTerseUpdatesPerPacket); | ||
3475 | if (count == 0) | ||
3476 | return; | ||
3477 | |||
3478 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; | ||
3479 | for (int i = 0; i < count; i++) | ||
3480 | terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); | ||
3481 | } | ||
3482 | |||
3483 | // HACK: Using the task category until the tiered reprioritization code is in | ||
3484 | OutPacket(terse, ThrottleOutPacketType.Task); | ||
3485 | } | ||
3486 | |||
3487 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | 3410 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) |
3488 | { | 3411 | { |
3489 | if (!IsActive) return; // We don't need to update inactive clients. | 3412 | if (!IsActive) return; // We don't need to update inactive clients. |
@@ -3528,172 +3451,187 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3528 | 3451 | ||
3529 | #region Primitive Packet/Data Sending Methods | 3452 | #region Primitive Packet/Data Sending Methods |
3530 | 3453 | ||
3531 | public void SendPrimitiveToClient(SendPrimitiveData data) | 3454 | /// <summary> |
3455 | /// Generate one of the object update packets based on PrimUpdateFlags | ||
3456 | /// and broadcast the packet to clients | ||
3457 | /// </summary> | ||
3458 | public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) | ||
3532 | { | 3459 | { |
3533 | // string text = data.text; | 3460 | double priority; |
3534 | // if (text.IndexOf("\n") >= 0) | ||
3535 | // text = text.Remove(text.IndexOf("\n")); | ||
3536 | // m_log.DebugFormat( | ||
3537 | // "[CLIENT]: Placing request to send full info about prim {0} text {1} to client {2}", | ||
3538 | // data.localID, text, Name); | ||
3539 | |||
3540 | if (data.priority == double.NaN) | ||
3541 | { | ||
3542 | m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update"); | ||
3543 | return; | ||
3544 | } | ||
3545 | |||
3546 | Quaternion rotation = data.rotation; | ||
3547 | if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) | ||
3548 | rotation = Quaternion.Identity; | ||
3549 | |||
3550 | if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD | ||
3551 | return; | ||
3552 | if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9) | ||
3553 | return; | ||
3554 | 3461 | ||
3555 | ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data); | 3462 | if (entity is SceneObjectPart) |
3463 | priority = ((SceneObjectPart)entity).ParentGroup.GetUpdatePriority(this); | ||
3464 | else if (entity is ScenePresence) | ||
3465 | priority = ((ScenePresence)entity).GetUpdatePriority(this); | ||
3466 | else | ||
3467 | priority = 0.0d; | ||
3556 | 3468 | ||
3557 | lock (m_primFullUpdates.SyncRoot) | 3469 | lock (m_entityUpdates.SyncRoot) |
3558 | m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); | 3470 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId); |
3559 | } | 3471 | } |
3560 | 3472 | ||
3561 | void ProcessPrimFullUpdates() | 3473 | private void ProcessEntityUpdates(int maxUpdates) |
3562 | { | 3474 | { |
3563 | ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 3475 | Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); |
3564 | outPacket.Header.Zerocoded = true; | 3476 | Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>(); |
3477 | Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | ||
3565 | 3478 | ||
3566 | outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; | 3479 | if (maxUpdates <= 0) maxUpdates = Int32.MaxValue; |
3567 | outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); | 3480 | int updatesThisCall = 0; |
3568 | 3481 | ||
3569 | lock (m_primFullUpdates.SyncRoot) | 3482 | lock (m_entityUpdates.SyncRoot) |
3570 | { | 3483 | { |
3571 | int count = Math.Min(m_primFullUpdates.Count, m_udpServer.PrimFullUpdatesPerPacket); | 3484 | EntityUpdate update; |
3572 | if (count == 0) | 3485 | while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update)) |
3573 | return; | ||
3574 | |||
3575 | m_fullUpdateDataBlocksBuilder.Clear(); | ||
3576 | |||
3577 | for (int i = 0; i < count; i++) | ||
3578 | { | 3486 | { |
3579 | ObjectUpdatePacket.ObjectDataBlock block = m_primFullUpdates.Dequeue(); | 3487 | ++updatesThisCall; |
3488 | |||
3489 | #region UpdateFlags to packet type conversion | ||
3580 | 3490 | ||
3581 | 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)) | ||
3582 | { | 3501 | { |
3583 | m_fullUpdateDataBlocksBuilder.Add(block); | 3502 | canUseCompressed = false; |
3584 | 3503 | canUseImproved = false; | |
3585 | // string text = Util.FieldToString(outPacket.ObjectData[i].Text); | ||
3586 | // if (text.IndexOf("\n") >= 0) | ||
3587 | // text = text.Remove(text.IndexOf("\n")); | ||
3588 | // m_log.DebugFormat( | ||
3589 | // "[CLIENT]: Sending full info about prim {0} text {1} to client {2}", | ||
3590 | // outPacket.ObjectData[i].ID, text, Name); | ||
3591 | } | 3504 | } |
3592 | // else | 3505 | else |
3593 | // { | 3506 | { |
3594 | // m_log.WarnFormat( | 3507 | if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || |
3595 | // "[CLIENT]: Preventing full update for {0} after kill to {1}", block.ID, Name); | 3508 | updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || |
3596 | // } | 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)); | ||
3551 | } | ||
3552 | else | ||
3553 | { | ||
3554 | terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); | ||
3555 | } | ||
3556 | |||
3557 | #endregion Block Construction | ||
3597 | } | 3558 | } |
3559 | } | ||
3598 | 3560 | ||
3599 | outPacket.ObjectData = m_fullUpdateDataBlocksBuilder.ToArray(); | 3561 | #region Packet Sending |
3600 | |||
3601 | OutPacket(outPacket, ThrottleOutPacketType.State); | ||
3602 | } | ||
3603 | } | ||
3604 | 3562 | ||
3605 | public void SendPrimTerseUpdate(SendPrimitiveTerseData data) | 3563 | const float TIME_DILATION = 1.0f; |
3606 | { | 3564 | ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); |
3607 | if (data.Priority == double.NaN) | 3565 | |
3566 | if (objectUpdateBlocks.IsValueCreated) | ||
3608 | { | 3567 | { |
3609 | m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); | 3568 | List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; |
3610 | return; | ||
3611 | } | ||
3612 | 3569 | ||
3613 | Quaternion rotation = data.Rotation; | 3570 | ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
3614 | if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) | 3571 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; |
3615 | rotation = Quaternion.Identity; | 3572 | packet.RegionData.TimeDilation = timeDilation; |
3573 | packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; | ||
3616 | 3574 | ||
3617 | if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD | 3575 | for (int i = 0; i < blocks.Count; i++) |
3618 | return; | 3576 | packet.ObjectData[i] = blocks[i]; |
3577 | |||
3578 | OutPacket(packet, ThrottleOutPacketType.Task, true); | ||
3579 | } | ||
3619 | 3580 | ||
3620 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data); | 3581 | if (compressedUpdateBlocks.IsValueCreated) |
3582 | { | ||
3583 | List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; | ||
3621 | 3584 | ||
3622 | lock (m_primTerseUpdates.SyncRoot) | 3585 | ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); |
3623 | m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID); | 3586 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; |
3624 | } | 3587 | packet.RegionData.TimeDilation = timeDilation; |
3588 | packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; | ||
3625 | 3589 | ||
3626 | void ProcessPrimTerseUpdates() | 3590 | for (int i = 0; i < blocks.Count; i++) |
3627 | { | 3591 | packet.ObjectData[i] = blocks[i]; |
3628 | ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | ||
3629 | outPacket.Header.Reliable = false; | ||
3630 | outPacket.Header.Zerocoded = true; | ||
3631 | 3592 | ||
3632 | outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; | 3593 | OutPacket(packet, ThrottleOutPacketType.Task, true); |
3633 | outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); | 3594 | } |
3634 | 3595 | ||
3635 | lock (m_primTerseUpdates.SyncRoot) | 3596 | if (terseUpdateBlocks.IsValueCreated) |
3636 | { | 3597 | { |
3637 | int count = Math.Min(m_primTerseUpdates.Count, m_udpServer.PrimTerseUpdatesPerPacket); | 3598 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; |
3638 | if (count == 0) | 3599 | |
3639 | return; | 3600 | ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); |
3601 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
3602 | packet.RegionData.TimeDilation = timeDilation; | ||
3603 | packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; | ||
3640 | 3604 | ||
3641 | outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; | 3605 | for (int i = 0; i < blocks.Count; i++) |
3642 | for (int i = 0; i < count; i++) | 3606 | packet.ObjectData[i] = blocks[i]; |
3643 | outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue(); | 3607 | |
3608 | OutPacket(packet, ThrottleOutPacketType.Task, true); | ||
3644 | } | 3609 | } |
3645 | 3610 | ||
3646 | OutPacket(outPacket, ThrottleOutPacketType.State); | 3611 | #endregion Packet Sending |
3647 | } | 3612 | } |
3648 | 3613 | ||
3649 | public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | 3614 | public void ReprioritizeUpdates(UpdatePriorityHandler handler) |
3650 | { | 3615 | { |
3651 | PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler = | 3616 | //m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName); |
3652 | delegate(ref double priority, uint local_id) | 3617 | |
3653 | { | 3618 | PriorityQueue<double, EntityUpdate>.UpdatePriorityHandler update_priority_handler = |
3654 | priority = handler(new UpdatePriorityData(priority, local_id)); | ||
3655 | return priority != double.NaN; | ||
3656 | }; | ||
3657 | PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler = | ||
3658 | delegate(ref double priority, uint local_id) | 3619 | delegate(ref double priority, uint local_id) |
3659 | { | 3620 | { |
3660 | priority = handler(new UpdatePriorityData(priority, local_id)); | 3621 | priority = handler(new UpdatePriorityData(priority, local_id)); |
3661 | return priority != double.NaN; | 3622 | return priority != double.NaN; |
3662 | }; | 3623 | }; |
3663 | 3624 | ||
3664 | if ((type & StateUpdateTypes.AvatarTerse) != 0) | 3625 | lock (m_entityUpdates.SyncRoot) |
3665 | { | 3626 | m_entityUpdates.Reprioritize(update_priority_handler); |
3666 | lock (m_avatarTerseUpdates.SyncRoot) | ||
3667 | m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler); | ||
3668 | } | ||
3669 | |||
3670 | if ((type & StateUpdateTypes.PrimitiveFull) != 0) | ||
3671 | { | ||
3672 | lock (m_primFullUpdates.SyncRoot) | ||
3673 | m_primFullUpdates.Reprioritize(update_priority_handler); | ||
3674 | } | ||
3675 | |||
3676 | if ((type & StateUpdateTypes.PrimitiveTerse) != 0) | ||
3677 | { | ||
3678 | lock (m_primTerseUpdates.SyncRoot) | ||
3679 | m_primTerseUpdates.Reprioritize(terse_update_priority_handler); | ||
3680 | } | ||
3681 | } | 3627 | } |
3682 | 3628 | ||
3683 | public void FlushPrimUpdates() | 3629 | public void FlushPrimUpdates() |
3684 | { | 3630 | { |
3685 | while (m_primFullUpdates.Count > 0) | 3631 | m_log.Debug("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName); |
3686 | { | 3632 | |
3687 | ProcessPrimFullUpdates(); | 3633 | while (m_entityUpdates.Count > 0) |
3688 | } | 3634 | ProcessEntityUpdates(-1); |
3689 | while (m_primTerseUpdates.Count > 0) | ||
3690 | { | ||
3691 | ProcessPrimTerseUpdates(); | ||
3692 | } | ||
3693 | while (m_avatarTerseUpdates.Count > 0) | ||
3694 | { | ||
3695 | ProcessAvatarTerseUpdates(); | ||
3696 | } | ||
3697 | } | 3635 | } |
3698 | 3636 | ||
3699 | #endregion Primitive Packet/Data Sending Methods | 3637 | #endregion Primitive Packet/Data Sending Methods |
@@ -3726,26 +3664,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3726 | { | 3664 | { |
3727 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) | 3665 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) |
3728 | { | 3666 | { |
3729 | lock (m_avatarTerseUpdates.SyncRoot) | 3667 | if (m_entityUpdates.Count > 0) |
3730 | { | 3668 | ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback); |
3731 | if (m_avatarTerseUpdates.Count > 0) | ||
3732 | ProcessAvatarTerseUpdates(); | ||
3733 | } | ||
3734 | } | ||
3735 | |||
3736 | if ((categories & ThrottleOutPacketTypeFlags.State) != 0) | ||
3737 | { | ||
3738 | lock (m_primFullUpdates.SyncRoot) | ||
3739 | { | ||
3740 | if (m_primFullUpdates.Count > 0) | ||
3741 | ProcessPrimFullUpdates(); | ||
3742 | } | ||
3743 | |||
3744 | lock (m_primTerseUpdates.SyncRoot) | ||
3745 | { | ||
3746 | if (m_primTerseUpdates.Count > 0) | ||
3747 | ProcessPrimTerseUpdates(); | ||
3748 | } | ||
3749 | } | 3669 | } |
3750 | 3670 | ||
3751 | if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) | 3671 | if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) |
@@ -4403,22 +4323,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4403 | 4323 | ||
4404 | #region Helper Methods | 4324 | #region Helper Methods |
4405 | 4325 | ||
4406 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data) | 4326 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture) |
4407 | { | 4327 | { |
4408 | return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity, | 4328 | #region ScenePresence/SOP Handling |
4409 | data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry); | ||
4410 | } | ||
4411 | 4329 | ||
4412 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data) | 4330 | bool avatar = (entity is ScenePresence); |
4413 | { | 4331 | uint localID = entity.LocalId; |
4414 | return CreateImprovedTerseBlock(false, data.LocalID, data.AttachPoint, Vector4.Zero, data.Position, data.Velocity, | 4332 | uint attachPoint; |
4415 | data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry); | 4333 | Vector4 collisionPlane; |
4416 | } | 4334 | Vector3 position, velocity, acceleration, angularVelocity; |
4335 | Quaternion rotation; | ||
4336 | byte[] textureEntry; | ||
4337 | |||
4338 | if (entity is ScenePresence) | ||
4339 | { | ||
4340 | ScenePresence presence = (ScenePresence)entity; | ||
4341 | |||
4342 | attachPoint = 0; | ||
4343 | collisionPlane = presence.CollisionPlane; | ||
4344 | position = presence.OffsetPosition; | ||
4345 | velocity = presence.Velocity; | ||
4346 | acceleration = Vector3.Zero; | ||
4347 | angularVelocity = Vector3.Zero; | ||
4348 | rotation = presence.Rotation; | ||
4349 | |||
4350 | if (sendTexture) | ||
4351 | textureEntry = presence.Appearance.Texture.GetBytes(); | ||
4352 | else | ||
4353 | textureEntry = null; | ||
4354 | } | ||
4355 | else | ||
4356 | { | ||
4357 | SceneObjectPart part = (SceneObjectPart)entity; | ||
4358 | |||
4359 | attachPoint = part.AttachmentPoint; | ||
4360 | collisionPlane = Vector4.Zero; | ||
4361 | position = part.RelativePosition; | ||
4362 | velocity = part.Velocity; | ||
4363 | acceleration = part.Acceleration; | ||
4364 | angularVelocity = part.AngularVelocity; | ||
4365 | rotation = part.RotationOffset; | ||
4366 | textureEntry = part.Shape.TextureEntry; | ||
4367 | } | ||
4368 | |||
4369 | #endregion ScenePresence/SOP Handling | ||
4417 | 4370 | ||
4418 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, int attachPoint, | ||
4419 | Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation, | ||
4420 | Vector3 angularVelocity, byte[] textureEntry) | ||
4421 | { | ||
4422 | int pos = 0; | 4371 | int pos = 0; |
4423 | byte[] data = new byte[(avatar ? 60 : 44)]; | 4372 | byte[] data = new byte[(avatar ? 60 : 44)]; |
4424 | 4373 | ||
@@ -4490,12 +4439,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4490 | return block; | 4439 | return block; |
4491 | } | 4440 | } |
4492 | 4441 | ||
4493 | protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data) | 4442 | protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) |
4494 | { | 4443 | { |
4495 | byte[] objectData = new byte[76]; | 4444 | byte[] objectData = new byte[76]; |
4496 | 4445 | ||
4497 | Vector4.UnitW.ToBytes(objectData, 0); // TODO: Collision plane support | 4446 | data.CollisionPlane.ToBytes(objectData, 0); |
4498 | data.Position.ToBytes(objectData, 16); | 4447 | data.OffsetPosition.ToBytes(objectData, 16); |
4499 | //data.Velocity.ToBytes(objectData, 28); | 4448 | //data.Velocity.ToBytes(objectData, 28); |
4500 | //data.Acceleration.ToBytes(objectData, 40); | 4449 | //data.Acceleration.ToBytes(objectData, 40); |
4501 | data.Rotation.ToBytes(objectData, 52); | 4450 | data.Rotation.ToBytes(objectData, 52); |
@@ -4505,12 +4454,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4505 | 4454 | ||
4506 | update.Data = Utils.EmptyBytes; | 4455 | update.Data = Utils.EmptyBytes; |
4507 | update.ExtraParams = new byte[1]; | 4456 | update.ExtraParams = new byte[1]; |
4508 | update.FullID = data.AvatarID; | 4457 | update.FullID = data.UUID; |
4509 | update.ID = data.AvatarLocalID; | 4458 | update.ID = data.LocalId; |
4510 | update.Material = (byte)Material.Flesh; | 4459 | update.Material = (byte)Material.Flesh; |
4511 | update.MediaURL = Utils.EmptyBytes; | 4460 | update.MediaURL = Utils.EmptyBytes; |
4512 | update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " + | 4461 | update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + |
4513 | data.LastName + "\nTitle STRING RW SV " + data.GroupTitle); | 4462 | data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); |
4514 | update.ObjectData = objectData; | 4463 | update.ObjectData = objectData; |
4515 | update.ParentID = data.ParentID; | 4464 | update.ParentID = data.ParentID; |
4516 | update.PathCurve = 16; | 4465 | update.PathCurve = 16; |
@@ -4519,102 +4468,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4519 | update.PCode = (byte)PCode.Avatar; | 4468 | update.PCode = (byte)PCode.Avatar; |
4520 | update.ProfileCurve = 1; | 4469 | update.ProfileCurve = 1; |
4521 | update.PSBlock = Utils.EmptyBytes; | 4470 | update.PSBlock = Utils.EmptyBytes; |
4522 | update.Scale = new Vector3(0.45f,0.6f,1.9f); | 4471 | update.Scale = new Vector3(0.45f, 0.6f, 1.9f); |
4523 | update.Text = Utils.EmptyBytes; | 4472 | update.Text = Utils.EmptyBytes; |
4524 | update.TextColor = new byte[4]; | 4473 | update.TextColor = new byte[4]; |
4525 | update.TextureAnim = Utils.EmptyBytes; | 4474 | update.TextureAnim = Utils.EmptyBytes; |
4526 | update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes; | 4475 | update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; |
4527 | update.UpdateFlags = (uint)(PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | PrimFlags.ObjectOwnerModify);//61 + (9 << 8) + (130 << 16) + (16 << 24); // TODO: Replace these numbers with PrimFlags | 4476 | update.UpdateFlags = (uint)( |
4477 | PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | | ||
4478 | PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | | ||
4479 | PrimFlags.ObjectOwnerModify); | ||
4528 | 4480 | ||
4529 | return update; | 4481 | return update; |
4530 | } | 4482 | } |
4531 | 4483 | ||
4532 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data) | 4484 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) |
4533 | { | 4485 | { |
4534 | byte[] objectData = new byte[60]; | 4486 | byte[] objectData = new byte[60]; |
4535 | data.pos.ToBytes(objectData, 0); | 4487 | data.RelativePosition.ToBytes(objectData, 0); |
4536 | data.vel.ToBytes(objectData, 12); | 4488 | data.Velocity.ToBytes(objectData, 12); |
4537 | data.acc.ToBytes(objectData, 24); | 4489 | data.Acceleration.ToBytes(objectData, 24); |
4538 | data.rotation.ToBytes(objectData, 36); | 4490 | data.RotationOffset.ToBytes(objectData, 36); |
4539 | data.rvel.ToBytes(objectData, 48); | 4491 | data.AngularVelocity.ToBytes(objectData, 48); |
4540 | 4492 | ||
4541 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | 4493 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); |
4542 | update.ClickAction = (byte)data.clickAction; | 4494 | update.ClickAction = (byte)data.ClickAction; |
4543 | update.CRC = 0; | 4495 | update.CRC = 0; |
4544 | update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes; | 4496 | update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes; |
4545 | update.FullID = data.objectID; | 4497 | update.FullID = data.UUID; |
4546 | update.ID = data.localID; | 4498 | update.ID = data.LocalId; |
4547 | //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated | 4499 | //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated |
4548 | //update.JointPivot = Vector3.Zero; | 4500 | //update.JointPivot = Vector3.Zero; |
4549 | //update.JointType = 0; | 4501 | //update.JointType = 0; |
4550 | update.Material = data.material; | 4502 | update.Material = data.Material; |
4551 | update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim | 4503 | update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim |
4552 | if (data.attachment) | 4504 | if (data.IsAttachment) |
4553 | { | 4505 | { |
4554 | update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId); | 4506 | update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID); |
4555 | update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); | 4507 | update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16)); |
4556 | } | 4508 | } |
4557 | else | 4509 | else |
4558 | { | 4510 | { |
4559 | update.NameValue = Utils.EmptyBytes; | 4511 | update.NameValue = Utils.EmptyBytes; |
4560 | update.State = data.primShape.State; | 4512 | update.State = data.Shape.State; |
4561 | } | 4513 | } |
4514 | |||
4562 | update.ObjectData = objectData; | 4515 | update.ObjectData = objectData; |
4563 | update.ParentID = data.parentID; | 4516 | update.ParentID = data.ParentID; |
4564 | update.PathBegin = data.primShape.PathBegin; | 4517 | update.PathBegin = data.Shape.PathBegin; |
4565 | update.PathCurve = data.primShape.PathCurve; | 4518 | update.PathCurve = data.Shape.PathCurve; |
4566 | update.PathEnd = data.primShape.PathEnd; | 4519 | update.PathEnd = data.Shape.PathEnd; |
4567 | update.PathRadiusOffset = data.primShape.PathRadiusOffset; | 4520 | update.PathRadiusOffset = data.Shape.PathRadiusOffset; |
4568 | update.PathRevolutions = data.primShape.PathRevolutions; | 4521 | update.PathRevolutions = data.Shape.PathRevolutions; |
4569 | update.PathScaleX = data.primShape.PathScaleX; | 4522 | update.PathScaleX = data.Shape.PathScaleX; |
4570 | update.PathScaleY = data.primShape.PathScaleY; | 4523 | update.PathScaleY = data.Shape.PathScaleY; |
4571 | update.PathShearX = data.primShape.PathShearX; | 4524 | update.PathShearX = data.Shape.PathShearX; |
4572 | update.PathShearY = data.primShape.PathShearY; | 4525 | update.PathShearY = data.Shape.PathShearY; |
4573 | update.PathSkew = data.primShape.PathSkew; | 4526 | update.PathSkew = data.Shape.PathSkew; |
4574 | update.PathTaperX = data.primShape.PathTaperX; | 4527 | update.PathTaperX = data.Shape.PathTaperX; |
4575 | update.PathTaperY = data.primShape.PathTaperY; | 4528 | update.PathTaperY = data.Shape.PathTaperY; |
4576 | update.PathTwist = data.primShape.PathTwist; | 4529 | update.PathTwist = data.Shape.PathTwist; |
4577 | update.PathTwistBegin = data.primShape.PathTwistBegin; | 4530 | update.PathTwistBegin = data.Shape.PathTwistBegin; |
4578 | update.PCode = data.primShape.PCode; | 4531 | update.PCode = data.Shape.PCode; |
4579 | update.ProfileBegin = data.primShape.ProfileBegin; | 4532 | update.ProfileBegin = data.Shape.ProfileBegin; |
4580 | update.ProfileCurve = data.primShape.ProfileCurve; | 4533 | update.ProfileCurve = data.Shape.ProfileCurve; |
4581 | update.ProfileEnd = data.primShape.ProfileEnd; | 4534 | update.ProfileEnd = data.Shape.ProfileEnd; |
4582 | update.ProfileHollow = data.primShape.ProfileHollow; | 4535 | update.ProfileHollow = data.Shape.ProfileHollow; |
4583 | update.PSBlock = data.particleSystem ?? Utils.EmptyBytes; | 4536 | update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes; |
4584 | update.TextColor = data.color ?? Color4.Black.GetBytes(true); | 4537 | update.TextColor = data.GetTextColor().GetBytes(false); |
4585 | update.TextureAnim = data.textureanim ?? Utils.EmptyBytes; | 4538 | update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes; |
4586 | update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes; | 4539 | update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes; |
4587 | update.Scale = data.primShape.Scale; | 4540 | update.Scale = data.Shape.Scale; |
4588 | update.Text = Util.StringToBytes256(data.text); | 4541 | update.Text = Util.StringToBytes256(data.Text); |
4589 | update.UpdateFlags = (uint)data.flags; | 4542 | |
4590 | 4543 | #region PrimFlags | |
4591 | if (data.SoundId != UUID.Zero) | 4544 | |
4592 | { | 4545 | PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID); |
4593 | update.Sound = data.SoundId; | 4546 | |
4594 | update.OwnerID = data.ownerID; | 4547 | // Don't send the CreateSelected flag to everyone |
4595 | update.Gain = (float)data.SoundVolume; | 4548 | flags &= ~PrimFlags.CreateSelected; |
4549 | |||
4550 | if (recipientID == data.OwnerID) | ||
4551 | { | ||
4552 | if ((data.Flags & PrimFlags.CreateSelected) != 0) | ||
4553 | { | ||
4554 | // Only send this flag once, then unset it | ||
4555 | flags |= PrimFlags.CreateSelected; | ||
4556 | data.Flags &= ~PrimFlags.CreateSelected; | ||
4557 | } | ||
4558 | } | ||
4559 | |||
4560 | update.UpdateFlags = (uint)flags; | ||
4561 | |||
4562 | #endregion PrimFlags | ||
4563 | |||
4564 | if (data.Sound != UUID.Zero) | ||
4565 | { | ||
4566 | update.Sound = data.Sound; | ||
4567 | update.OwnerID = data.OwnerID; | ||
4568 | update.Gain = (float)data.SoundGain; | ||
4596 | update.Radius = (float)data.SoundRadius; | 4569 | update.Radius = (float)data.SoundRadius; |
4597 | update.Flags = data.SoundFlags; | 4570 | update.Flags = data.SoundFlags; |
4598 | } | 4571 | } |
4599 | 4572 | ||
4600 | switch ((PCode)data.primShape.PCode) | 4573 | switch ((PCode)data.Shape.PCode) |
4601 | { | 4574 | { |
4602 | case PCode.Grass: | 4575 | case PCode.Grass: |
4603 | case PCode.Tree: | 4576 | case PCode.Tree: |
4604 | case PCode.NewTree: | 4577 | case PCode.NewTree: |
4605 | update.Data = new byte[] { data.primShape.State }; | 4578 | update.Data = new byte[] { data.Shape.State }; |
4606 | break; | 4579 | break; |
4607 | default: | 4580 | default: |
4608 | // TODO: Support ScratchPad | ||
4609 | //if (prim.ScratchPad != null) | ||
4610 | //{ | ||
4611 | // update.Data = new byte[prim.ScratchPad.Length]; | ||
4612 | // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length); | ||
4613 | //} | ||
4614 | //else | ||
4615 | //{ | ||
4616 | // update.Data = Utils.EmptyBytes; | ||
4617 | //} | ||
4618 | update.Data = Utils.EmptyBytes; | 4581 | update.Data = Utils.EmptyBytes; |
4619 | break; | 4582 | break; |
4620 | } | 4583 | } |
@@ -4622,6 +4585,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4622 | return update; | 4585 | return update; |
4623 | } | 4586 | } |
4624 | 4587 | ||
4588 | protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags) | ||
4589 | { | ||
4590 | // TODO: Implement this | ||
4591 | return null; | ||
4592 | } | ||
4593 | |||
4625 | public void SendNameReply(UUID profileId, string firstname, string lastname) | 4594 | public void SendNameReply(UUID profileId, string firstname, string lastname) |
4626 | { | 4595 | { |
4627 | UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply); | 4596 | UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply); |
@@ -11644,7 +11613,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11644 | throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); | 11613 | throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); |
11645 | } | 11614 | } |
11646 | 11615 | ||
11647 | internal TValue Dequeue() | 11616 | internal bool TryDequeue(out TValue value) |
11648 | { | 11617 | { |
11649 | for (int i = 0; i < m_heaps.Length; ++i) | 11618 | for (int i = 0; i < m_heaps.Length; ++i) |
11650 | { | 11619 | { |
@@ -11652,10 +11621,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11652 | { | 11621 | { |
11653 | MinHeapItem item = m_heaps[i].RemoveMin(); | 11622 | MinHeapItem item = m_heaps[i].RemoveMin(); |
11654 | m_lookupTable.Remove(item.LocalID); | 11623 | m_lookupTable.Remove(item.LocalID); |
11655 | return item.Value; | 11624 | value = item.Value; |
11625 | return true; | ||
11656 | } | 11626 | } |
11657 | } | 11627 | } |
11658 | throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); | 11628 | |
11629 | value = default(TValue); | ||
11630 | return false; | ||
11659 | } | 11631 | } |
11660 | 11632 | ||
11661 | internal void Reprioritize(UpdatePriorityHandler handler) | 11633 | internal void Reprioritize(UpdatePriorityHandler handler) |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 41e41e4..1b81105 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -99,15 +99,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
99 | 99 | ||
100 | /// <summary>The measured resolution of Environment.TickCount</summary> | 100 | /// <summary>The measured resolution of Environment.TickCount</summary> |
101 | public readonly float TickCountResolution; | 101 | public readonly float TickCountResolution; |
102 | /// <summary>Number of terse prim updates to put on the queue each time the | 102 | /// <summary>Number of prim updates to put on the queue each time the |
103 | /// OnQueueEmpty event is triggered for updates</summary> | 103 | /// OnQueueEmpty event is triggered for updates</summary> |
104 | public readonly int PrimTerseUpdatesPerPacket; | 104 | public readonly int PrimUpdatesPerCallback; |
105 | /// <summary>Number of terse avatar updates to put on the queue each time the | ||
106 | /// OnQueueEmpty event is triggered for updates</summary> | ||
107 | public readonly int AvatarTerseUpdatesPerPacket; | ||
108 | /// <summary>Number of full prim updates to put on the queue each time the | ||
109 | /// OnQueueEmpty event is triggered for updates</summary> | ||
110 | public readonly int PrimFullUpdatesPerPacket; | ||
111 | /// <summary>Number of texture packets to put on the queue each time the | 105 | /// <summary>Number of texture packets to put on the queue each time the |
112 | /// OnQueueEmpty event is triggered for textures</summary> | 106 | /// OnQueueEmpty event is triggered for textures</summary> |
113 | public readonly int TextureSendLimit; | 107 | public readonly int TextureSendLimit; |
@@ -191,9 +185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
191 | m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); | 185 | m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); |
192 | sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); | 186 | sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); |
193 | 187 | ||
194 | PrimTerseUpdatesPerPacket = config.GetInt("PrimTerseUpdatesPerPacket", 25); | 188 | PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100); |
195 | AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10); | ||
196 | PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100); | ||
197 | TextureSendLimit = config.GetInt("TextureSendLimit", 20); | 189 | TextureSendLimit = config.GetInt("TextureSendLimit", 20); |
198 | 190 | ||
199 | m_defaultRTO = config.GetInt("DefaultRTO", 0); | 191 | m_defaultRTO = config.GetInt("DefaultRTO", 0); |
@@ -201,9 +193,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
201 | } | 193 | } |
202 | else | 194 | else |
203 | { | 195 | { |
204 | PrimTerseUpdatesPerPacket = 25; | 196 | PrimUpdatesPerCallback = 100; |
205 | AvatarTerseUpdatesPerPacket = 10; | ||
206 | PrimFullUpdatesPerPacket = 100; | ||
207 | TextureSendLimit = 20; | 197 | TextureSendLimit = 20; |
208 | } | 198 | } |
209 | 199 | ||
diff --git a/OpenSim/Region/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 139e6ff..4ccd0f0 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -948,6 +948,16 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
948 | masterLandObject.SendLandUpdateToAvatarsOverMe(); | 948 | masterLandObject.SendLandUpdateToAvatarsOverMe(); |
949 | } | 949 | } |
950 | 950 | ||
951 | public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) | ||
952 | { | ||
953 | join(start_x, start_y, end_x, end_y, attempting_user_id); | ||
954 | } | ||
955 | |||
956 | public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) | ||
957 | { | ||
958 | subdivide(start_x, start_y, end_x, end_y, attempting_user_id); | ||
959 | } | ||
960 | |||
951 | #endregion | 961 | #endregion |
952 | 962 | ||
953 | #region Parcel Updating | 963 | #region Parcel Updating |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 09611af..aac47d1 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | |||
@@ -528,14 +528,6 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
528 | { | 528 | { |
529 | } | 529 | } |
530 | 530 | ||
531 | public virtual void SendAvatarData(SendAvatarData data) | ||
532 | { | ||
533 | } | ||
534 | |||
535 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||
536 | { | ||
537 | } | ||
538 | |||
539 | public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | 531 | public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) |
540 | { | 532 | { |
541 | } | 533 | } |
@@ -548,15 +540,15 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
548 | { | 540 | { |
549 | } | 541 | } |
550 | 542 | ||
551 | public virtual void SendPrimitiveToClient(SendPrimitiveData data) | 543 | public void SendAvatarDataImmediate(ISceneEntity avatar) |
552 | { | 544 | { |
553 | } | 545 | } |
554 | 546 | ||
555 | public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) | 547 | public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) |
556 | { | 548 | { |
557 | } | 549 | } |
558 | 550 | ||
559 | public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | 551 | public void ReprioritizeUpdates(UpdatePriorityHandler handler) |
560 | { | 552 | { |
561 | } | 553 | } |
562 | 554 | ||
diff --git a/OpenSim/Region/Framework/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/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index ce11267..ef13c98 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -68,8 +68,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
68 | 68 | ||
69 | #region Fields | 69 | #region Fields |
70 | 70 | ||
71 | protected Dictionary<UUID, ScenePresence> m_scenePresences = new Dictionary<UUID, ScenePresence>(); | 71 | protected object m_presenceLock = new object(); |
72 | protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0]; | 72 | protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); |
73 | protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); | ||
73 | 74 | ||
74 | // SceneObjects is not currently populated or used. | 75 | // SceneObjects is not currently populated or used. |
75 | //public Dictionary<UUID, SceneObjectGroup> SceneObjects; | 76 | //public Dictionary<UUID, SceneObjectGroup> SceneObjects; |
@@ -132,10 +133,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
132 | 133 | ||
133 | protected internal void Close() | 134 | protected internal void Close() |
134 | { | 135 | { |
135 | lock (m_scenePresences) | 136 | lock (m_presenceLock) |
136 | { | 137 | { |
137 | m_scenePresences.Clear(); | 138 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); |
138 | m_scenePresenceArray = new ScenePresence[0]; | 139 | List<ScenePresence> newlist = new List<ScenePresence>(); |
140 | m_scenePresenceMap = newmap; | ||
141 | m_scenePresenceArray = newlist; | ||
139 | } | 142 | } |
140 | 143 | ||
141 | lock (m_dictionary_lock) | 144 | lock (m_dictionary_lock) |
@@ -518,34 +521,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
518 | 521 | ||
519 | Entities[presence.UUID] = presence; | 522 | Entities[presence.UUID] = presence; |
520 | 523 | ||
521 | lock (m_scenePresences) | 524 | lock (m_presenceLock) |
522 | { | 525 | { |
523 | if (!m_scenePresences.ContainsKey(presence.UUID)) | 526 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
527 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | ||
528 | |||
529 | if (!newmap.ContainsKey(presence.UUID)) | ||
524 | { | 530 | { |
525 | m_scenePresences.Add(presence.UUID, presence); | 531 | newmap.Add(presence.UUID, presence); |
526 | 532 | newlist.Add(presence); | |
527 | // Create a new array of ScenePresence references | ||
528 | int oldLength = m_scenePresenceArray.Length; | ||
529 | ScenePresence[] newArray = new ScenePresence[oldLength + 1]; | ||
530 | Array.Copy(m_scenePresenceArray, newArray, oldLength); | ||
531 | newArray[oldLength] = presence; | ||
532 | m_scenePresenceArray = newArray; | ||
533 | } | 533 | } |
534 | else | 534 | else |
535 | { | 535 | { |
536 | m_scenePresences[presence.UUID] = presence; | 536 | // Remember the old presene reference from the dictionary |
537 | 537 | ScenePresence oldref = newmap[presence.UUID]; | |
538 | // Do a linear search through the array of ScenePresence references | 538 | // Replace the presence reference in the dictionary with the new value |
539 | // and update the modified entry | 539 | newmap[presence.UUID] = presence; |
540 | for (int i = 0; i < m_scenePresenceArray.Length; i++) | 540 | // Find the index in the list where the old ref was stored and update the reference |
541 | { | 541 | newlist[newlist.IndexOf(oldref)] = presence; |
542 | if (m_scenePresenceArray[i].UUID == presence.UUID) | ||
543 | { | ||
544 | m_scenePresenceArray[i] = presence; | ||
545 | break; | ||
546 | } | ||
547 | } | ||
548 | } | 542 | } |
543 | |||
544 | // Swap out the dictionary and list with new references | ||
545 | m_scenePresenceMap = newmap; | ||
546 | m_scenePresenceArray = newlist; | ||
549 | } | 547 | } |
550 | } | 548 | } |
551 | 549 | ||
@@ -561,25 +559,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
561 | agentID); | 559 | agentID); |
562 | } | 560 | } |
563 | 561 | ||
564 | lock (m_scenePresences) | 562 | lock (m_presenceLock) |
565 | { | 563 | { |
566 | if (m_scenePresences.Remove(agentID)) | 564 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); |
565 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | ||
566 | |||
567 | // Remember the old presene reference from the dictionary | ||
568 | ScenePresence oldref = newmap[agentID]; | ||
569 | // Remove the presence reference from the dictionary | ||
570 | if (newmap.Remove(agentID)) | ||
567 | { | 571 | { |
568 | // Copy all of the elements from the previous array | 572 | // Find the index in the list where the old ref was stored and remove the reference |
569 | // into the new array except the removed element | 573 | newlist.RemoveAt(newlist.IndexOf(oldref)); |
570 | int oldLength = m_scenePresenceArray.Length; | 574 | // Swap out the dictionary and list with new references |
571 | ScenePresence[] newArray = new ScenePresence[oldLength - 1]; | 575 | m_scenePresenceMap = newmap; |
572 | int j = 0; | 576 | m_scenePresenceArray = newlist; |
573 | for (int i = 0; i < m_scenePresenceArray.Length; i++) | ||
574 | { | ||
575 | ScenePresence presence = m_scenePresenceArray[i]; | ||
576 | if (presence.UUID != agentID) | ||
577 | { | ||
578 | newArray[j] = presence; | ||
579 | ++j; | ||
580 | } | ||
581 | } | ||
582 | m_scenePresenceArray = newArray; | ||
583 | } | 577 | } |
584 | else | 578 | else |
585 | { | 579 | { |
@@ -698,7 +692,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
698 | } | 692 | } |
699 | 693 | ||
700 | /// <summary> | 694 | /// <summary> |
701 | /// Request a copy of m_scenePresences in this World | 695 | /// Get a reference to the scene presence list. Changes to the list will be done in a copy |
702 | /// There is no guarantee that presences will remain in the scene after the list is returned. | 696 | /// There is no guarantee that presences will remain in the scene after the list is returned. |
703 | /// This list should remain private to SceneGraph. Callers wishing to iterate should instead | 697 | /// This list should remain private to SceneGraph. Callers wishing to iterate should instead |
704 | /// pass a delegate to ForEachScenePresence. | 698 | /// pass a delegate to ForEachScenePresence. |
@@ -706,8 +700,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
706 | /// <returns></returns> | 700 | /// <returns></returns> |
707 | private List<ScenePresence> GetScenePresences() | 701 | private List<ScenePresence> GetScenePresences() |
708 | { | 702 | { |
709 | lock (m_scenePresences) | 703 | return m_scenePresenceArray; |
710 | return new List<ScenePresence>(m_scenePresenceArray); | ||
711 | } | 704 | } |
712 | 705 | ||
713 | /// <summary> | 706 | /// <summary> |
@@ -717,12 +710,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
717 | /// <returns>null if the presence was not found</returns> | 710 | /// <returns>null if the presence was not found</returns> |
718 | protected internal ScenePresence GetScenePresence(UUID agentID) | 711 | protected internal ScenePresence GetScenePresence(UUID agentID) |
719 | { | 712 | { |
720 | ScenePresence sp; | 713 | Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap; |
721 | lock (m_scenePresences) | 714 | ScenePresence presence; |
722 | { | 715 | presences.TryGetValue(agentID, out presence); |
723 | m_scenePresences.TryGetValue(agentID, out sp); | 716 | return presence; |
724 | } | ||
725 | return sp; | ||
726 | } | 717 | } |
727 | 718 | ||
728 | /// <summary> | 719 | /// <summary> |
@@ -733,7 +724,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
733 | /// <returns>null if the presence was not found</returns> | 724 | /// <returns>null if the presence was not found</returns> |
734 | protected internal ScenePresence GetScenePresence(string firstName, string lastName) | 725 | protected internal ScenePresence GetScenePresence(string firstName, string lastName) |
735 | { | 726 | { |
736 | foreach (ScenePresence presence in GetScenePresences()) | 727 | List<ScenePresence> presences = GetScenePresences(); |
728 | foreach (ScenePresence presence in presences) | ||
737 | { | 729 | { |
738 | if (presence.Firstname == firstName && presence.Lastname == lastName) | 730 | if (presence.Firstname == firstName && presence.Lastname == lastName) |
739 | return presence; | 731 | return presence; |
@@ -748,7 +740,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
748 | /// <returns>null if the presence was not found</returns> | 740 | /// <returns>null if the presence was not found</returns> |
749 | protected internal ScenePresence GetScenePresence(uint localID) | 741 | protected internal ScenePresence GetScenePresence(uint localID) |
750 | { | 742 | { |
751 | foreach (ScenePresence presence in GetScenePresences()) | 743 | List<ScenePresence> presences = GetScenePresences(); |
744 | foreach (ScenePresence presence in presences) | ||
752 | if (presence.LocalId == localID) | 745 | if (presence.LocalId == localID) |
753 | return presence; | 746 | return presence; |
754 | return null; | 747 | return null; |
@@ -756,10 +749,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
756 | 749 | ||
757 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) | 750 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) |
758 | { | 751 | { |
759 | lock (m_scenePresences) | 752 | Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap; |
760 | { | 753 | presences.TryGetValue(agentID, out avatar); |
761 | m_scenePresences.TryGetValue(agentID, out avatar); | ||
762 | } | ||
763 | return (avatar != null); | 754 | return (avatar != null); |
764 | } | 755 | } |
765 | 756 | ||
@@ -1036,8 +1027,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1036 | }); | 1027 | }); |
1037 | Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction); | 1028 | Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction); |
1038 | */ | 1029 | */ |
1039 | // For now, perform actiona serially | 1030 | // For now, perform actions serially |
1040 | foreach (ScenePresence sp in GetScenePresences()) | 1031 | List<ScenePresence> presences = GetScenePresences(); |
1032 | foreach (ScenePresence sp in presences) | ||
1041 | { | 1033 | { |
1042 | try | 1034 | try |
1043 | { | 1035 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 46eadee..71c8018 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -104,7 +104,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
104 | 104 | ||
105 | #endregion Enumerations | 105 | #endregion Enumerations |
106 | 106 | ||
107 | public class SceneObjectPart : IScriptHost | 107 | public class SceneObjectPart : IScriptHost, ISceneEntity |
108 | { | 108 | { |
109 | /// <value> | 109 | /// <value> |
110 | /// Denote all sides of the prim | 110 | /// Denote all sides of the prim |
@@ -712,6 +712,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
712 | } | 712 | } |
713 | } | 713 | } |
714 | 714 | ||
715 | public Vector3 RelativePosition | ||
716 | { | ||
717 | get | ||
718 | { | ||
719 | if (IsRoot) | ||
720 | { | ||
721 | if (IsAttachment) | ||
722 | return AttachedPos; | ||
723 | else | ||
724 | return AbsolutePosition; | ||
725 | } | ||
726 | else | ||
727 | { | ||
728 | return OffsetPosition; | ||
729 | } | ||
730 | } | ||
731 | } | ||
732 | |||
715 | public Quaternion RotationOffset | 733 | public Quaternion RotationOffset |
716 | { | 734 | { |
717 | get | 735 | get |
@@ -973,7 +991,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
973 | get { return AggregateScriptEvents; } | 991 | get { return AggregateScriptEvents; } |
974 | } | 992 | } |
975 | 993 | ||
976 | |||
977 | public Quaternion SitTargetOrientation | 994 | public Quaternion SitTargetOrientation |
978 | { | 995 | { |
979 | get { return m_sitTargetOrientation; } | 996 | get { return m_sitTargetOrientation; } |
@@ -2925,11 +2942,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2925 | //if (LocalId != ParentGroup.RootPart.LocalId) | 2942 | //if (LocalId != ParentGroup.RootPart.LocalId) |
2926 | //isattachment = ParentGroup.RootPart.IsAttachment; | 2943 | //isattachment = ParentGroup.RootPart.IsAttachment; |
2927 | 2944 | ||
2928 | byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; | 2945 | remoteClient.SendPrimUpdate(this, PrimUpdateFlags.FullUpdate); |
2929 | remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape, | ||
2930 | lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID, | ||
2931 | m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, | ||
2932 | AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient))); | ||
2933 | } | 2946 | } |
2934 | 2947 | ||
2935 | /// <summary> | 2948 | /// <summary> |
@@ -4640,11 +4653,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4640 | 4653 | ||
4641 | // Causes this thread to dig into the Client Thread Data. | 4654 | // Causes this thread to dig into the Client Thread Data. |
4642 | // Remember your locking here! | 4655 | // Remember your locking here! |
4643 | remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, | 4656 | remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); |
4644 | m_parentGroup.GetTimeDilation(), LocalId, lPos, | ||
4645 | RotationOffset, Velocity, Acceleration, | ||
4646 | AngularVelocity, FromItemID, | ||
4647 | OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient))); | ||
4648 | } | 4657 | } |
4649 | 4658 | ||
4650 | public void AddScriptLPS(int count) | 4659 | public void AddScriptLPS(int count) |
@@ -4694,7 +4703,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4694 | 4703 | ||
4695 | public Color4 GetTextColor() | 4704 | public Color4 GetTextColor() |
4696 | { | 4705 | { |
4697 | return new Color4((byte)Color.R, (byte)Color.G, (byte)Color.B, (byte)(0xFF - Color.A)); | 4706 | Color color = Color; |
4707 | return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); | ||
4698 | } | 4708 | } |
4699 | } | 4709 | } |
4700 | } | 4710 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 30eafd7..ee0eb07 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -67,7 +67,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
67 | 67 | ||
68 | public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence); | 68 | public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence); |
69 | 69 | ||
70 | public class ScenePresence : EntityBase | 70 | public class ScenePresence : EntityBase, ISceneEntity |
71 | { | 71 | { |
72 | // ~ScenePresence() | 72 | // ~ScenePresence() |
73 | // { | 73 | // { |
@@ -478,6 +478,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
478 | } | 478 | } |
479 | } | 479 | } |
480 | 480 | ||
481 | public Vector3 OffsetPosition | ||
482 | { | ||
483 | get { return m_pos; } | ||
484 | set { m_pos = value; } | ||
485 | } | ||
486 | |||
481 | /// <summary> | 487 | /// <summary> |
482 | /// Current velocity of the avatar. | 488 | /// Current velocity of the avatar. |
483 | /// </summary> | 489 | /// </summary> |
@@ -1036,8 +1042,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1036 | AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); | 1042 | AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); |
1037 | } | 1043 | } |
1038 | 1044 | ||
1039 | ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, | 1045 | ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position); |
1040 | AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); | 1046 | //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, |
1047 | // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); | ||
1041 | } | 1048 | } |
1042 | 1049 | ||
1043 | public void AddNeighbourRegion(ulong regionHandle, string cap) | 1050 | public void AddNeighbourRegion(ulong regionHandle, string cap) |
@@ -2360,8 +2367,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2360 | 2367 | ||
2361 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); | 2368 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); |
2362 | 2369 | ||
2363 | remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, | 2370 | remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); |
2364 | pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient))); | ||
2365 | 2371 | ||
2366 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2372 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2367 | m_scene.StatsReporter.AddAgentUpdates(1); | 2373 | m_scene.StatsReporter.AddAgentUpdates(1); |
@@ -2457,9 +2463,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2457 | Vector3 pos = m_pos; | 2463 | Vector3 pos = m_pos; |
2458 | pos.Z += m_appearance.HipOffset; | 2464 | pos.Z += m_appearance.HipOffset; |
2459 | 2465 | ||
2460 | remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, | 2466 | remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); |
2461 | LocalId, pos, m_appearance.Texture.GetBytes(), | ||
2462 | m_parentID, m_bodyRot)); | ||
2463 | m_scene.StatsReporter.AddAgentUpdates(1); | 2467 | m_scene.StatsReporter.AddAgentUpdates(1); |
2464 | } | 2468 | } |
2465 | 2469 | ||
@@ -2527,8 +2531,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2527 | Vector3 pos = m_pos; | 2531 | Vector3 pos = m_pos; |
2528 | pos.Z += m_appearance.HipOffset; | 2532 | pos.Z += m_appearance.HipOffset; |
2529 | 2533 | ||
2530 | m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2534 | m_controllingClient.SendAvatarDataImmediate(this); |
2531 | pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); | ||
2532 | 2535 | ||
2533 | SendInitialFullUpdateToAllClients(); | 2536 | SendInitialFullUpdateToAllClients(); |
2534 | SendAppearanceToAllOtherAgents(); | 2537 | SendAppearanceToAllOtherAgents(); |
@@ -2638,9 +2641,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2638 | Vector3 pos = m_pos; | 2641 | Vector3 pos = m_pos; |
2639 | pos.Z += m_appearance.HipOffset; | 2642 | pos.Z += m_appearance.HipOffset; |
2640 | 2643 | ||
2641 | m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2644 | m_controllingClient.SendAvatarDataImmediate(this); |
2642 | pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); | ||
2643 | |||
2644 | } | 2645 | } |
2645 | 2646 | ||
2646 | public void SetWearable(int wearableId, AvatarWearable wearable) | 2647 | public void SetWearable(int wearableId, AvatarWearable wearable) |
@@ -3906,7 +3907,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3906 | 3907 | ||
3907 | private void Reprioritize(object sender, ElapsedEventArgs e) | 3908 | private void Reprioritize(object sender, ElapsedEventArgs e) |
3908 | { | 3909 | { |
3909 | m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority); | 3910 | m_controllingClient.ReprioritizeUpdates(UpdatePriority); |
3910 | 3911 | ||
3911 | lock (m_reprioritization_timer) | 3912 | lock (m_reprioritization_timer) |
3912 | { | 3913 | { |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 69e78b3..84faac0 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -1045,16 +1045,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1045 | 1045 | ||
1046 | } | 1046 | } |
1047 | 1047 | ||
1048 | public void SendAvatarData(SendAvatarData data) | ||
1049 | { | ||
1050 | |||
1051 | } | ||
1052 | |||
1053 | public void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||
1054 | { | ||
1055 | |||
1056 | } | ||
1057 | |||
1058 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | 1048 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) |
1059 | { | 1049 | { |
1060 | 1050 | ||
@@ -1065,32 +1055,27 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1065 | 1055 | ||
1066 | } | 1056 | } |
1067 | 1057 | ||
1068 | public void SetChildAgentThrottle(byte[] throttle) | 1058 | public void SendAvatarDataImmediate(ISceneEntity avatar) |
1069 | { | 1059 | { |
1070 | |||
1071 | } | ||
1072 | 1060 | ||
1073 | public void SendPrimitiveToClient(SendPrimitiveData data) | ||
1074 | { | ||
1075 | |||
1076 | } | 1061 | } |
1077 | 1062 | ||
1078 | public void SendPrimTerseUpdate(SendPrimitiveTerseData data) | 1063 | public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) |
1079 | { | 1064 | { |
1080 | 1065 | ||
1081 | } | 1066 | } |
1082 | 1067 | ||
1083 | public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | 1068 | public void ReprioritizeUpdates(UpdatePriorityHandler handler) |
1084 | { | 1069 | { |
1085 | 1070 | ||
1086 | } | 1071 | } |
1087 | 1072 | ||
1088 | public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems) | 1073 | public void FlushPrimUpdates() |
1089 | { | 1074 | { |
1090 | 1075 | ||
1091 | } | 1076 | } |
1092 | 1077 | ||
1093 | public void FlushPrimUpdates() | 1078 | public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems) |
1094 | { | 1079 | { |
1095 | 1080 | ||
1096 | } | 1081 | } |
@@ -1420,6 +1405,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1420 | 1405 | ||
1421 | } | 1406 | } |
1422 | 1407 | ||
1408 | public virtual void SetChildAgentThrottle(byte[] throttle) | ||
1409 | { | ||
1410 | |||
1411 | } | ||
1412 | |||
1423 | public byte[] GetThrottlesPacked(float multiplier) | 1413 | public byte[] GetThrottlesPacked(float multiplier) |
1424 | { | 1414 | { |
1425 | return new byte[0]; | 1415 | return new byte[0]; |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 6360c99..9066691 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -618,14 +618,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
618 | { | 618 | { |
619 | } | 619 | } |
620 | 620 | ||
621 | public virtual void SendAvatarData(SendAvatarData data) | ||
622 | { | ||
623 | } | ||
624 | |||
625 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||
626 | { | ||
627 | } | ||
628 | |||
629 | public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | 621 | public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) |
630 | { | 622 | { |
631 | } | 623 | } |
@@ -638,15 +630,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
638 | { | 630 | { |
639 | } | 631 | } |
640 | 632 | ||
641 | public virtual void SendPrimitiveToClient(SendPrimitiveData data) | 633 | public void SendAvatarDataImmediate(ISceneEntity avatar) |
642 | { | 634 | { |
643 | } | 635 | } |
644 | 636 | ||
645 | public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) | 637 | public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) |
646 | { | 638 | { |
647 | } | 639 | } |
648 | 640 | ||
649 | public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | 641 | public void ReprioritizeUpdates(UpdatePriorityHandler handler) |
650 | { | 642 | { |
651 | } | 643 | } |
652 | 644 | ||
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 7e68cc7..15469db 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -1129,7 +1129,89 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1129 | return 0.0f; | 1129 | return 0.0f; |
1130 | } | 1130 | } |
1131 | 1131 | ||
1132 | // Routines for creating and managing parcels programmatically | ||
1133 | public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2) | ||
1134 | { | ||
1135 | CheckThreatLevel(ThreatLevel.High, "osParcelJoin"); | ||
1136 | m_host.AddScriptLPS(1); | ||
1137 | |||
1138 | int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); | ||
1139 | int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); | ||
1140 | int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x); | ||
1141 | int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y); | ||
1142 | |||
1143 | World.LandChannel.Join(startx,starty,endx,endy,m_host.OwnerID); | ||
1144 | } | ||
1145 | |||
1146 | public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2) | ||
1147 | { | ||
1148 | CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide"); | ||
1149 | m_host.AddScriptLPS(1); | ||
1150 | |||
1151 | int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); | ||
1152 | int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); | ||
1153 | int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x); | ||
1154 | int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y); | ||
1132 | 1155 | ||
1156 | World.LandChannel.Subdivide(startx,starty,endx,endy,m_host.OwnerID); | ||
1157 | } | ||
1158 | |||
1159 | public void osParcelSetDetails(LSL_Vector pos, LSL_List rules) | ||
1160 | { | ||
1161 | CheckThreatLevel(ThreatLevel.High, "osParcelSetDetails"); | ||
1162 | m_host.AddScriptLPS(1); | ||
1163 | |||
1164 | // Get a reference to the land data and make sure the owner of the script | ||
1165 | // can modify it | ||
1166 | |||
1167 | ILandObject startLandObject = World.LandChannel.GetLandObject((int)pos.x, (int)pos.y); | ||
1168 | if (startLandObject == null) | ||
1169 | { | ||
1170 | OSSLShoutError("There is no land at that location"); | ||
1171 | return; | ||
1172 | } | ||
1173 | |||
1174 | if (! World.Permissions.CanEditParcel(m_host.OwnerID, startLandObject)) | ||
1175 | { | ||
1176 | OSSLShoutError("You do not have permission to modify the parcel"); | ||
1177 | return; | ||
1178 | } | ||
1179 | |||
1180 | // Create a new land data object we can modify | ||
1181 | LandData newLand = startLandObject.LandData.Copy(); | ||
1182 | UUID uuid; | ||
1183 | |||
1184 | // Process the rules, not sure what the impact would be of changing owner or group | ||
1185 | for (int idx = 0; idx < rules.Length; ) | ||
1186 | { | ||
1187 | int code = rules.GetLSLIntegerItem(idx++); | ||
1188 | string arg = rules.GetLSLStringItem(idx++); | ||
1189 | switch (code) | ||
1190 | { | ||
1191 | case 0: | ||
1192 | newLand.Name = arg; | ||
1193 | break; | ||
1194 | |||
1195 | case 1: | ||
1196 | newLand.Description = arg; | ||
1197 | break; | ||
1198 | |||
1199 | case 2: | ||
1200 | CheckThreatLevel(ThreatLevel.VeryHigh, "osParcelSetDetails"); | ||
1201 | if (UUID.TryParse(arg , out uuid)) | ||
1202 | newLand.OwnerID = uuid; | ||
1203 | break; | ||
1204 | |||
1205 | case 3: | ||
1206 | CheckThreatLevel(ThreatLevel.VeryHigh, "osParcelSetDetails"); | ||
1207 | if (UUID.TryParse(arg , out uuid)) | ||
1208 | newLand.GroupID = uuid; | ||
1209 | break; | ||
1210 | } | ||
1211 | } | ||
1212 | |||
1213 | World.LandChannel.UpdateLandObject(newLand.LocalID,newLand); | ||
1214 | } | ||
1133 | 1215 | ||
1134 | public double osList2Double(LSL_Types.list src, int index) | 1216 | public double osList2Double(LSL_Types.list src, int index) |
1135 | { | 1217 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 60b8050..7a8f469 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); |