aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Client/MXP/ClientStack/MXPClientView.cs31
-rw-r--r--OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs13
-rw-r--r--OpenSim/Data/MySQL/MySQLLegacyRegionData.cs25
-rw-r--r--OpenSim/Framework/IClientAPI.cs254
-rwxr-xr-xOpenSim/Framework/MinHeap.cs375
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs713
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs79
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs6
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs28
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISceneViewer.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs73
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs18
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs74
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs65
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs13
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs4
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs27
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs18
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs4
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs28
-rw-r--r--bin/OpenSim.ini.example8
29 files changed, 1414 insertions, 514 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index bc02bc4..ea29c41 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -996,19 +996,19 @@ namespace OpenSim.Client.MXP.ClientStack
996 // Need to translate to MXP somehow 996 // Need to translate to MXP somehow
997 } 997 }
998 998
999 public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, uint avatarLocalID, Vector3 position, byte[] textureEntry, uint parentID, Quaternion rotation) 999 public void SendAvatarData(SendAvatarData data)
1000 { 1000 {
1001 //ScenePresence presence=((Scene)this.Scene).GetScenePresence(avatarID); 1001 //ScenePresence presence=((Scene)this.Scene).GetScenePresence(avatarID);
1002 UUID ownerID = avatarID; 1002 UUID ownerID = data.avatarID;
1003 MXPSendAvatarData(firstName + " " + lastName, ownerID, UUID.Zero, avatarID, avatarLocalID, position, rotation); 1003 MXPSendAvatarData(data.firstName + " " + data.lastName, ownerID, UUID.Zero, data.avatarID, data.avatarLocalID, data.Pos, data.rotation);
1004 } 1004 }
1005 1005
1006 public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation, UUID uuid) 1006 public void SendAvatarTerseUpdate(SendAvatarTerseData data)
1007 { 1007 {
1008 MovementEventMessage me = new MovementEventMessage(); 1008 MovementEventMessage me = new MovementEventMessage();
1009 me.ObjectIndex = localID; 1009 me.ObjectIndex = data.localID;
1010 me.Location =ToOmVector(position); 1010 me.Location = ToOmVector(data.position);
1011 me.Orientation = ToOmQuaternion(rotation); 1011 me.Orientation = ToOmQuaternion(data.rotation);
1012 1012
1013 Session.Send(me); 1013 Session.Send(me);
1014 } 1014 }
@@ -1028,22 +1028,17 @@ namespace OpenSim.Client.MXP.ClientStack
1028 // Need to translate to MXP somehow 1028 // Need to translate to MXP somehow
1029 } 1029 }
1030 1030
1031 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius) 1031 public void SendPrimitiveToClient(SendPrimitiveData data)
1032 { 1032 {
1033 MXPSendPrimitive(localID, ownerID, acc, rvel, primShape, pos, objectID, vel, rotation, flags,text,color,parentID,particleSystem,clickAction,material,textureanim); 1033 MXPSendPrimitive(data.localID, data.ownerID, data.acc, data.rvel, data.primShape, data.pos, data.objectID, data.vel, data.rotation, data.flags, data.text, data.color, data.parentID, data.particleSystem, data.clickAction, data.material, data.textureanim);
1034 } 1034 }
1035 1035
1036 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material) 1036 public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
1037 {
1038 MXPSendPrimitive(localID, ownerID, acc, rvel, primShape, pos, objectID, vel, rotation, flags, text, color, parentID, particleSystem, clickAction, material, new byte[0]);
1039 }
1040
1041 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID owner, int attachPoint)
1042 { 1037 {
1043 MovementEventMessage me = new MovementEventMessage(); 1038 MovementEventMessage me = new MovementEventMessage();
1044 me.ObjectIndex = localID; 1039 me.ObjectIndex = data.localID;
1045 me.Location = ToOmVector(position); 1040 me.Location = ToOmVector(data.position);
1046 me.Orientation = ToOmQuaternion(rotation); 1041 me.Orientation = ToOmQuaternion(data.rotation);
1047 Session.Send(me); 1042 Session.Send(me);
1048 } 1043 }
1049 1044
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
index e3abcf5..3a48a03 100644
--- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
+++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
@@ -560,12 +560,12 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
560 throw new System.NotImplementedException(); 560 throw new System.NotImplementedException();
561 } 561 }
562 562
563 public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) 563 public void SendAvatarData(SendAvatarData data)
564 { 564 {
565 throw new System.NotImplementedException(); 565 throw new System.NotImplementedException();
566 } 566 }
567 567
568 public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation, UUID uuid) 568 public void SendAvatarTerseUpdate(SendAvatarTerseData data)
569 { 569 {
570 throw new System.NotImplementedException(); 570 throw new System.NotImplementedException();
571 } 571 }
@@ -585,17 +585,12 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
585 throw new System.NotImplementedException(); 585 throw new System.NotImplementedException();
586 } 586 }
587 587
588 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius) 588 public void SendPrimitiveToClient(SendPrimitiveData data)
589 { 589 {
590 throw new System.NotImplementedException(); 590 throw new System.NotImplementedException();
591 } 591 }
592 592
593 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material) 593 public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
594 {
595 throw new System.NotImplementedException();
596 }
597
598 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID owner, int attachPoint)
599 { 594 {
600 throw new System.NotImplementedException(); 595 throw new System.NotImplementedException();
601 } 596 }
diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
index fe0914b..6bc8bec 100644
--- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
+++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
@@ -68,12 +68,20 @@ namespace OpenSim.Data.MySQL
68 68
69 // Clean dropped attachments 69 // Clean dropped attachments
70 // 70 //
71 MySqlCommand cmd = m_Connection.CreateCommand(); 71 try
72 cmd.CommandText = "delete from prims, primshapes using prims " + 72 {
73 "left join primshapes on prims.uuid = primshapes.uuid " + 73 using (MySqlCommand cmd = m_Connection.CreateCommand())
74 "where PCode = 9 and State <> 0"; 74 {
75 ExecuteNonQuery(cmd); 75 cmd.CommandText = "delete from prims, primshapes using prims " +
76 cmd.Dispose(); 76 "left join primshapes on prims.uuid = primshapes.uuid " +
77 "where PCode = 9 and State <> 0";
78 ExecuteNonQuery(cmd);
79 }
80 }
81 catch (MySqlException ex)
82 {
83 m_log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message);
84 }
77 } 85 }
78 86
79 private IDataReader ExecuteReader(MySqlCommand c) 87 private IDataReader ExecuteReader(MySqlCommand c)
@@ -401,6 +409,7 @@ namespace OpenSim.Data.MySQL
401 Dictionary<UUID, SceneObjectGroup> objects = new Dictionary<UUID, SceneObjectGroup>(); 409 Dictionary<UUID, SceneObjectGroup> objects = new Dictionary<UUID, SceneObjectGroup>();
402 Dictionary<UUID, SceneObjectPart> prims = new Dictionary<UUID, SceneObjectPart>(); 410 Dictionary<UUID, SceneObjectPart> prims = new Dictionary<UUID, SceneObjectPart>();
403 SceneObjectGroup grp = null; 411 SceneObjectGroup grp = null;
412 int count = 0;
404 413
405 lock (m_Connection) 414 lock (m_Connection)
406 { 415 {
@@ -463,6 +472,10 @@ namespace OpenSim.Data.MySQL
463 if (link != 0) 472 if (link != 0)
464 prim.LinkNum = link; 473 prim.LinkNum = link;
465 } 474 }
475
476 ++count;
477 if (count % 5000 == 0)
478 m_log.Debug("[REGION DB]: Loaded " + count + " prims...");
466 } 479 }
467 } 480 }
468 481
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 29846f5..4b51e15 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -517,6 +517,233 @@ namespace OpenSim.Framework
517 public float dwell; 517 public float dwell;
518 } 518 }
519 519
520 public struct SendAvatarData
521 {
522 private ulong m_regionHandle;
523 private string m_firstName;
524 private string m_lastName;
525 private string m_grouptitle;
526 private UUID m_avatarID;
527 private uint m_avatarLocalID;
528 private Vector3 m_Pos;
529 private byte[] m_textureEntry;
530 private uint m_parentID;
531 private Quaternion m_rotation;
532
533 public SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID,
534 uint avatarLocalID,
535 Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation)
536 {
537 this.m_regionHandle = regionHandle;
538 this.m_firstName = firstName;
539 this.m_lastName = lastName;
540 this.m_grouptitle = grouptitle;
541 this.m_avatarID = avatarID;
542 this.m_avatarLocalID = avatarLocalID;
543 this.m_Pos = Pos;
544 this.m_textureEntry = textureEntry;
545 this.m_parentID = parentID;
546 this.m_rotation = rotation;
547 }
548
549 public ulong regionHandle { get { return this.m_regionHandle; } }
550 public string firstName { get { return this.m_firstName; } }
551 public string lastName { get { return this.m_lastName; } }
552 public string grouptitle { get { return this.m_grouptitle; } }
553 public UUID avatarID { get { return this.m_avatarID; } }
554 public uint avatarLocalID { get { return this.m_avatarLocalID; } }
555 public Vector3 Pos { get { return this.m_Pos; } }
556 public byte[] textureEntry { get { return this.m_textureEntry; } }
557 public uint parentID { get { return this.m_parentID; } }
558 public Quaternion rotation { get { return this.m_rotation; } }
559 }
560
561 public struct SendAvatarTerseData
562 {
563 private ulong m_regionHandle;
564 private ushort m_timeDilation;
565 private uint m_localID;
566 private Vector3 m_position;
567 private Vector3 m_velocity;
568 private Quaternion m_rotation;
569 private UUID m_agentid;
570 private double m_priority;
571
572 public SendAvatarTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
573 Vector3 velocity, Quaternion rotation, UUID agentid, double priority)
574 {
575 this.m_regionHandle = regionHandle;
576 this.m_timeDilation = timeDilation;
577 this.m_localID = localID;
578 this.m_position = position;
579 this.m_velocity = velocity;
580 this.m_rotation = rotation;
581 this.m_agentid = agentid;
582 this.m_priority = priority;
583 }
584
585 public ulong regionHandle { get { return this.m_regionHandle; } }
586 public ushort timeDilation { get { return this.m_timeDilation; } }
587 public uint localID { get { return this.m_localID; } }
588 public Vector3 position { get { return this.m_position; } }
589 public Vector3 velocity { get { return this.m_velocity; } }
590 public Quaternion rotation { get { return this.m_rotation; } }
591 public UUID agentid { get { return this.m_agentid; } }
592 public double priority { get { return this.m_priority; } }
593 }
594
595 public struct SendPrimitiveTerseData
596 {
597 private ulong m_regionHandle;
598 private ushort m_timeDilation;
599 private uint m_localID;
600 private Vector3 m_position;
601 private Quaternion m_rotation;
602 private Vector3 m_velocity;
603 private Vector3 m_rotationalvelocity;
604 private byte m_state;
605 private UUID m_AssetId;
606 private UUID m_owner;
607 private int m_attachPoint;
608 private double m_priority;
609
610 public SendPrimitiveTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
611 Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state,
612 UUID AssetId, UUID owner, int attachPoint, double priority)
613 {
614 this.m_regionHandle = regionHandle;
615 this.m_timeDilation = timeDilation;
616 this.m_localID = localID;
617 this.m_position = position;
618 this.m_rotation = rotation;
619 this.m_velocity = velocity;
620 this.m_rotationalvelocity = rotationalvelocity;
621 this.m_state = state;
622 this.m_AssetId = AssetId;
623 this.m_owner = owner;
624 this.m_attachPoint = attachPoint;
625 this.m_priority = priority;
626 }
627
628 public ulong regionHandle { get { return this.m_regionHandle; } }
629 public ushort timeDilation { get { return this.m_timeDilation; } }
630 public uint localID { get { return this.m_localID; } }
631 public Vector3 position { get { return this.m_position; } }
632 public Quaternion rotation { get { return this.m_rotation; } }
633 public Vector3 velocity { get { return this.m_velocity; } }
634 public Vector3 rotationalvelocity { get { return this.m_rotationalvelocity; } }
635 public byte state { get { return this.m_state; } }
636 public UUID AssetId { get { return this.m_AssetId; } }
637 public UUID owner { get { return this.m_owner; } }
638 public int attachPoint { get { return this.m_attachPoint; } }
639 public double priority { get { return this.m_priority; } }
640 }
641
642 public struct SendPrimitiveData
643 {
644 private ulong m_regionHandle;
645 private ushort m_timeDilation;
646 private uint m_localID;
647 private PrimitiveBaseShape m_primShape;
648 private Vector3 m_pos;
649 private Vector3 m_vel;
650 private Vector3 m_acc;
651 private Quaternion m_rotation;
652 private Vector3 m_rvel;
653 private uint m_flags;
654 private UUID m_objectID;
655 private UUID m_ownerID;
656 private string m_text;
657 private byte[] m_color;
658 private uint m_parentID;
659 private byte[] m_particleSystem;
660 private byte m_clickAction;
661 private byte m_material;
662 private byte[] m_textureanim;
663 private bool m_attachment;
664 private uint m_AttachPoint;
665 private UUID m_AssetId;
666 private UUID m_SoundId;
667 private double m_SoundVolume;
668 private byte m_SoundFlags;
669 private double m_SoundRadius;
670 private double m_priority;
671
672 public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
673 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
674 uint flags, UUID objectID, UUID ownerID, string text, byte[] color,
675 uint parentID, byte[] particleSystem, byte clickAction, byte material, double priority) :
676 this(regionHandle, timeDilation, localID, primShape, pos, vel, acc, rotation, rvel, flags, objectID,
677 ownerID, text, color, parentID, particleSystem, clickAction, material, new byte[0], false, 0, UUID.Zero,
678 UUID.Zero, 0, 0, 0, priority) { }
679
680 public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
681 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
682 uint flags,
683 UUID objectID, UUID ownerID, string text, byte[] color, uint parentID,
684 byte[] particleSystem,
685 byte clickAction, byte material, byte[] textureanim, bool attachment,
686 uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags,
687 double SoundRadius, double priority)
688 {
689 this.m_regionHandle = regionHandle;
690 this.m_timeDilation = timeDilation;
691 this.m_localID = localID;
692 this.m_primShape = primShape;
693 this.m_pos = pos;
694 this.m_vel = vel;
695 this.m_acc = acc;
696 this.m_rotation = rotation;
697 this.m_rvel = rvel;
698 this.m_flags = flags;
699 this.m_objectID = objectID;
700 this.m_ownerID = ownerID;
701 this.m_text = text;
702 this.m_color = color;
703 this.m_parentID = parentID;
704 this.m_particleSystem = particleSystem;
705 this.m_clickAction = clickAction;
706 this.m_material = material;
707 this.m_textureanim = textureanim;
708 this.m_attachment = attachment;
709 this.m_AttachPoint = AttachPoint;
710 this.m_AssetId = AssetId;
711 this.m_SoundId = SoundId;
712 this.m_SoundVolume = SoundVolume;
713 this.m_SoundFlags = SoundFlags;
714 this.m_SoundRadius = SoundRadius;
715 this.m_priority = priority;
716 }
717
718 public ulong regionHandle { get { return this.m_regionHandle; } }
719 public ushort timeDilation { get { return this.m_timeDilation; } }
720 public uint localID { get { return this.m_localID; } }
721 public PrimitiveBaseShape primShape { get { return this.m_primShape; } }
722 public Vector3 pos { get { return this.m_pos; } }
723 public Vector3 vel { get { return this.m_vel; } }
724 public Vector3 acc { get { return this.m_acc; } }
725 public Quaternion rotation { get { return this.m_rotation; } }
726 public Vector3 rvel { get { return this.m_rvel; } }
727 public uint flags { get { return this.m_flags; } }
728 public UUID objectID { get { return this.m_objectID; } }
729 public UUID ownerID { get { return this.m_ownerID; } }
730 public string text { get { return this.m_text; } }
731 public byte[] color { get { return this.m_color; } }
732 public uint parentID { get { return this.m_parentID; } }
733 public byte[] particleSystem { get { return this.m_particleSystem; } }
734 public byte clickAction { get { return this.m_clickAction; } }
735 public byte material { get { return this.m_material; } }
736 public byte[] textureanim { get { return this.m_textureanim; } }
737 public bool attachment { get { return this.m_attachment; } }
738 public uint AttachPoint { get { return this.m_AttachPoint; } }
739 public UUID AssetId { get { return this.m_AssetId; } }
740 public UUID SoundId { get { return this.m_SoundId; } }
741 public double SoundVolume { get { return this.m_SoundVolume; } }
742 public byte SoundFlags { get { return this.m_SoundFlags; } }
743 public double SoundRadius { get { return this.m_SoundRadius; } }
744 public double priority { get { return this.m_priority; } }
745 }
746
520 public interface IClientAPI 747 public interface IClientAPI
521 { 748 {
522 Vector3 StartPos { get; set; } 749 Vector3 StartPos { get; set; }
@@ -877,37 +1104,18 @@ namespace OpenSim.Framework
877 void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance); 1104 void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance);
878 void SendPayPrice(UUID objectID, int[] payPrice); 1105 void SendPayPrice(UUID objectID, int[] payPrice);
879 1106
880 void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, 1107 void SendAvatarData(SendAvatarData data);
881 uint avatarLocalID,
882 Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation);
883 1108
884 void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, 1109 void SendAvatarTerseUpdate(SendAvatarTerseData data);
885 Vector3 velocity, Quaternion rotation, UUID agentid);
886 1110
887 void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations); 1111 void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations);
888 1112
889 void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID); 1113 void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID);
890 void SetChildAgentThrottle(byte[] throttle); 1114 void SetChildAgentThrottle(byte[] throttle);
891 1115
892 void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, 1116 void SendPrimitiveToClient(SendPrimitiveData data);
893 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
894 uint flags,
895 UUID objectID, UUID ownerID, string text, byte[] color, uint parentID,
896 byte[] particleSystem,
897 byte clickAction, byte material, byte[] textureanim, bool attachment,
898 uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags,
899 double SoundRadius);
900
901 1117
902 void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, 1118 void SendPrimTerseUpdate(SendPrimitiveTerseData data);
903 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
904 uint flags, UUID objectID, UUID ownerID, string text, byte[] color,
905 uint parentID, byte[] particleSystem, byte clickAction, byte material);
906
907
908 void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
909 Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state,
910 UUID AssetId, UUID owner, int attachPoint);
911 1119
912 void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, 1120 void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items,
913 List<InventoryFolderBase> folders, bool fetchFolders, 1121 List<InventoryFolderBase> folders, bool fetchFolders,
diff --git a/OpenSim/Framework/MinHeap.cs b/OpenSim/Framework/MinHeap.cs
new file mode 100755
index 0000000..ad39bbc
--- /dev/null
+++ b/OpenSim/Framework/MinHeap.cs
@@ -0,0 +1,375 @@
1using System;
2using System.Threading;
3using System.Collections;
4using System.Collections.Generic;
5using System.Runtime.InteropServices;
6
7namespace OpenSim.Framework
8{
9 public interface IHandle { }
10
11 [Serializable, ComVisible(false)]
12 public class MinHeap<T> : ICollection<T>, ICollection
13 {
14 private class Handle : IHandle
15 {
16 internal int index = -1;
17 internal MinHeap<T> heap = null;
18
19 internal void Clear()
20 {
21 this.index = -1;
22 this.heap = null;
23 }
24 }
25
26 private struct HeapItem
27 {
28 internal T value;
29 internal Handle handle;
30
31 internal HeapItem(T value, Handle handle)
32 {
33 this.value = value;
34 this.handle = handle;
35 }
36
37 internal void Clear()
38 {
39 this.value = default(T);
40 if (this.handle != null)
41 {
42 this.handle.Clear();
43 this.handle = null;
44 }
45 }
46 }
47
48 public const int DEFAULT_CAPACITY = 4;
49
50 private HeapItem[] items;
51 private int size;
52 private object sync_root;
53 private int version;
54
55 private Comparison<T> comparison;
56
57 public MinHeap() : this(DEFAULT_CAPACITY, Comparer<T>.Default) { }
58 public MinHeap(int capacity) : this(capacity, Comparer<T>.Default) { }
59 public MinHeap(IComparer<T> comparer) : this(DEFAULT_CAPACITY, comparer) { }
60 public MinHeap(int capacity, IComparer<T> comparer) :
61 this(capacity, new Comparison<T>(comparer.Compare)) { }
62 public MinHeap(Comparison<T> comparison) : this(DEFAULT_CAPACITY, comparison) { }
63 public MinHeap(int capacity, Comparison<T> comparison)
64 {
65 this.items = new HeapItem[capacity];
66 this.comparison = comparison;
67 this.size = this.version = 0;
68 }
69
70 public int Count { get { return this.size; } }
71
72 public bool IsReadOnly { get { return false; } }
73
74 public bool IsSynchronized { get { return false; } }
75
76 public T this[IHandle key]
77 {
78 get
79 {
80 Handle handle = ValidateThisHandle(key);
81 return this.items[handle.index].value;
82 }
83
84 set
85 {
86 Handle handle = ValidateThisHandle(key);
87 this.items[handle.index].value = value;
88 if (!BubbleUp(handle.index))
89 BubbleDown(handle.index);
90 }
91 }
92
93 public object SyncRoot
94 {
95 get
96 {
97 if (this.sync_root == null)
98 Interlocked.CompareExchange<object>(ref this.sync_root, new object(), null);
99 return this.sync_root;
100 }
101 }
102
103 private Handle ValidateHandle(IHandle ihandle)
104 {
105 if (ihandle == null)
106 throw new ArgumentNullException("handle");
107 Handle handle = ihandle as Handle;
108 if (handle == null)
109 throw new InvalidOperationException("handle is not valid");
110 return handle;
111 }
112
113 private Handle ValidateThisHandle(IHandle ihandle)
114 {
115 Handle handle = ValidateHandle(ihandle);
116 if (!object.ReferenceEquals(handle.heap, this))
117 throw new InvalidOperationException("handle is not valid for this heap");
118 if (handle.index < 0)
119 throw new InvalidOperationException("handle is not associated to a value");
120 return handle;
121 }
122
123 private void Set(HeapItem item, int index)
124 {
125 this.items[index] = item;
126 if (item.handle != null)
127 item.handle.index = index;
128 }
129
130 private bool BubbleUp(int index)
131 {
132 HeapItem item = this.items[index];
133 int current, parent;
134
135 for (current = index, parent = (current - 1) / 2;
136 (current > 0) && (this.comparison(this.items[parent].value, item.value)) > 0;
137 current = parent, parent = (current - 1) / 2)
138 {
139 Set(this.items[parent], current);
140 }
141
142 if (current != index)
143 {
144 Set(item, current);
145 ++this.version;
146 return true;
147 }
148 return false;
149 }
150
151 private void BubbleDown(int index)
152 {
153 HeapItem item = this.items[index];
154 int current, child;
155
156 for (current = index, child = (2 * current) + 1;
157 current < this.size / 2;
158 current = child, child = (2 * current) + 1)
159 {
160 if ((child < this.size - 1) && this.comparison(this.items[child].value, this.items[child + 1].value) > 0)
161 ++child;
162 if (this.comparison(this.items[child].value, item.value) >= 0)
163 break;
164 Set(this.items[child], current);
165 }
166
167 if (current != index)
168 {
169 Set(item, current);
170 ++this.version;
171 }
172 }
173
174 public bool TryGetValue(IHandle key, out T value)
175 {
176 Handle handle = ValidateHandle(key);
177 if (handle.index > -1)
178 {
179 value = this.items[handle.index].value;
180 return true;
181 }
182 value = default(T);
183 return false;
184 }
185
186 public bool ContainsHandle(IHandle ihandle)
187 {
188 Handle handle = ValidateHandle(ihandle);
189 return object.ReferenceEquals(handle.heap, this) && handle.index > -1;
190 }
191
192 public void Add(T value, ref IHandle handle)
193 {
194 if (handle == null)
195 handle = new Handle();
196 Add(value, handle);
197 }
198
199 public void Add(T value, IHandle ihandle)
200 {
201 if (this.size == this.items.Length)
202 {
203 int capacity = (int)((this.items.Length * 200L) / 100L);
204 if (capacity < (this.items.Length + DEFAULT_CAPACITY))
205 capacity = this.items.Length + DEFAULT_CAPACITY;
206 Array.Resize<HeapItem>(ref this.items, capacity);
207 }
208
209 Handle handle = null;
210 if (ihandle != null)
211 {
212 handle = ValidateHandle(ihandle);
213 handle.heap = this;
214 }
215
216 HeapItem item = new MinHeap<T>.HeapItem(value, handle);
217
218 Set(item, this.size);
219 BubbleUp(this.size++);
220 }
221
222 public void Add(T value)
223 {
224 Add(value, null);
225 }
226
227 public T Min()
228 {
229 if (this.size == 0)
230 throw new InvalidOperationException("Heap is empty");
231
232 return this.items[0].value;
233 }
234
235 public void Clear()
236 {
237 for (int index = 0; index < this.size; ++index)
238 this.items[index].Clear();
239 this.size = 0;
240 ++this.version;
241 }
242
243 public void TrimExcess()
244 {
245 int length = (int)(this.items.Length * 0.9);
246 if (this.size < length)
247 Array.Resize<HeapItem>(ref this.items, Math.Min(this.size, DEFAULT_CAPACITY));
248 }
249
250 private void RemoveAt(int index)
251 {
252 if (this.size == 0)
253 throw new InvalidOperationException("Heap is empty");
254 if (index >= this.size)
255 throw new ArgumentOutOfRangeException("index");
256
257 this.items[index].Clear();
258 if (--this.size > 0 && index != this.size)
259 {
260 Set(this.items[this.size], index);
261 if (!BubbleUp(index))
262 BubbleDown(index);
263 }
264 }
265
266 public T RemoveMin()
267 {
268 if (this.size == 0)
269 throw new InvalidOperationException("Heap is empty");
270
271 HeapItem item = this.items[0];
272 RemoveAt(0);
273 return item.value;
274 }
275
276 public T Remove(IHandle ihandle)
277 {
278 Handle handle = ValidateThisHandle(ihandle);
279 HeapItem item = this.items[handle.index];
280 RemoveAt(handle.index);
281 return item.value;
282 }
283
284 private int GetIndex(T value)
285 {
286 EqualityComparer<T> comparer = EqualityComparer<T>.Default;
287 int index;
288
289 for (index = 0; index < this.size; ++index)
290 {
291 if (comparer.Equals(this.items[index].value, value))
292 return index;
293 }
294 return -1;
295 }
296
297 public bool Contains(T value)
298 {
299 return GetIndex(value) != -1;
300 }
301
302 public bool Remove(T value)
303 {
304 int index = GetIndex(value);
305 if (index != -1)
306 {
307 RemoveAt(index);
308 return true;
309 }
310 return false;
311 }
312
313 public void CopyTo(T[] array, int index)
314 {
315 if (array == null)
316 throw new ArgumentNullException("array");
317 if (array.Rank != 1)
318 throw new ArgumentException("Multidimensional array not supported");
319 if (array.GetLowerBound(0) != 0)
320 throw new ArgumentException("Non-zero lower bound array not supported");
321
322 int length = array.Length;
323 if ((index < 0) || (index > length))
324 throw new ArgumentOutOfRangeException("index");
325 if ((length - index) < this.size)
326 throw new ArgumentException("Not enough space available in array starting at index");
327
328 for (int i = 0; i < this.size; ++i)
329 array[index + i] = this.items[i].value;
330 }
331
332 public void CopyTo(Array array, int index)
333 {
334 if (array == null)
335 throw new ArgumentNullException("array");
336 if (array.Rank != 1)
337 throw new ArgumentException("Multidimensional array not supported");
338 if (array.GetLowerBound(0) != 0)
339 throw new ArgumentException("Non-zero lower bound array not supported");
340
341 int length = array.Length;
342 if ((index < 0) || (index > length))
343 throw new ArgumentOutOfRangeException("index");
344 if ((length - index) < this.size)
345 throw new ArgumentException("Not enough space available in array starting at index");
346
347 try
348 {
349 for (int i = 0; i < this.size; ++i)
350 array.SetValue(this.items[i].value, index + i);
351 }
352 catch (ArrayTypeMismatchException)
353 {
354 throw new ArgumentException("Invalid array type");
355 }
356 }
357
358 public IEnumerator<T> GetEnumerator()
359 {
360 int version = this.version;
361
362 for (int index = 0; index < this.size; ++index)
363 {
364 if (version != this.version)
365 throw new InvalidOperationException("Heap was modified while enumerating");
366 yield return this.items[index].value;
367 }
368 }
369
370 IEnumerator IEnumerable.GetEnumerator()
371 {
372 return GetEnumerator();
373 }
374 }
375}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 05a2a63..630b6e6 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -51,6 +51,44 @@ using Nini.Config;
51 51
52namespace OpenSim.Region.ClientStack.LindenUDP 52namespace OpenSim.Region.ClientStack.LindenUDP
53{ 53{
54 #region Enums
55
56 /// <summary>
57 /// Specifies the fields that have been changed when sending a prim or
58 /// avatar update
59 /// </summary>
60 [Flags]
61 public enum PrimUpdateFlags : uint
62 {
63 None = 0,
64 AttachmentPoint = 1 << 0,
65 Material = 1 << 1,
66 ClickAction = 1 << 2,
67 Scale = 1 << 3,
68 ParentID = 1 << 4,
69 PrimFlags = 1 << 5,
70 PrimData = 1 << 6,
71 MediaURL = 1 << 7,
72 ScratchPad = 1 << 8,
73 Textures = 1 << 9,
74 TextureAnim = 1 << 10,
75 NameValue = 1 << 11,
76 Position = 1 << 12,
77 Rotation = 1 << 13,
78 Velocity = 1 << 14,
79 Acceleration = 1 << 15,
80 AngularVelocity = 1 << 16,
81 CollisionPlane = 1 << 17,
82 Text = 1 << 18,
83 Particles = 1 << 19,
84 ExtraData = 1 << 20,
85 Sound = 1 << 21,
86 Joint = 1 << 22,
87 FullUpdate = UInt32.MaxValue
88 }
89
90 #endregion Enums
91
54 public delegate bool PacketMethod(IClientAPI simClient, Packet packet); 92 public delegate bool PacketMethod(IClientAPI simClient, Packet packet);
55 93
56 /// <summary> 94 /// <summary>
@@ -282,12 +320,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
282 private readonly IGroupsModule m_GroupsModule; 320 private readonly IGroupsModule m_GroupsModule;
283 321
284 private int m_cachedTextureSerial; 322 private int m_cachedTextureSerial;
285 private Timer m_avatarTerseUpdateTimer; 323 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates =
286 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); 324 new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
287 private Timer m_primTerseUpdateTimer; 325 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates =
288 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); 326 new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
289 private Timer m_primFullUpdateTimer; 327 private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates =
290 private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = new List<ObjectUpdatePacket.ObjectDataBlock>(); 328 new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>();
291 private int m_moneyBalance; 329 private int m_moneyBalance;
292 private int m_animationSequenceNumber = 1; 330 private int m_animationSequenceNumber = 1;
293 private bool m_SendLogoutPacketWhenClosing = true; 331 private bool m_SendLogoutPacketWhenClosing = true;
@@ -312,9 +350,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
312 // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet 350 // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet
313 protected int m_primTerseUpdatesPerPacket = 10; 351 protected int m_primTerseUpdatesPerPacket = 10;
314 protected int m_primFullUpdatesPerPacket = 14; 352 protected int m_primFullUpdatesPerPacket = 14;
315 protected int m_primTerseUpdateRate = 10;
316 protected int m_primFullUpdateRate = 14;
317 protected int m_avatarTerseUpdateRate = 50;
318 protected int m_avatarTerseUpdatesPerPacket = 5; 353 protected int m_avatarTerseUpdatesPerPacket = 5;
319 /// <summary>Number of texture packets to put on the queue each time the 354 /// <summary>Number of texture packets to put on the queue each time the
320 /// OnQueueEmpty event is triggered for the texture category</summary> 355 /// OnQueueEmpty event is triggered for the texture category</summary>
@@ -438,25 +473,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
438 // Remove ourselves from the scene 473 // Remove ourselves from the scene
439 m_scene.RemoveClient(AgentId); 474 m_scene.RemoveClient(AgentId);
440 475
441 // Shut down timers. Thread Context of this method is murky. Lock all timers
442 if (m_avatarTerseUpdateTimer.Enabled)
443 lock (m_avatarTerseUpdateTimer)
444 m_avatarTerseUpdateTimer.Stop();
445 if (m_primTerseUpdateTimer.Enabled)
446 lock (m_primTerseUpdateTimer)
447 m_primTerseUpdateTimer.Stop();
448 if (m_primFullUpdateTimer.Enabled)
449 lock (m_primFullUpdateTimer)
450 m_primFullUpdateTimer.Stop();
451
452 // We can't reach into other scenes and close the connection 476 // We can't reach into other scenes and close the connection
453 // We need to do this over grid communications 477 // We need to do this over grid communications
454 //m_scene.CloseAllAgents(CircuitCode); 478 //m_scene.CloseAllAgents(CircuitCode);
455 479
456 m_avatarTerseUpdateTimer.Dispose();
457 m_primTerseUpdateTimer.Dispose();
458 m_primFullUpdateTimer.Dispose();
459
460 // Disable UDP handling for this client 480 // Disable UDP handling for this client
461 m_udpClient.Shutdown(); 481 m_udpClient.Shutdown();
462 482
@@ -483,18 +503,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
483 503
484 public void Stop() 504 public void Stop()
485 { 505 {
486 // Shut down timers. Thread Context is Murky, lock all timers!
487 if (m_avatarTerseUpdateTimer.Enabled)
488 lock (m_avatarTerseUpdateTimer)
489 m_avatarTerseUpdateTimer.Stop();
490 506
491 if (m_primTerseUpdateTimer.Enabled)
492 lock (m_primTerseUpdateTimer)
493 m_primTerseUpdateTimer.Stop();
494
495 if (m_primFullUpdateTimer.Enabled)
496 lock (m_primFullUpdateTimer)
497 m_primFullUpdateTimer.Stop();
498 } 507 }
499 508
500 #endregion Client Methods 509 #endregion Client Methods
@@ -590,18 +599,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
590 599
591 public virtual void Start() 600 public virtual void Start()
592 { 601 {
593 m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate);
594 m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates);
595 m_avatarTerseUpdateTimer.AutoReset = false;
596
597 m_primTerseUpdateTimer = new Timer(m_primTerseUpdateRate);
598 m_primTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimTerseUpdates);
599 m_primTerseUpdateTimer.AutoReset = false;
600
601 m_primFullUpdateTimer = new Timer(m_primFullUpdateRate);
602 m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates);
603 m_primFullUpdateTimer.AutoReset = false;
604
605 m_scene.AddNewClient(this); 602 m_scene.AddNewClient(this);
606 603
607 RefreshGroupMembership(); 604 RefreshGroupMembership();
@@ -3127,7 +3124,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3127 3124
3128 avp.Sender.IsTrial = false; 3125 avp.Sender.IsTrial = false;
3129 avp.Sender.ID = agentID; 3126 avp.Sender.ID = agentID;
3130 OutPacket(avp, ThrottleOutPacketType.State); 3127 OutPacket(avp, ThrottleOutPacketType.Task);
3131 } 3128 }
3132 3129
3133 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) 3130 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
@@ -3159,33 +3156,221 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3159 3156
3160 #endregion 3157 #endregion
3161 3158
3159 #region Prim/Avatar Updates
3160
3161 /*void SendObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3162 {
3163 bool canUseCompressed, canUseImproved;
3164 UpdateFlagsToPacketType(creatorFlags, updateFlags, out canUseCompressed, out canUseImproved);
3165
3166 if (!canUseImproved && !canUseCompressed)
3167 SendFullObjectUpdate(obj, creatorFlags, updateFlags);
3168 else if (!canUseImproved)
3169 SendObjectUpdateCompressed(obj, creatorFlags, updateFlags);
3170 else
3171 SendImprovedTerseObjectUpdate(obj, creatorFlags, updateFlags);
3172 }
3173
3174 void SendFullObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3175 {
3176 IClientAPI owner;
3177 if (m_scene.ClientManager.TryGetValue(obj.OwnerID, out owner) && owner is LLClientView)
3178 {
3179 LLClientView llOwner = (LLClientView)owner;
3180
3181 // Send an update out to the owner
3182 ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket();
3183 updateToOwner.RegionData.RegionHandle = obj.RegionHandle;
3184 //updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue);
3185 updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3186 updateToOwner.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags | creatorFlags | PrimFlags.ObjectYouOwner, 0);
3187
3188 m_udpServer.SendPacket(llOwner.UDPClient, updateToOwner, ThrottleOutPacketType.State, true);
3189 }
3190
3191 // Send an update out to everyone else
3192 ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket();
3193 updateToOthers.RegionData.RegionHandle = obj.RegionHandle;
3194 //updateToOthers.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue);
3195 updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3196 updateToOthers.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags, 0);
3197
3198 m_scene.ClientManager.ForEach(
3199 delegate(IClientAPI client)
3200 {
3201 if (client.AgentId != obj.OwnerID && client is LLClientView)
3202 {
3203 LLClientView llClient = (LLClientView)client;
3204 m_udpServer.SendPacket(llClient.UDPClient, updateToOthers, ThrottleOutPacketType.State, true);
3205 }
3206 }
3207 );
3208 }
3209
3210 void SendObjectUpdateCompressed(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3211 {
3212 }
3213
3214 void SendImprovedTerseObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags)
3215 {
3216 }
3217
3218 void UpdateFlagsToPacketType(PrimFlags creatorFlags, PrimUpdateFlags updateFlags, out bool canUseCompressed, out bool canUseImproved)
3219 {
3220 canUseCompressed = true;
3221 canUseImproved = true;
3222
3223 if ((updateFlags & PrimUpdateFlags.FullUpdate) == PrimUpdateFlags.FullUpdate || creatorFlags != PrimFlags.None)
3224 {
3225 canUseCompressed = false;
3226 canUseImproved = false;
3227 }
3228 else
3229 {
3230 if ((updateFlags & PrimUpdateFlags.Velocity) != 0 ||
3231 (updateFlags & PrimUpdateFlags.Acceleration) != 0 ||
3232 (updateFlags & PrimUpdateFlags.CollisionPlane) != 0 ||
3233 (updateFlags & PrimUpdateFlags.Joint) != 0)
3234 {
3235 canUseCompressed = false;
3236 }
3237
3238 if ((updateFlags & PrimUpdateFlags.PrimFlags) != 0 ||
3239 (updateFlags & PrimUpdateFlags.ParentID) != 0 ||
3240 (updateFlags & PrimUpdateFlags.Scale) != 0 ||
3241 (updateFlags & PrimUpdateFlags.PrimData) != 0 ||
3242 (updateFlags & PrimUpdateFlags.Text) != 0 ||
3243 (updateFlags & PrimUpdateFlags.NameValue) != 0 ||
3244 (updateFlags & PrimUpdateFlags.ExtraData) != 0 ||
3245 (updateFlags & PrimUpdateFlags.TextureAnim) != 0 ||
3246 (updateFlags & PrimUpdateFlags.Sound) != 0 ||
3247 (updateFlags & PrimUpdateFlags.Particles) != 0 ||
3248 (updateFlags & PrimUpdateFlags.Material) != 0 ||
3249 (updateFlags & PrimUpdateFlags.ClickAction) != 0 ||
3250 (updateFlags & PrimUpdateFlags.MediaURL) != 0 ||
3251 (updateFlags & PrimUpdateFlags.Joint) != 0)
3252 {
3253 canUseImproved = false;
3254 }
3255 }
3256 }
3257
3258 static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlockFromPrim(SceneObjectPart prim, UUID assetID, PrimFlags flags, uint crc)
3259 {
3260 byte[] objectData = new byte[60];
3261 prim.OffsetPosition.ToBytes(objectData, 0);
3262 prim.Velocity.ToBytes(objectData, 12);
3263 prim.Acceleration.ToBytes(objectData, 24);
3264 prim.RotationOffset.ToBytes(objectData, 36);
3265 prim.AngularVelocity.ToBytes(objectData, 48);
3266
3267 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
3268 update.ClickAction = (byte)prim.ClickAction;
3269 update.CRC = crc;
3270 update.ExtraParams = prim.Shape.ExtraParams ?? Utils.EmptyBytes;
3271 update.Flags = (byte)flags;
3272 update.FullID = prim.UUID;
3273 update.ID = prim.LocalId;
3274 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
3275 //update.JointPivot = Vector3.Zero;
3276 //update.JointType = 0;
3277 update.Material = prim.Material;
3278 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
3279 if (prim.IsAttachment)
3280 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + assetID);
3281 else
3282 update.NameValue = Utils.EmptyBytes;
3283 update.ObjectData = objectData;
3284 update.ParentID = prim.ParentID;
3285 update.PathBegin = prim.Shape.PathBegin;
3286 update.PathCurve = prim.Shape.PathCurve;
3287 update.PathEnd = prim.Shape.PathEnd;
3288 update.PathRadiusOffset = prim.Shape.PathRadiusOffset;
3289 update.PathRevolutions = prim.Shape.PathRevolutions;
3290 update.PathScaleX = prim.Shape.PathScaleX;
3291 update.PathScaleY = prim.Shape.PathScaleY;
3292 update.PathShearX = prim.Shape.PathShearX;
3293 update.PathShearY = prim.Shape.PathShearY;
3294 update.PathSkew = prim.Shape.PathSkew;
3295 update.PathTaperX = prim.Shape.PathTaperX;
3296 update.PathTaperY = prim.Shape.PathTaperY;
3297 update.PathTwist = prim.Shape.PathTwist;
3298 update.PathTwistBegin = prim.Shape.PathTwistBegin;
3299 update.PCode = prim.Shape.PCode;
3300 update.ProfileBegin = prim.Shape.ProfileBegin;
3301 update.ProfileCurve = prim.Shape.ProfileCurve;
3302 update.ProfileEnd = prim.Shape.ProfileEnd;
3303 update.ProfileHollow = prim.Shape.ProfileHollow;
3304 update.PSBlock = prim.ParticleSystem ?? Utils.EmptyBytes;
3305 update.TextColor = new Color4(prim.Color).GetBytes(true);
3306 update.TextureAnim = prim.TextureAnimation ?? Utils.EmptyBytes;
3307 update.TextureEntry = prim.Shape.TextureEntry ?? Utils.EmptyBytes;
3308 update.Scale = prim.Scale;
3309 update.State = prim.Shape.State;
3310 update.Text = Util.StringToBytes256(prim.Text);
3311 update.UpdateFlags = (uint)flags;
3312
3313 if (prim.Sound != UUID.Zero)
3314 {
3315 update.Sound = prim.Sound;
3316 update.OwnerID = prim.OwnerID;
3317 update.Gain = (float)prim.SoundGain;
3318 update.Radius = (float)prim.SoundRadius;
3319 }
3320
3321 switch ((PCode)prim.Shape.PCode)
3322 {
3323 case PCode.Grass:
3324 case PCode.Tree:
3325 case PCode.NewTree:
3326 update.Data = new byte[] { prim.Shape.State };
3327 break;
3328 default:
3329 // TODO: Support ScratchPad
3330 //if (prim.ScratchPad != null)
3331 //{
3332 // update.Data = new byte[prim.ScratchPad.Length];
3333 // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length);
3334 //}
3335 //else
3336 //{
3337 // update.Data = Utils.EmptyBytes;
3338 //}
3339 update.Data = Utils.EmptyBytes;
3340 break;
3341 }
3342
3343 return update;
3344 }*/
3345
3346 #endregion Prim/Avatar Updates
3347
3162 #region Avatar Packet/data sending Methods 3348 #region Avatar Packet/data sending Methods
3163 3349
3164 /// <summary> 3350 /// <summary>
3165 /// send a objectupdate packet with information about the clients avatar 3351 /// send a objectupdate packet with information about the clients avatar
3166 /// </summary> 3352 /// </summary>
3167 public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, 3353 public void SendAvatarData(SendAvatarData data)
3168 uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation)
3169 { 3354 {
3170 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3355 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3171 // TODO: don't create new blocks if recycling an old packet 3356 // TODO: don't create new blocks if recycling an old packet
3172 objupdate.RegionData.RegionHandle = regionHandle; 3357 objupdate.RegionData.RegionHandle = data.regionHandle;
3173 objupdate.RegionData.TimeDilation = ushort.MaxValue; 3358 objupdate.RegionData.TimeDilation = ushort.MaxValue;
3174 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3359 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3175 objupdate.ObjectData[0] = CreateDefaultAvatarPacket(textureEntry); 3360 objupdate.ObjectData[0] = CreateDefaultAvatarPacket(data.textureEntry);
3176 3361
3177 //give this avatar object a local id and assign the user a name 3362 //give this avatar object a local id and assign the user a name
3178 objupdate.ObjectData[0].ID = avatarLocalID; 3363 objupdate.ObjectData[0].ID = data.avatarLocalID;
3179 objupdate.ObjectData[0].FullID = avatarID; 3364 objupdate.ObjectData[0].FullID = data.avatarID;
3180 objupdate.ObjectData[0].ParentID = parentID; 3365 objupdate.ObjectData[0].ParentID = data.parentID;
3181 objupdate.ObjectData[0].NameValue = 3366 objupdate.ObjectData[0].NameValue =
3182 Utils.StringToBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + "\nTitle STRING RW SV " + grouptitle); 3367 Utils.StringToBytes("FirstName STRING RW SV " + data.firstName + "\nLastName STRING RW SV " + data.lastName + "\nTitle STRING RW SV " + data.grouptitle);
3183 3368
3184 Vector3 pos2 = new Vector3(Pos.X, Pos.Y, Pos.Z); 3369 Vector3 pos2 = new Vector3(data.Pos.X, data.Pos.Y, data.Pos.Z);
3185 byte[] pb = pos2.GetBytes(); 3370 byte[] pb = pos2.GetBytes();
3186 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); 3371 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
3187 3372
3188 byte[] rot = rotation.GetBytes(); 3373 byte[] rot = data.rotation.GetBytes();
3189 Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length); 3374 Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length);
3190 3375
3191 objupdate.Header.Zerocoded = true; 3376 objupdate.Header.Zerocoded = true;
@@ -3196,38 +3381,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3196 /// Send a terse positional/rotation/velocity update about an avatar 3381 /// Send a terse positional/rotation/velocity update about an avatar
3197 /// to the client. This avatar can be that of the client itself. 3382 /// to the client. This avatar can be that of the client itself.
3198 /// </summary> 3383 /// </summary>
3199 public virtual void SendAvatarTerseUpdate(ulong regionHandle, 3384 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
3200 ushort timeDilation, uint localID, Vector3 position,
3201 Vector3 velocity, Quaternion rotation, UUID agentid)
3202 { 3385 {
3386 if (data.priority == double.NaN)
3387 {
3388 m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update");
3389 return;
3390 }
3391
3392 Quaternion rotation = data.rotation;
3393
3203 if (rotation.X == rotation.Y && 3394 if (rotation.X == rotation.Y &&
3204 rotation.Y == rotation.Z && 3395 rotation.Y == rotation.Z &&
3205 rotation.Z == rotation.W && rotation.W == 0) 3396 rotation.Z == rotation.W && rotation.W == 0)
3206 rotation = Quaternion.Identity; 3397 rotation = Quaternion.Identity;
3207 3398
3208 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = 3399 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock =
3209 CreateAvatarImprovedBlock(localID, position, velocity,rotation); 3400 CreateAvatarImprovedBlock(data.localID, data.position, data.velocity, rotation);
3210 3401
3211 lock (m_avatarTerseUpdates) 3402 lock (m_avatarTerseUpdates.SyncRoot)
3212 { 3403 m_avatarTerseUpdates.Enqueue(data.priority, terseBlock, data.localID);
3213 m_avatarTerseUpdates.Add(terseBlock);
3214
3215 // If packet is full or own movement packet, send it.
3216 if (m_avatarTerseUpdates.Count >= m_avatarTerseUpdatesPerPacket)
3217 {
3218 ProcessAvatarTerseUpdates(this, null);
3219 }
3220 else if (m_avatarTerseUpdates.Count == 1)
3221 {
3222 lock (m_avatarTerseUpdateTimer)
3223 m_avatarTerseUpdateTimer.Start();
3224 }
3225 }
3226 } 3404 }
3227 3405
3228 private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e) 3406 private void ProcessAvatarTerseUpdates()
3229 { 3407 {
3230 lock (m_avatarTerseUpdates) 3408 lock (m_avatarTerseUpdates.SyncRoot)
3231 { 3409 {
3232 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 3410 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3233 3411
@@ -3247,34 +3425,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3247 byte[] zerobuffer = new byte[1024]; 3425 byte[] zerobuffer = new byte[1024];
3248 byte[] blockbuffer = new byte[1024]; 3426 byte[] blockbuffer = new byte[1024];
3249 3427
3428 Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> updates = new Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
3429
3250 for (count = 0 ; count < max ; count++) 3430 for (count = 0 ; count < max ; count++)
3251 { 3431 {
3252 int length = 0; 3432 int length = 0;
3253 m_avatarTerseUpdates[count].ToBytes(blockbuffer, ref length); 3433 m_avatarTerseUpdates.Peek().ToBytes(blockbuffer, ref length);
3254 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); 3434 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer);
3255 if (size + length > Packet.MTU) 3435 if (size + length > Packet.MTU)
3256 break; 3436 break;
3257 size += length; 3437 size += length;
3438 updates.Enqueue(m_avatarTerseUpdates.Dequeue());
3258 } 3439 }
3259 3440
3260 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; 3441 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
3261 3442
3262 for (int i = 0 ; i < count ; i++) 3443 for (int i = 0 ; i < count ; i++)
3263 { 3444 terse.ObjectData[i] = updates.Dequeue();
3264 terse.ObjectData[i] = m_avatarTerseUpdates[0];
3265 m_avatarTerseUpdates.RemoveAt(0);
3266 }
3267 3445
3268 terse.Header.Reliable = false; 3446 terse.Header.Reliable = false;
3269 terse.Header.Zerocoded = true; 3447 terse.Header.Zerocoded = true;
3270 // FIXME: Move this to ThrottleOutPacketType.State when the real prioritization code is committed
3271 OutPacket(terse, ThrottleOutPacketType.Task);
3272 3448
3273 if (m_avatarTerseUpdates.Count == 0) 3449 OutPacket(terse, ThrottleOutPacketType.State);
3274 {
3275 lock (m_avatarTerseUpdateTimer)
3276 m_avatarTerseUpdateTimer.Stop();
3277 }
3278 } 3450 }
3279 } 3451 }
3280 3452
@@ -3342,54 +3514,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3342 OutPacket(attach, ThrottleOutPacketType.Task); 3514 OutPacket(attach, ThrottleOutPacketType.Task);
3343 } 3515 }
3344 3516
3345 public void SendPrimitiveToClient( 3517 public void SendPrimitiveToClient(SendPrimitiveData data)
3346 ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
3347 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
3348 uint flags, UUID objectID, UUID ownerID, string text, byte[] color,
3349 uint parentID, byte[] particleSystem, byte clickAction, byte material)
3350 { 3518 {
3351 byte[] textureanim = new byte[0]; 3519 if (data.priority == double.NaN)
3352 3520 {
3353 SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, vel, 3521 m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update");
3354 acc, rotation, rvel, flags, 3522 return;
3355 objectID, ownerID, text, color, parentID, particleSystem, 3523 }
3356 clickAction, material, textureanim, false, 0, UUID.Zero, UUID.Zero, 0, 0, 0);
3357 }
3358 3524
3359 public void SendPrimitiveToClient( 3525 Quaternion rotation = data.rotation;
3360 ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
3361 Vector3 pos, Vector3 velocity, Vector3 acceleration, Quaternion rotation, Vector3 rotational_velocity,
3362 uint flags,
3363 UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem,
3364 byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundGain, byte SoundFlags, double SoundRadius)
3365 {
3366 3526
3367 if (AttachPoint > 30 && ownerID != AgentId) // Someone else's HUD 3527 if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD
3368 return; 3528 return;
3369 if (primShape.PCode == 9 && primShape.State != 0 && parentID == 0) 3529 if (data.primShape.PCode == 9 && data.primShape.State != 0 && data.parentID == 0)
3370 return; 3530 return;
3371 3531
3372 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) 3532 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0.0f)
3373 rotation = Quaternion.Identity; 3533 rotation = Quaternion.Identity;
3374 3534
3375 ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(primShape, flags); 3535 ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data.primShape, data.flags);
3376 3536
3377 objectData.ID = localID; 3537 objectData.ID = data.localID;
3378 objectData.FullID = objectID; 3538 objectData.FullID = data.objectID;
3379 objectData.OwnerID = ownerID; 3539 objectData.OwnerID = data.ownerID;
3380 3540
3381 objectData.Text = Util.StringToBytes256(text); 3541 objectData.Text = Util.StringToBytes256(data.text);
3382 objectData.TextColor[0] = color[0]; 3542 objectData.TextColor[0] = data.color[0];
3383 objectData.TextColor[1] = color[1]; 3543 objectData.TextColor[1] = data.color[1];
3384 objectData.TextColor[2] = color[2]; 3544 objectData.TextColor[2] = data.color[2];
3385 objectData.TextColor[3] = color[3]; 3545 objectData.TextColor[3] = data.color[3];
3386 objectData.ParentID = parentID; 3546 objectData.ParentID = data.parentID;
3387 objectData.PSBlock = particleSystem; 3547 objectData.PSBlock = data.particleSystem;
3388 objectData.ClickAction = clickAction; 3548 objectData.ClickAction = data.clickAction;
3389 objectData.Material = material; 3549 objectData.Material = data.material;
3390 objectData.Flags = 0; 3550 objectData.Flags = 0;
3391 3551
3392 if (attachment) 3552 if (data.attachment)
3393 { 3553 {
3394 // Necessary??? 3554 // Necessary???
3395 objectData.JointAxisOrAnchor = new Vector3(0, 0, 2); 3555 objectData.JointAxisOrAnchor = new Vector3(0, 0, 2);
@@ -3397,14 +3557,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3397 3557
3398 // Item from inventory??? 3558 // Item from inventory???
3399 objectData.NameValue = 3559 objectData.NameValue =
3400 Utils.StringToBytes("AttachItemID STRING RW SV " + AssetId.Guid); 3560 Utils.StringToBytes("AttachItemID STRING RW SV " + data.AssetId.Guid);
3401 objectData.State = (byte)((AttachPoint % 16) * 16 + (AttachPoint / 16)); 3561 objectData.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16));
3402 } 3562 }
3403 3563
3404 // Xantor 20080528: Send sound info as well 3564 // Xantor 20080528: Send sound info as well
3405 // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again 3565 // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again
3406 objectData.Sound = SoundId; 3566 objectData.Sound = data.SoundId;
3407 if (SoundId == UUID.Zero) 3567 if (data.SoundId == UUID.Zero)
3408 { 3568 {
3409 objectData.OwnerID = UUID.Zero; 3569 objectData.OwnerID = UUID.Zero;
3410 objectData.Gain = 0.0f; 3570 objectData.Gain = 0.0f;
@@ -3413,39 +3573,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3413 } 3573 }
3414 else 3574 else
3415 { 3575 {
3416 objectData.OwnerID = ownerID; 3576 objectData.OwnerID = data.ownerID;
3417 objectData.Gain = (float)SoundGain; 3577 objectData.Gain = (float)data.SoundVolume;
3418 objectData.Radius = (float)SoundRadius; 3578 objectData.Radius = (float)data.SoundRadius;
3419 objectData.Flags = SoundFlags; 3579 objectData.Flags = data.SoundFlags;
3420 } 3580 }
3421 3581
3422 byte[] pb = pos.GetBytes(); 3582 byte[] pb = data.pos.GetBytes();
3423 Array.Copy(pb, 0, objectData.ObjectData, 0, pb.Length); 3583 Buffer.BlockCopy(pb, 0, objectData.ObjectData, 0, pb.Length);
3424 3584
3425 byte[] vel = velocity.GetBytes(); 3585 byte[] vel = data.vel.GetBytes();
3426 Array.Copy(vel, 0, objectData.ObjectData, pb.Length, vel.Length); 3586 Buffer.BlockCopy(vel, 0, objectData.ObjectData, pb.Length, vel.Length);
3427 3587
3428 byte[] rot = rotation.GetBytes(); 3588 byte[] rot = rotation.GetBytes();
3429 Array.Copy(rot, 0, objectData.ObjectData, 36, rot.Length); 3589 Buffer.BlockCopy(rot, 0, objectData.ObjectData, 36, rot.Length);
3430 3590
3431 byte[] rvel = rotational_velocity.GetBytes(); 3591 byte[] rvel = data.rvel.GetBytes();
3432 Array.Copy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length); 3592 Buffer.BlockCopy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length);
3433 3593
3434 if (textureanim.Length > 0) 3594 if (data.textureanim.Length > 0)
3435 { 3595 {
3436 objectData.TextureAnim = textureanim; 3596 objectData.TextureAnim = data.textureanim;
3437 } 3597 }
3438 3598
3439 lock (m_primFullUpdates) 3599 lock (m_primFullUpdates.SyncRoot)
3440 { 3600 m_primFullUpdates.Enqueue(data.priority, objectData, data.localID);
3441 if (m_primFullUpdates.Count == 0)
3442 m_primFullUpdateTimer.Start();
3443
3444 m_primFullUpdates.Add(objectData);
3445
3446 if (m_primFullUpdates.Count >= m_primFullUpdatesPerPacket)
3447 ProcessPrimFullUpdates(this, null);
3448 }
3449 } 3601 }
3450 3602
3451 void HandleQueueEmpty(ThrottleOutPacketType queue) 3603 void HandleQueueEmpty(ThrottleOutPacketType queue)
@@ -3455,6 +3607,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3455 case ThrottleOutPacketType.Texture: 3607 case ThrottleOutPacketType.Texture:
3456 ProcessTextureRequests(); 3608 ProcessTextureRequests();
3457 break; 3609 break;
3610 case ThrottleOutPacketType.State:
3611 int count = 0;
3612
3613 lock (m_avatarTerseUpdates.SyncRoot)
3614 count = m_avatarTerseUpdates.Count;
3615 if (count > 0)
3616 {
3617 ProcessAvatarTerseUpdates();
3618 return;
3619 }
3620
3621 lock (m_primFullUpdates.SyncRoot)
3622 count = m_primFullUpdates.Count;
3623 if (count > 0)
3624 {
3625 ProcessPrimFullUpdates();
3626 return;
3627 }
3628
3629 lock (m_primTerseUpdates.SyncRoot)
3630 count = m_primTerseUpdates.Count;
3631 if (count > 0)
3632 {
3633 ProcessPrimTerseUpdates();
3634 return;
3635 }
3636 break;
3458 } 3637 }
3459 } 3638 }
3460 3639
@@ -3464,18 +3643,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3464 m_imageManager.ProcessImageQueue(m_textureSendLimit); 3643 m_imageManager.ProcessImageQueue(m_textureSendLimit);
3465 } 3644 }
3466 3645
3467 void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) 3646 void ProcessPrimFullUpdates()
3468 { 3647 {
3469 lock (m_primFullUpdates) 3648 lock (m_primFullUpdates.SyncRoot)
3470 { 3649 {
3471 if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled)
3472 {
3473 lock (m_primFullUpdateTimer)
3474 m_primFullUpdateTimer.Stop();
3475
3476 return;
3477 }
3478
3479 ObjectUpdatePacket outPacket = 3650 ObjectUpdatePacket outPacket =
3480 (ObjectUpdatePacket)PacketPool.Instance.GetPacket( 3651 (ObjectUpdatePacket)PacketPool.Instance.GetPacket(
3481 PacketType.ObjectUpdate); 3652 PacketType.ObjectUpdate);
@@ -3495,74 +3666,63 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3495 byte[] zerobuffer = new byte[1024]; 3666 byte[] zerobuffer = new byte[1024];
3496 byte[] blockbuffer = new byte[1024]; 3667 byte[] blockbuffer = new byte[1024];
3497 3668
3669 Queue<ObjectUpdatePacket.ObjectDataBlock> updates = new Queue<ObjectUpdatePacket.ObjectDataBlock>();
3670
3498 for (count = 0 ; count < max ; count++) 3671 for (count = 0 ; count < max ; count++)
3499 { 3672 {
3500 int length = 0; 3673 int length = 0;
3501 m_primFullUpdates[count].ToBytes(blockbuffer, ref length); 3674 m_primFullUpdates.Peek().ToBytes(blockbuffer, ref length);
3502 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); 3675 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer);
3503 if (size + length > Packet.MTU) 3676 if (size + length > Packet.MTU)
3504 break; 3677 break;
3505 size += length; 3678 size += length;
3679 updates.Enqueue(m_primFullUpdates.Dequeue());
3506 } 3680 }
3507 3681
3508 outPacket.ObjectData = 3682 outPacket.ObjectData =
3509 new ObjectUpdatePacket.ObjectDataBlock[count]; 3683 new ObjectUpdatePacket.ObjectDataBlock[count];
3510 3684
3511 for (int index = 0 ; index < count ; index++) 3685 for (int index = 0 ; index < count ; index++)
3512 { 3686 outPacket.ObjectData[index] = updates.Dequeue();
3513 outPacket.ObjectData[index] = m_primFullUpdates[0];
3514 m_primFullUpdates.RemoveAt(0);
3515 }
3516 3687
3517 outPacket.Header.Zerocoded = true; 3688 outPacket.Header.Zerocoded = true;
3518 OutPacket(outPacket, ThrottleOutPacketType.State); 3689 OutPacket(outPacket, ThrottleOutPacketType.State);
3519
3520 if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled)
3521 lock (m_primFullUpdateTimer)
3522 m_primFullUpdateTimer.Stop();
3523 } 3690 }
3524 } 3691 }
3525 3692
3526 /// <summary> 3693 /// <summary>
3527 /// 3694 ///
3528 /// </summary> 3695 /// </summary>
3529 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, 3696 //public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
3530 Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) 3697 // Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint)
3698 public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
3531 { 3699 {
3532 if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD 3700 if (data.priority == double.NaN)
3701 {
3702 m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update");
3703 return;
3704 }
3705
3706 Quaternion rotation = data.rotation;
3707
3708 if (data.attachPoint > 30 && data.owner != AgentId) // Someone else's HUD
3533 return; 3709 return;
3534 3710
3535 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) 3711 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0)
3536 rotation = Quaternion.Identity; 3712 rotation = Quaternion.Identity;
3537 3713
3538 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = 3714 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData =
3539 CreatePrimImprovedBlock(localID, position, rotation, 3715 CreatePrimImprovedBlock(data.localID, data.position, rotation,
3540 velocity, rotationalvelocity, state); 3716 data.velocity, data.rotationalvelocity, data.state);
3541 3717
3542 lock (m_primTerseUpdates) 3718 lock (m_primTerseUpdates.SyncRoot)
3543 { 3719 m_primTerseUpdates.Enqueue(data.priority, objectData, data.localID);
3544 if (m_primTerseUpdates.Count == 0)
3545 m_primTerseUpdateTimer.Start();
3546
3547 m_primTerseUpdates.Add(objectData);
3548
3549 if (m_primTerseUpdates.Count >= m_primTerseUpdatesPerPacket)
3550 ProcessPrimTerseUpdates(this, null);
3551 }
3552 } 3720 }
3553 3721
3554 void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e) 3722 void ProcessPrimTerseUpdates()
3555 { 3723 {
3556 lock (m_primTerseUpdates) 3724 lock (m_primTerseUpdates.SyncRoot)
3557 { 3725 {
3558 if (m_primTerseUpdates.Count == 0)
3559 {
3560 lock (m_primTerseUpdateTimer)
3561 m_primTerseUpdateTimer.Stop();
3562
3563 return;
3564 }
3565
3566 ImprovedTerseObjectUpdatePacket outPacket = 3726 ImprovedTerseObjectUpdatePacket outPacket =
3567 (ImprovedTerseObjectUpdatePacket) 3727 (ImprovedTerseObjectUpdatePacket)
3568 PacketPool.Instance.GetPacket( 3728 PacketPool.Instance.GetPacket(
@@ -3583,14 +3743,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3583 byte[] zerobuffer = new byte[1024]; 3743 byte[] zerobuffer = new byte[1024];
3584 byte[] blockbuffer = new byte[1024]; 3744 byte[] blockbuffer = new byte[1024];
3585 3745
3746 Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> updates = new Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
3747
3586 for (count = 0 ; count < max ; count++) 3748 for (count = 0 ; count < max ; count++)
3587 { 3749 {
3588 int length = 0; 3750 int length = 0;
3589 m_primTerseUpdates[count].ToBytes(blockbuffer, ref length); 3751 m_primTerseUpdates.Peek().ToBytes(blockbuffer, ref length);
3590 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); 3752 length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer);
3591 if (size + length > Packet.MTU) 3753 if (size + length > Packet.MTU)
3592 break; 3754 break;
3593 size += length; 3755 size += length;
3756 updates.Enqueue(m_primTerseUpdates.Dequeue());
3594 } 3757 }
3595 3758
3596 outPacket.ObjectData = 3759 outPacket.ObjectData =
@@ -3598,18 +3761,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3598 ObjectDataBlock[count]; 3761 ObjectDataBlock[count];
3599 3762
3600 for (int index = 0 ; index < count ; index++) 3763 for (int index = 0 ; index < count ; index++)
3601 { 3764 outPacket.ObjectData[index] = updates.Dequeue();
3602 outPacket.ObjectData[index] = m_primTerseUpdates[0];
3603 m_primTerseUpdates.RemoveAt(0);
3604 }
3605 3765
3606 outPacket.Header.Reliable = false; 3766 outPacket.Header.Reliable = false;
3607 outPacket.Header.Zerocoded = true; 3767 outPacket.Header.Zerocoded = true;
3608 OutPacket(outPacket, ThrottleOutPacketType.State); 3768 OutPacket(outPacket, ThrottleOutPacketType.State);
3609
3610 if (m_primTerseUpdates.Count == 0)
3611 lock (m_primTerseUpdateTimer)
3612 m_primTerseUpdateTimer.Stop();
3613 } 3769 }
3614 } 3770 }
3615 3771
@@ -3617,15 +3773,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3617 { 3773 {
3618 while (m_primFullUpdates.Count > 0) 3774 while (m_primFullUpdates.Count > 0)
3619 { 3775 {
3620 ProcessPrimFullUpdates(this, null); 3776 ProcessPrimFullUpdates();
3621 } 3777 }
3622 while (m_primTerseUpdates.Count > 0) 3778 while (m_primTerseUpdates.Count > 0)
3623 { 3779 {
3624 ProcessPrimTerseUpdates(this, null); 3780 ProcessPrimTerseUpdates();
3625 } 3781 }
3626 while (m_avatarTerseUpdates.Count > 0) 3782 while (m_avatarTerseUpdates.Count > 0)
3627 { 3783 {
3628 ProcessAvatarTerseUpdates(this, null); 3784 ProcessAvatarTerseUpdates();
3629 } 3785 }
3630 } 3786 }
3631 3787
@@ -10371,5 +10527,136 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10371 pack.TextureData.TextureID = textureID; 10527 pack.TextureData.TextureID = textureID;
10372 OutPacket(pack, ThrottleOutPacketType.Task); 10528 OutPacket(pack, ThrottleOutPacketType.Task);
10373 } 10529 }
10530
10531 #region PriorityQueue
10532 private class PriorityQueue<TPriority, TValue>
10533 {
10534 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1];
10535 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>();
10536 private Comparison<TPriority> comparison;
10537 private object sync_root = new object();
10538
10539 internal PriorityQueue() :
10540 this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<TPriority>.Default) { }
10541 internal PriorityQueue(int capacity) :
10542 this(capacity, Comparer<TPriority>.Default) { }
10543 internal PriorityQueue(IComparer<TPriority> comparer) :
10544 this(new Comparison<TPriority>(comparer.Compare)) { }
10545 internal PriorityQueue(Comparison<TPriority> comparison) :
10546 this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, comparison) { }
10547 internal PriorityQueue(int capacity, IComparer<TPriority> comparer) :
10548 this(capacity, new Comparison<TPriority>(comparer.Compare)) { }
10549 internal PriorityQueue(int capacity, Comparison<TPriority> comparison)
10550 {
10551 for (int i = 0; i < heaps.Length; ++i)
10552 heaps[i] = new MinHeap<MinHeapItem>(capacity);
10553 this.comparison = comparison;
10554 }
10555
10556 internal object SyncRoot { get { return this.sync_root; } }
10557 internal int Count
10558 {
10559 get
10560 {
10561 int count = 0;
10562 for (int i = 0; i < heaps.Length; ++i)
10563 count = heaps[i].Count;
10564 return count;
10565 }
10566 }
10567
10568 internal bool Enqueue(TPriority priority, TValue value, uint local_id)
10569 {
10570 LookupItem item;
10571
10572 if (lookup_table.TryGetValue(local_id, out item))
10573 {
10574 item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.comparison);
10575 return false;
10576 }
10577 else
10578 {
10579 item.Heap = heaps[0];
10580 item.Heap.Add(new MinHeapItem(priority, value, local_id, this.comparison), ref item.Handle);
10581 lookup_table.Add(local_id, item);
10582 return true;
10583 }
10584 }
10585
10586 internal TValue Peek()
10587 {
10588 for (int i = 0; i < heaps.Length; ++i)
10589 if (heaps[i].Count > 0)
10590 return heaps[i].Min().Value;
10591 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
10592 }
10593
10594 internal TValue Dequeue()
10595 {
10596 for (int i = 0; i < heaps.Length; ++i)
10597 {
10598 if (heaps[i].Count > 0)
10599 {
10600 MinHeapItem item = heaps[i].RemoveMin();
10601 lookup_table.Remove(item.LocalID);
10602 return item.Value;
10603 }
10604 }
10605 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
10606 }
10607
10608 #region MinHeapItem
10609 private struct MinHeapItem : IComparable<MinHeapItem>
10610 {
10611 private TPriority priority;
10612 private TValue value;
10613 private uint local_id;
10614 private Comparison<TPriority> comparison;
10615
10616 internal MinHeapItem(TPriority priority, TValue value, uint local_id) :
10617 this(priority, value, local_id, Comparer<TPriority>.Default) { }
10618 internal MinHeapItem(TPriority priority, TValue value, uint local_id, IComparer<TPriority> comparer) :
10619 this(priority, value, local_id, new Comparison<TPriority>(comparer.Compare)) { }
10620 internal MinHeapItem(TPriority priority, TValue value, uint local_id, Comparison<TPriority> comparison)
10621 {
10622 this.priority = priority;
10623 this.value = value;
10624 this.local_id = local_id;
10625 this.comparison = comparison;
10626 }
10627
10628 internal TPriority Priority { get { return this.priority; } }
10629 internal TValue Value { get { return this.value; } }
10630 internal uint LocalID { get { return this.local_id; } }
10631
10632 public override string ToString()
10633 {
10634 StringBuilder sb = new StringBuilder();
10635 sb.Append("[");
10636 if (this.priority != null)
10637 sb.Append(this.priority.ToString());
10638 sb.Append(",");
10639 if (this.value != null)
10640 sb.Append(this.value.ToString());
10641 sb.Append("]");
10642 return sb.ToString();
10643 }
10644
10645 public int CompareTo(MinHeapItem other)
10646 {
10647 return this.comparison(this.priority, other.priority);
10648 }
10649 }
10650 #endregion
10651
10652 #region LookupItem
10653 private struct LookupItem {
10654 internal MinHeap<MinHeapItem> Heap;
10655 internal IHandle Handle;
10656 }
10657 #endregion
10658 }
10659 #endregion
10660
10374 } 10661 }
10375} 10662}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index 4eee6b6..8c42ca4 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -170,7 +170,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
170 { 170 {
171 ThrottleOutPacketType type = (ThrottleOutPacketType)i; 171 ThrottleOutPacketType type = (ThrottleOutPacketType)i;
172 172
173 // Initialize the packet outboxes, where packets sit while they are waiting for tokens
173 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); 174 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
175 // Initialize the token buckets that control the throttling for each category
174 m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type)); 176 m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type));
175 } 177 }
176 178
@@ -293,36 +295,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP
293 int state = (int)((float)task * STATE_TASK_PERCENTAGE); 295 int state = (int)((float)task * STATE_TASK_PERCENTAGE);
294 task -= state; 296 task -= state;
295 297
296 int ceiling = Int32.MaxValue; 298 // Make sure none of the throttles are set below our packet MTU,
297 if (m_defaultThrottleRates.Total != 0) 299 // otherwise a throttle could become permanently clogged
298 { 300 resend = Math.Max(resend, Packet.MTU);
299 ceiling = m_defaultThrottleRates.Total; 301 land = Math.Max(land, Packet.MTU);
300 if (ceiling < Packet.MTU) ceiling = Packet.MTU; 302 wind = Math.Max(wind, Packet.MTU);
301 } 303 cloud = Math.Max(cloud, Packet.MTU);
302 304 task = Math.Max(task, Packet.MTU);
303 resend = Utils.Clamp(resend, Packet.MTU, ceiling); 305 texture = Math.Max(texture, Packet.MTU);
304 land = Utils.Clamp(land, Packet.MTU, ceiling); 306 asset = Math.Max(asset, Packet.MTU);
305 wind = Utils.Clamp(wind, Packet.MTU, ceiling); 307 state = Math.Max(state, Packet.MTU);
306 cloud = Utils.Clamp(cloud, Packet.MTU, ceiling);
307 task = Utils.Clamp(task, Packet.MTU, ceiling);
308 texture = Utils.Clamp(texture, Packet.MTU, ceiling);
309 asset = Utils.Clamp(asset, Packet.MTU, ceiling);
310 state = Utils.Clamp(state, Packet.MTU, ceiling);
311 308
312 int total = resend + land + wind + cloud + task + texture + asset + state; 309 int total = resend + land + wind + cloud + task + texture + asset + state;
313 int taskTotal = task + state;
314 310
315 m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, Total={9}", 311 m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, Total={9}",
316 AgentID, resend, land, wind, cloud, task, texture, asset, state, total); 312 AgentID, resend, land, wind, cloud, task, texture, asset, state, total);
317 313
318 SetThrottle(ThrottleOutPacketType.Resend, resend, resend); 314 // Update the token buckets with new throttle values
319 SetThrottle(ThrottleOutPacketType.Land, land, land); 315 TokenBucket bucket;
320 SetThrottle(ThrottleOutPacketType.Wind, wind, wind); 316
321 SetThrottle(ThrottleOutPacketType.Cloud, cloud, cloud); 317 bucket = m_throttle;
322 SetThrottle(ThrottleOutPacketType.Task, task, taskTotal); 318 bucket.MaxBurst = total;
323 SetThrottle(ThrottleOutPacketType.Texture, texture, texture); 319
324 SetThrottle(ThrottleOutPacketType.Asset, asset, asset); 320 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend];
325 SetThrottle(ThrottleOutPacketType.State, state, taskTotal); 321 bucket.DripRate = bucket.MaxBurst = resend;
322
323 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land];
324 bucket.DripRate = bucket.MaxBurst = land;
325
326 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind];
327 bucket.DripRate = bucket.MaxBurst = wind;
328
329 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud];
330 bucket.DripRate = bucket.MaxBurst = cloud;
331
332 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset];
333 bucket.DripRate = bucket.MaxBurst = asset;
334
335 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task];
336 bucket.DripRate = task + state + texture;
337 bucket.MaxBurst = task + state + texture;
338
339 bucket = m_throttleCategories[(int)ThrottleOutPacketType.State];
340 bucket.DripRate = state + texture;
341 bucket.MaxBurst = state + texture;
342
343 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture];
344 bucket.DripRate = texture;
345 bucket.MaxBurst = texture;
326 } 346 }
327 347
328 public byte[] GetThrottlesPacked() 348 public byte[] GetThrottlesPacked()
@@ -342,17 +362,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
342 return data; 362 return data;
343 } 363 }
344 364
345 public void SetThrottle(ThrottleOutPacketType category, int rate, int maxBurst)
346 {
347 int i = (int)category;
348 if (i >= 0 && i < m_throttleCategories.Length)
349 {
350 TokenBucket bucket = m_throttleCategories[(int)category];
351 bucket.DripRate = rate;
352 bucket.MaxBurst = maxBurst;
353 }
354 }
355
356 public bool EnqueueOutgoing(OutgoingPacket packet) 365 public bool EnqueueOutgoing(OutgoingPacket packet)
357 { 366 {
358 int category = (int)packet.Category; 367 int category = (int)packet.Category;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 545a0bc..b11a80d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -285,7 +285,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
285 // The packet grew larger than the bufferSize while zerocoding. 285 // The packet grew larger than the bufferSize while zerocoding.
286 // Remove the MSG_ZEROCODED flag and send the unencoded data 286 // Remove the MSG_ZEROCODED flag and send the unencoded data
287 // instead 287 // instead
288 m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". Removing MSG_ZEROCODED flag"); 288 m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". DataLength=" + dataLength +
289 " and BufferLength=" + buffer.Data.Length + ". Removing MSG_ZEROCODED flag");
289 data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); 290 data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED);
290 Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); 291 Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
291 } 292 }
@@ -513,7 +514,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
513 IClientAPI client; 514 IClientAPI client;
514 if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView)) 515 if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView))
515 { 516 {
516 m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + 517 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address +
517 " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients"); 518 " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients");
518 return; 519 return;
519 } 520 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 66a9b5a..cd59bdb 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -224,11 +224,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
224 224
225 foreach (Scene s in m_scenes) 225 foreach (Scene s in m_scenes)
226 { 226 {
227 s.ForEachScenePresence(delegate(ScenePresence presence) 227 s.ForEachScenePresence(
228 { 228 delegate(ScenePresence presence)
229 TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, 229 {
230 c.Type, message, sourceType); 230 TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType);
231 }); 231 }
232 );
232 } 233 }
233 } 234 }
234 235
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 4896edf..3bb162e 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -756,7 +756,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
756 756
757 public void sendRegionHandshakeToAll() 757 public void sendRegionHandshakeToAll()
758 { 758 {
759 m_scene.Broadcast(sendRegionHandshake); 759 m_scene.ForEachClient(sendRegionHandshake);
760 } 760 }
761 761
762 public void handleEstateChangeInfo(IClientAPI remoteClient, UUID invoice, UUID senderID, UInt32 parms1, UInt32 parms2) 762 public void handleEstateChangeInfo(IClientAPI remoteClient, UUID invoice, UUID senderID, UInt32 parms1, UInt32 parms2)
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index d2b5cb1..332d3ce 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -1061,7 +1061,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1061 { 1061 {
1062 land.LandData.OwnerID = ownerID; 1062 land.LandData.OwnerID = ownerID;
1063 1063
1064 m_scene.Broadcast(SendParcelOverlay); 1064 m_scene.ForEachClient(SendParcelOverlay);
1065 land.SendLandUpdateToClient(remote_client); 1065 land.SendLandUpdateToClient(remote_client);
1066 } 1066 }
1067 } 1067 }
@@ -1083,7 +1083,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1083 land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 1083 land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
1084 else 1084 else
1085 land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; 1085 land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID;
1086 m_scene.Broadcast(SendParcelOverlay); 1086 m_scene.ForEachClient(SendParcelOverlay);
1087 land.SendLandUpdateToClient(remote_client); 1087 land.SendLandUpdateToClient(remote_client);
1088 } 1088 }
1089 } 1089 }
@@ -1107,7 +1107,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1107 land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; 1107 land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID;
1108 land.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 1108 land.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
1109 land.LandData.IsGroupOwned = false; 1109 land.LandData.IsGroupOwned = false;
1110 m_scene.Broadcast(SendParcelOverlay); 1110 m_scene.ForEachClient(SendParcelOverlay);
1111 land.SendLandUpdateToClient(remote_client); 1111 land.SendLandUpdateToClient(remote_client);
1112 } 1112 }
1113 } 1113 }
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index d651fd4..3799a02 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -499,13 +499,11 @@ namespace OpenSim.Region.Examples.SimpleModule
499 { 499 {
500 } 500 }
501 501
502 public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, 502 public virtual void SendAvatarData(SendAvatarData data)
503 uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation)
504 { 503 {
505 } 504 }
506 505
507 public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, 506 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
508 Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentid)
509 { 507 {
510 } 508 }
511 509
@@ -521,27 +519,11 @@ namespace OpenSim.Region.Examples.SimpleModule
521 { 519 {
522 } 520 }
523 521
524 public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, 522 public virtual void SendPrimitiveToClient(SendPrimitiveData data)
525 PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel,
526 Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags,
527 UUID objectID, UUID ownerID, string text, byte[] color,
528 uint parentID,
529 byte[] particleSystem, byte clickAction, byte material)
530 { 523 {
531 } 524 }
532 public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, 525
533 PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, 526 public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data)
534 Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags,
535 UUID objectID, UUID ownerID, string text, byte[] color,
536 uint parentID,
537 byte[] particleSystem, byte clickAction, byte material, byte[] textureanimation,
538 bool attachment, uint AttachmentPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius)
539 {
540 }
541 public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID,
542 Vector3 position, Quaternion rotation, Vector3 velocity,
543 Vector3 rotationalvelocity, byte state, UUID AssetId,
544 UUID ownerID, int attachPoint)
545 { 527 {
546 } 528 }
547 529
diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
index 8e3f4a0..7251d57 100644
--- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
+++ b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
@@ -34,7 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces
34 { 34 {
35 void Reset(); 35 void Reset();
36 void Close(); 36 void Close();
37 int MaxPrimsPerFrame { get; set; }
38 void QueuePartForUpdate(SceneObjectPart part); 37 void QueuePartForUpdate(SceneObjectPart part);
39 void SendPrimUpdates(); 38 void SendPrimUpdates();
40 } 39 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 29d2a84..49c1ebf 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -57,6 +57,12 @@ namespace OpenSim.Region.Framework.Scenes
57 57
58 public partial class Scene : SceneBase 58 public partial class Scene : SceneBase
59 { 59 {
60 public enum UpdatePrioritizationSchemes {
61 Time = 0,
62 Distance = 1,
63 SimpleAngularDistance = 2,
64 }
65
60 public delegate void SynchronizeSceneHandler(Scene scene); 66 public delegate void SynchronizeSceneHandler(Scene scene);
61 public SynchronizeSceneHandler SynchronizeScene = null; 67 public SynchronizeSceneHandler SynchronizeScene = null;
62 68
@@ -269,9 +275,10 @@ namespace OpenSim.Region.Framework.Scenes
269 private volatile bool shuttingdown = false; 275 private volatile bool shuttingdown = false;
270 276
271 private int m_lastUpdate = Environment.TickCount; 277 private int m_lastUpdate = Environment.TickCount;
272 private int m_maxPrimsPerFrame = 200;
273 private bool m_firstHeartbeat = true; 278 private bool m_firstHeartbeat = true;
274 279
280 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
281
275 private object m_deleting_scene_object = new object(); 282 private object m_deleting_scene_object = new object();
276 283
277 // the minimum time that must elapse before a changed object will be considered for persisted 284 // the minimum time that must elapse before a changed object will be considered for persisted
@@ -283,6 +290,8 @@ namespace OpenSim.Region.Framework.Scenes
283 290
284 #region Properties 291 #region Properties
285 292
293 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } }
294
286 public AgentCircuitManager AuthenticateHandler 295 public AgentCircuitManager AuthenticateHandler
287 { 296 {
288 get { return m_authenticateHandler; } 297 get { return m_authenticateHandler; }
@@ -327,12 +336,6 @@ namespace OpenSim.Region.Framework.Scenes
327 get { return m_sceneGraph.m_syncRoot; } 336 get { return m_sceneGraph.m_syncRoot; }
328 } 337 }
329 338
330 public int MaxPrimsPerFrame
331 {
332 get { return m_maxPrimsPerFrame; }
333 set { m_maxPrimsPerFrame = value; }
334 }
335
336 /// <summary> 339 /// <summary>
337 /// This is for llGetRegionFPS 340 /// This is for llGetRegionFPS
338 /// </summary> 341 /// </summary>
@@ -510,7 +513,6 @@ namespace OpenSim.Region.Framework.Scenes
510 513
511 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine"); 514 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine");
512 515
513 m_maxPrimsPerFrame = startupConfig.GetInt("MaxPrimsPerFrame", 200);
514 IConfig packetConfig = m_config.Configs["PacketPool"]; 516 IConfig packetConfig = m_config.Configs["PacketPool"];
515 if (packetConfig != null) 517 if (packetConfig != null)
516 { 518 {
@@ -519,6 +521,30 @@ namespace OpenSim.Region.Framework.Scenes
519 } 521 }
520 522
521 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 523 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
524
525 IConfig interest_management_config = m_config.Configs["InterestManagement"];
526 if (interest_management_config != null)
527 {
528 string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
529 switch (update_prioritization_scheme)
530 {
531 case "time":
532 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
533 break;
534 case "distance":
535 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance;
536 break;
537 case "simpleangulardistance":
538 m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance;
539 break;
540 default:
541 m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time");
542 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
543 break;
544 }
545 }
546
547 m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme");
522 } 548 }
523 catch 549 catch
524 { 550 {
@@ -1200,15 +1226,6 @@ namespace OpenSim.Region.Framework.Scenes
1200 } 1226 }
1201 1227
1202 /// <summary> 1228 /// <summary>
1203 /// Perform delegate action on all clients subscribing to updates from this region.
1204 /// </summary>
1205 /// <returns></returns>
1206 public void Broadcast(Action<IClientAPI> whatToDo)
1207 {
1208 ForEachScenePresence(delegate(ScenePresence presence) { whatToDo(presence.ControllingClient); });
1209 }
1210
1211 /// <summary>
1212 /// Backup the scene. This acts as the main method of the backup thread. 1229 /// Backup the scene. This acts as the main method of the backup thread.
1213 /// </summary> 1230 /// </summary>
1214 /// <returns></returns> 1231 /// <returns></returns>
@@ -3054,17 +3071,13 @@ namespace OpenSim.Region.Framework.Scenes
3054 } 3071 }
3055 3072
3056 m_eventManager.TriggerOnRemovePresence(agentID); 3073 m_eventManager.TriggerOnRemovePresence(agentID);
3057 Broadcast(delegate(IClientAPI client) 3074 ForEachClient(
3058 { 3075 delegate(IClientAPI client)
3059 try 3076 {
3060 { 3077 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3061 client.SendKillObject(avatar.RegionHandle, avatar.LocalId); 3078 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); }
3062 } 3079 catch (NullReferenceException) { }
3063 catch (NullReferenceException) 3080 });
3064 {
3065 //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
3066 }
3067 });
3068 3081
3069 ForEachScenePresence( 3082 ForEachScenePresence(
3070 delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); 3083 delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
@@ -3149,7 +3162,7 @@ namespace OpenSim.Region.Framework.Scenes
3149 return; 3162 return;
3150 } 3163 }
3151 } 3164 }
3152 Broadcast(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); 3165 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3153 } 3166 }
3154 3167
3155 #endregion 3168 #endregion
@@ -4222,7 +4235,7 @@ namespace OpenSim.Region.Framework.Scenes
4222 4235
4223 public void ForEachClient(Action<IClientAPI> action) 4236 public void ForEachClient(Action<IClientAPI> action)
4224 { 4237 {
4225 m_sceneGraph.ForEachClient(action); 4238 ClientManager.ForEach(action);
4226 } 4239 }
4227 4240
4228 public void ForEachSOG(Action<SceneObjectGroup> action) 4241 public void ForEachSOG(Action<SceneObjectGroup> action)
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 9cd2247..b9872ca 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -613,7 +613,6 @@ namespace OpenSim.Region.Framework.Scenes
613 613
614 newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance); 614 newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance);
615 newAvatar.IsChildAgent = true; 615 newAvatar.IsChildAgent = true;
616 newAvatar.MaxPrimsPerFrame = m_parentScene.MaxPrimsPerFrame;
617 616
618 AddScenePresence(newAvatar); 617 AddScenePresence(newAvatar);
619 618
@@ -1107,23 +1106,6 @@ namespace OpenSim.Region.Framework.Scenes
1107 return UUID.Zero; 1106 return UUID.Zero;
1108 } 1107 }
1109 1108
1110 protected internal void ForEachClient(Action<IClientAPI> action)
1111 {
1112 List<ScenePresence> splist = GetScenePresences();
1113 foreach (ScenePresence presence in splist)
1114 {
1115 try
1116 {
1117 action(presence.ControllingClient);
1118 }
1119 catch (Exception e)
1120 {
1121 // Catch it and move on. This includes situations where splist has inconsistent info
1122 m_log.WarnFormat("[SCENE]: Problem processing action in ForEachClient: ", e.Message);
1123 }
1124 }
1125 }
1126
1127 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1109 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1128 { 1110 {
1129 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1111 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index d4cef7d..2153b9b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1817,7 +1817,7 @@ namespace OpenSim.Region.Framework.Scenes
1817 public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) 1817 public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags)
1818 { 1818 {
1819 1819
1820 remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.ObjectOwner, RootPart.GroupID, RootPart.BaseMask, 1820 remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask,
1821 RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, 1821 RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask,
1822 RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, 1822 RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category,
1823 RootPart.CreatorID, RootPart.Name, RootPart.Description); 1823 RootPart.CreatorID, RootPart.Name, RootPart.Description);
@@ -3343,5 +3343,77 @@ namespace OpenSim.Region.Framework.Scenes
3343 3343
3344 return true; 3344 return true;
3345 } 3345 }
3346
3347 public double GetUpdatePriority(IClientAPI client)
3348 {
3349 switch (Scene.UpdatePrioritizationScheme)
3350 {
3351 case Scene.UpdatePrioritizationSchemes.Time:
3352 return GetPriorityByTime();
3353 case Scene.UpdatePrioritizationSchemes.Distance:
3354 return GetPriorityByDistance(client);
3355 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3356 return GetPriorityBySimpleAngularDistance(client);
3357 default:
3358 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3359 }
3360 }
3361
3362 private double GetPriorityByTime()
3363 {
3364 return DateTime.Now.ToOADate();
3365 }
3366
3367 private double GetPriorityByDistance(IClientAPI client)
3368 {
3369 ScenePresence presence = Scene.GetScenePresence(client.AgentId);
3370 if (presence != null)
3371 {
3372 return GetPriorityByDistance((presence.IsChildAgent) ?
3373 presence.AbsolutePosition : presence.CameraPosition);
3374 }
3375 return double.NaN;
3376 }
3377
3378 private double GetPriorityBySimpleAngularDistance(IClientAPI client)
3379 {
3380 ScenePresence presence = Scene.GetScenePresence(client.AgentId);
3381 if (presence != null)
3382 {
3383 return GetPriorityBySimpleAngularDistance((presence.IsChildAgent) ?
3384 presence.AbsolutePosition : presence.CameraPosition);
3385 }
3386 return double.NaN;
3387 }
3388
3389 public double GetPriorityByDistance(Vector3 position)
3390 {
3391 return Vector3.Distance(AbsolutePosition, position);
3392 }
3393
3394 public double GetPriorityBySimpleAngularDistance(Vector3 position)
3395 {
3396 double distance = Vector3.Distance(position, AbsolutePosition);
3397 if (distance >= double.Epsilon)
3398 {
3399 float height;
3400 Vector3 box = GetAxisAlignedBoundingBox(out height);
3401
3402 double angle = box.X / distance;
3403 double max = angle;
3404
3405 angle = box.Y / distance;
3406 if (max < angle)
3407 max = angle;
3408
3409 angle = box.Z / distance;
3410 if (max < angle)
3411 max = angle;
3412
3413 return -max;
3414 }
3415 else
3416 return double.MinValue;
3417 }
3346 } 3418 }
3347} 3419}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 801a7db..79f6366 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -853,16 +853,6 @@ if (m_shape != null) {
853 return m_offsetPosition + m_groupPosition; } 853 return m_offsetPosition + m_groupPosition; }
854 } 854 }
855 855
856 public UUID ObjectCreator
857 {
858 get { return _creatorID; }
859 }
860
861 public UUID ObjectOwner
862 {
863 get { return _ownerID; }
864 }
865
866 public SceneObjectGroup ParentGroup 856 public SceneObjectGroup ParentGroup
867 { 857 {
868 get { return m_parentGroup; } 858 get { return m_parentGroup; }
@@ -1440,7 +1430,7 @@ if (m_shape != null) {
1440 // Move afterwards ResetIDs as it clears the localID 1430 // Move afterwards ResetIDs as it clears the localID
1441 dupe.LocalId = localID; 1431 dupe.LocalId = localID;
1442 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1432 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1443 dupe._lastOwnerID = ObjectOwner; 1433 dupe._lastOwnerID = OwnerID;
1444 1434
1445 byte[] extraP = new byte[Shape.ExtraParams.Length]; 1435 byte[] extraP = new byte[Shape.ExtraParams.Length];
1446 Array.Copy(Shape.ExtraParams, extraP, extraP.Length); 1436 Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
@@ -2410,10 +2400,10 @@ if (m_shape != null) {
2410 //isattachment = ParentGroup.RootPart.IsAttachment; 2400 //isattachment = ParentGroup.RootPart.IsAttachment;
2411 2401
2412 byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; 2402 byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A};
2413 remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, 2403 remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape,
2414 lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, 2404 lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID,
2415 m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, 2405 m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment,
2416 AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius); 2406 AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient)));
2417 } 2407 }
2418 2408
2419 /// <summary> 2409 /// <summary>
@@ -3804,12 +3794,12 @@ if (m_shape != null) {
3804 3794
3805 // Causes this thread to dig into the Client Thread Data. 3795 // Causes this thread to dig into the Client Thread Data.
3806 // Remember your locking here! 3796 // Remember your locking here!
3807 remoteClient.SendPrimTerseUpdate(m_regionHandle, 3797 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle,
3808 (ushort)(m_parentGroup.GetTimeDilation() * 3798 (ushort)(m_parentGroup.GetTimeDilation() *
3809 (float)ushort.MaxValue), LocalId, lPos, 3799 (float)ushort.MaxValue), LocalId, lPos,
3810 RotationOffset, Velocity, 3800 RotationOffset, Velocity,
3811 RotationalVelocity, state, FromItemID, 3801 RotationalVelocity, state, FromItemID,
3812 OwnerID, (int)AttachmentPoint); 3802 OwnerID, (int)AttachmentPoint, ParentGroup.GetUpdatePriority(remoteClient)));
3813 } 3803 }
3814 3804
3815 public void AddScriptLPS(int count) 3805 public void AddScriptLPS(int count)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index b468dde..973537e 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -403,12 +403,6 @@ namespace OpenSim.Region.Framework.Scenes
403 set { m_parentPosition = value; } 403 set { m_parentPosition = value; }
404 } 404 }
405 405
406 public int MaxPrimsPerFrame
407 {
408 get { return m_sceneViewer.MaxPrimsPerFrame; }
409 set { m_sceneViewer.MaxPrimsPerFrame = value; }
410 }
411
412 /// <summary> 406 /// <summary>
413 /// Absolute position of this avatar in 'region cordinates' 407 /// Absolute position of this avatar in 'region cordinates'
414 /// </summary> 408 /// </summary>
@@ -2456,11 +2450,10 @@ namespace OpenSim.Region.Framework.Scenes
2456 m_perfMonMS = Environment.TickCount; 2450 m_perfMonMS = Environment.TickCount;
2457 2451
2458 Vector3 pos = m_pos; 2452 Vector3 pos = m_pos;
2459 Vector3 vel = Velocity;
2460 Quaternion rot = m_bodyRot;
2461 pos.Z -= m_appearance.HipOffset; 2453 pos.Z -= m_appearance.HipOffset;
2462 remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, new Vector3(pos.X, pos.Y, pos.Z), 2454
2463 new Vector3(vel.X, vel.Y, vel.Z), rot, m_uuid); 2455 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
2456 pos, m_velocity, m_rotation, m_uuid, GetUpdatePriority(remoteClient)));
2464 2457
2465 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2458 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
2466 m_scene.StatsReporter.AddAgentUpdates(1); 2459 m_scene.StatsReporter.AddAgentUpdates(1);
@@ -2474,7 +2467,7 @@ namespace OpenSim.Region.Framework.Scenes
2474 { 2467 {
2475 m_perfMonMS = Environment.TickCount; 2468 m_perfMonMS = Environment.TickCount;
2476 2469
2477 m_scene.Broadcast(SendTerseUpdateToClient); 2470 m_scene.ForEachClient(SendTerseUpdateToClient);
2478 2471
2479 m_lastVelocity = m_velocity; 2472 m_lastVelocity = m_velocity;
2480 lastPhysPos = AbsolutePosition; 2473 lastPhysPos = AbsolutePosition;
@@ -2566,9 +2559,9 @@ namespace OpenSim.Region.Framework.Scenes
2566 Vector3 pos = m_pos; 2559 Vector3 pos = m_pos;
2567 pos.Z -= m_appearance.HipOffset; 2560 pos.Z -= m_appearance.HipOffset;
2568 2561
2569 remoteAvatar.m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, 2562 remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid,
2570 LocalId, m_pos, m_appearance.Texture.GetBytes(), 2563 LocalId, m_pos, m_appearance.Texture.GetBytes(),
2571 m_parentID, rot); 2564 m_parentID, rot));
2572 m_scene.StatsReporter.AddAgentUpdates(1); 2565 m_scene.StatsReporter.AddAgentUpdates(1);
2573 } 2566 }
2574 2567
@@ -2637,8 +2630,8 @@ namespace OpenSim.Region.Framework.Scenes
2637 Vector3 pos = m_pos; 2630 Vector3 pos = m_pos;
2638 pos.Z -= m_appearance.HipOffset; 2631 pos.Z -= m_appearance.HipOffset;
2639 2632
2640 m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, 2633 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
2641 m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot); 2634 m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot));
2642 2635
2643 if (!m_isChildAgent) 2636 if (!m_isChildAgent)
2644 { 2637 {
@@ -2744,8 +2737,8 @@ namespace OpenSim.Region.Framework.Scenes
2744 } 2737 }
2745 2738
2746 Quaternion rot = m_bodyRot; 2739 Quaternion rot = m_bodyRot;
2747 m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, 2740 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
2748 m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot); 2741 m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot));
2749 2742
2750 } 2743 }
2751 2744
@@ -2776,7 +2769,7 @@ namespace OpenSim.Region.Framework.Scenes
2776 if (m_isChildAgent) 2769 if (m_isChildAgent)
2777 return; 2770 return;
2778 2771
2779 m_scene.Broadcast( 2772 m_scene.ForEachClient(
2780 delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); }); 2773 delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); });
2781 } 2774 }
2782 2775
@@ -3882,5 +3875,41 @@ namespace OpenSim.Region.Framework.Scenes
3882 } 3875 }
3883 } 3876 }
3884 } 3877 }
3878
3879 public double GetUpdatePriority(IClientAPI client)
3880 {
3881 switch (Scene.UpdatePrioritizationScheme)
3882 {
3883 case Scene.UpdatePrioritizationSchemes.Time:
3884 return GetPriorityByTime();
3885 case Scene.UpdatePrioritizationSchemes.Distance:
3886 return GetPriorityByDistance(client);
3887 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3888 return GetPriorityByDistance(client);
3889 default:
3890 throw new InvalidOperationException("UpdatePrioritizationScheme not defined.");
3891 }
3892 }
3893
3894 private double GetPriorityByTime()
3895 {
3896 return DateTime.Now.ToOADate();
3897 }
3898
3899 private double GetPriorityByDistance(IClientAPI client)
3900 {
3901 ScenePresence presence = Scene.GetScenePresence(client.AgentId);
3902 if (presence != null)
3903 {
3904 return GetPriorityByDistance((presence.IsChildAgent) ?
3905 presence.AbsolutePosition : presence.CameraPosition);
3906 }
3907 return double.NaN;
3908 }
3909
3910 private double GetPriorityByDistance(Vector3 position)
3911 {
3912 return Vector3.Distance(AbsolutePosition, position);
3913 }
3885 } 3914 }
3886} 3915}
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index 8ab0552..e4296ef 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -45,14 +45,6 @@ namespace OpenSim.Region.Framework.Scenes
45 45
46 protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); 46 protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>();
47 47
48 protected int m_maxPrimsPerFrame = 200;
49
50 public int MaxPrimsPerFrame
51 {
52 get { return m_maxPrimsPerFrame; }
53 set { m_maxPrimsPerFrame = value; }
54 }
55
56 public SceneViewer() 48 public SceneViewer()
57 { 49 {
58 } 50 }
@@ -82,16 +74,7 @@ namespace OpenSim.Region.Framework.Scenes
82 { 74 {
83 m_pendingObjects = new Queue<SceneObjectGroup>(); 75 m_pendingObjects = new Queue<SceneObjectGroup>();
84 76
85 List<EntityBase> ents = new List<EntityBase>(m_presence.Scene.Entities); 77 foreach (EntityBase e in m_presence.Scene.Entities)
86 if (!m_presence.IsChildAgent) // Proximity sort makes no sense for
87 { // Child agents
88 ents.Sort(delegate(EntityBase a, EntityBase b)
89 {
90 return Vector3.Distance(m_presence.AbsolutePosition, a.AbsolutePosition).CompareTo(Vector3.Distance(m_presence.AbsolutePosition, b.AbsolutePosition));
91 });
92 }
93
94 foreach (EntityBase e in ents)
95 { 78 {
96 if (e is SceneObjectGroup) 79 if (e is SceneObjectGroup)
97 m_pendingObjects.Enqueue((SceneObjectGroup)e); 80 m_pendingObjects.Enqueue((SceneObjectGroup)e);
@@ -99,7 +82,7 @@ namespace OpenSim.Region.Framework.Scenes
99 } 82 }
100 } 83 }
101 84
102 while (m_pendingObjects != null && m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < m_maxPrimsPerFrame) 85 while (m_pendingObjects != null && m_pendingObjects.Count > 0)
103 { 86 {
104 SceneObjectGroup g = m_pendingObjects.Dequeue(); 87 SceneObjectGroup g = m_pendingObjects.Dequeue();
105 88
@@ -183,8 +166,6 @@ namespace OpenSim.Region.Framework.Scenes
183 m_presence.GenerateClientFlags(part.UUID)); 166 m_presence.GenerateClientFlags(part.UUID));
184 } 167 }
185 } 168 }
186
187 m_presence.ControllingClient.FlushPrimUpdates();
188 } 169 }
189 170
190 public void Reset() 171 public void Reset()
diff --git a/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs b/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs
index 29c4672..f3be028 100644
--- a/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs
+++ b/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs
@@ -35,8 +35,8 @@ namespace OpenSim.Region.Framework.Scenes.Scripting
35 string Description { get; set; } 35 string Description { get; set; }
36 36
37 UUID UUID { get; } 37 UUID UUID { get; }
38 UUID ObjectOwner { get; } 38 UUID OwnerID { get; }
39 UUID ObjectCreator { get; } 39 UUID CreatorID { get; }
40 Vector3 AbsolutePosition { get; } 40 Vector3 AbsolutePosition { get; }
41 41
42 string SitName { get; set; } 42 string SitName { get; set; }
diff --git a/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs b/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs
index af18a98..d7198f0 100644
--- a/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs
+++ b/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs
@@ -68,12 +68,12 @@ namespace OpenSim.Region.Framework.Scenes.Scripting
68 get { return UUID.Zero; } 68 get { return UUID.Zero; }
69 } 69 }
70 70
71 public UUID ObjectOwner 71 public UUID OwnerID
72 { 72 {
73 get { return UUID.Zero; } 73 get { return UUID.Zero; }
74 } 74 }
75 75
76 public UUID ObjectCreator 76 public UUID CreatorID
77 { 77 {
78 get { return UUID.Zero; } 78 get { return UUID.Zero; }
79 } 79 }
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index a8acf0d..8ad9327 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -1011,12 +1011,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1011 1011
1012 } 1012 }
1013 1013
1014 public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) 1014 public void SendAvatarData(SendAvatarData data)
1015 { 1015 {
1016 1016
1017 } 1017 }
1018 1018
1019 public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentid) 1019 public void SendAvatarTerseUpdate(SendAvatarTerseData data)
1020 { 1020 {
1021 1021
1022 } 1022 }
@@ -1036,17 +1036,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1036 1036
1037 } 1037 }
1038 1038
1039 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius) 1039 public void SendPrimitiveToClient(SendPrimitiveData data)
1040 { 1040 {
1041 1041
1042 } 1042 }
1043 1043
1044 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material) 1044 public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
1045 {
1046
1047 }
1048
1049 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID owner, int attachPoint)
1050 { 1045 {
1051 1046
1052 } 1047 }
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
index 0379180..e185351 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
@@ -188,7 +188,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
188 // MISC COMPARISONS (UUID, Byte) 188 // MISC COMPARISONS (UUID, Byte)
189 if (first.ClickAction != second.ClickAction) 189 if (first.ClickAction != second.ClickAction)
190 result |= Diff.CLICKACTION; 190 result |= Diff.CLICKACTION;
191 if (first.ObjectOwner != second.ObjectOwner) 191 if (first.OwnerID != second.OwnerID)
192 result |= Diff.OBJECTOWNER; 192 result |= Diff.OBJECTOWNER;
193 193
194 194
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
index ce50f9e..4521f8e 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
@@ -259,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
259 if (e.InnerException != null) 259 if (e.InnerException != null)
260 m_log.Error("[MRM] " + e.InnerException); 260 m_log.Error("[MRM] " + e.InnerException);
261 261
262 m_scene.Broadcast(delegate(IClientAPI user) 262 m_scene.ForEachClient(delegate(IClientAPI user)
263 { 263 {
264 user.SendAlertMessage( 264 user.SendAlertMessage(
265 "MRM UnAuthorizedAccess: " + e); 265 "MRM UnAuthorizedAccess: " + e);
@@ -268,7 +268,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
268 catch (Exception e) 268 catch (Exception e)
269 { 269 {
270 m_log.Info("[MRM] Error: " + e); 270 m_log.Info("[MRM] Error: " + e);
271 m_scene.Broadcast(delegate(IClientAPI user) 271 m_scene.ForEachClient(delegate(IClientAPI user)
272 { 272 {
273 user.SendAlertMessage( 273 user.SendAlertMessage(
274 "Compile error while building MRM script, check OpenSim console for more information."); 274 "Compile error while building MRM script, check OpenSim console for more information.");
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index f7c63ac..6c58f2d 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -588,13 +588,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
588 { 588 {
589 } 589 }
590 590
591 public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, 591 public virtual void SendAvatarData(SendAvatarData data)
592 uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation)
593 { 592 {
594 } 593 }
595 594
596 public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, 595 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
597 Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentId)
598 { 596 {
599 } 597 }
600 598
@@ -610,26 +608,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
610 { 608 {
611 } 609 }
612 610
613 public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, 611 public virtual void SendPrimitiveToClient(SendPrimitiveData data)
614 PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel,
615 Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags,
616 UUID objectID, UUID ownerID, string text, byte[] color,
617 uint parentID,
618 byte[] particleSystem, byte clickAction, byte material)
619 { 612 {
620 } 613 }
621 public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, 614
622 PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, 615 public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data)
623 Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags,
624 UUID objectID, UUID ownerID, string text, byte[] color,
625 uint parentID,
626 byte[] particleSystem, byte clickAction, byte material, byte[] textureanimation,
627 bool attachment, uint AttachmentPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius)
628 {
629 }
630 public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID,
631 Vector3 position, Quaternion rotation, Vector3 velocity,
632 Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint)
633 { 616 {
634 } 617 }
635 618
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index e10e612..57b14f7 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2875,7 +2875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2875 { 2875 {
2876 m_host.AddScriptLPS(1); 2876 m_host.AddScriptLPS(1);
2877 2877
2878 return m_host.ObjectOwner.ToString(); 2878 return m_host.OwnerID.ToString();
2879 } 2879 }
2880 2880
2881 public void llInstantMessage(string user, string message) 2881 public void llInstantMessage(string user, string message)
@@ -5634,7 +5634,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5634 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y); 5634 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y);
5635 if (parcel != null) 5635 if (parcel != null)
5636 { 5636 {
5637 if (m_host.ObjectOwner == parcel.LandData.OwnerID || 5637 if (m_host.OwnerID == parcel.LandData.OwnerID ||
5638 (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID 5638 (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID
5639 && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID)) 5639 && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID))
5640 { 5640 {
@@ -7157,7 +7157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7157 7157
7158 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 7158 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
7159 7159
7160 if (land.LandData.OwnerID != m_host.ObjectOwner) 7160 if (land.LandData.OwnerID != m_host.OwnerID)
7161 return; 7161 return;
7162 7162
7163 land.SetMusicUrl(url); 7163 land.SetMusicUrl(url);
@@ -7215,7 +7215,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7215 public LSL_String llGetCreator() 7215 public LSL_String llGetCreator()
7216 { 7216 {
7217 m_host.AddScriptLPS(1); 7217 m_host.AddScriptLPS(1);
7218 return m_host.ObjectCreator.ToString(); 7218 return m_host.CreatorID.ToString();
7219 } 7219 }
7220 7220
7221 public LSL_String llGetTimestamp() 7221 public LSL_String llGetTimestamp()
@@ -8396,7 +8396,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8396 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 8396 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
8397 if (null != dm) 8397 if (null != dm)
8398 dm.SendUrlToUser( 8398 dm.SendUrlToUser(
8399 new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.ObjectOwner, false, message, url); 8399 new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.OwnerID, false, message, url);
8400 8400
8401 ConditionalScriptSleep(10000); 8401 ConditionalScriptSleep(10000);
8402 } 8402 }
@@ -8411,7 +8411,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8411 // according to the docs, this command only works if script owner and land owner are the same 8411 // according to the docs, this command only works if script owner and land owner are the same
8412 // lets add estate owners and gods, too, and use the generic permission check. 8412 // lets add estate owners and gods, too, and use the generic permission check.
8413 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 8413 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
8414 if (!World.Permissions.CanEditParcel(m_host.ObjectOwner, landObject)) return; 8414 if (!World.Permissions.CanEditParcel(m_host.OwnerID, landObject)) return;
8415 8415
8416 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 8416 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
8417 byte loop = 0; 8417 byte loop = 0;
@@ -9081,9 +9081,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9081 Vector3 velocity = m_host.Velocity; 9081 Vector3 velocity = m_host.Velocity;
9082 Quaternion rotation = m_host.RotationOffset; 9082 Quaternion rotation = m_host.RotationOffset;
9083 string ownerName = String.Empty; 9083 string ownerName = String.Empty;
9084 ScenePresence scenePresence = World.GetScenePresence(m_host.ObjectOwner); 9084 ScenePresence scenePresence = World.GetScenePresence(m_host.OwnerID);
9085 if (scenePresence == null) 9085 if (scenePresence == null)
9086 ownerName = resolveName(m_host.ObjectOwner); 9086 ownerName = resolveName(m_host.OwnerID);
9087 else 9087 else
9088 ownerName = scenePresence.Name; 9088 ownerName = scenePresence.Name;
9089 9089
@@ -9108,7 +9108,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9108 httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z); 9108 httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z);
9109 httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W); 9109 httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W);
9110 httpHeaders["X-SecondLife-Owner-Name"] = ownerName; 9110 httpHeaders["X-SecondLife-Owner-Name"] = ownerName;
9111 httpHeaders["X-SecondLife-Owner-Key"] = m_host.ObjectOwner.ToString(); 9111 httpHeaders["X-SecondLife-Owner-Key"] = m_host.OwnerID.ToString();
9112 string userAgent = config.Configs["Network"].GetString("user_agent", null); 9112 string userAgent = config.Configs["Network"].GetString("user_agent", null);
9113 if (userAgent != null) 9113 if (userAgent != null)
9114 httpHeaders["User-Agent"] = userAgent; 9114 httpHeaders["User-Agent"] = userAgent;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 4cb4b61..52396b6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -1164,7 +1164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1164 ILandObject land 1164 ILandObject land
1165 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 1165 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1166 1166
1167 if (land.LandData.OwnerID != m_host.ObjectOwner) 1167 if (land.LandData.OwnerID != m_host.OwnerID)
1168 return; 1168 return;
1169 1169
1170 land.SetMediaUrl(url); 1170 land.SetMediaUrl(url);
@@ -1182,7 +1182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1182 ILandObject land 1182 ILandObject land
1183 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 1183 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1184 1184
1185 if (land.LandData.OwnerID != m_host.ObjectOwner) 1185 if (land.LandData.OwnerID != m_host.OwnerID)
1186 { 1186 {
1187 OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function"); 1187 OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function");
1188 return; 1188 return;
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 5c838c5..21606e2 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -592,13 +592,11 @@ namespace OpenSim.Tests.Common.Mock
592 { 592 {
593 } 593 }
594 594
595 public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, 595 public virtual void SendAvatarData(SendAvatarData data)
596 uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation)
597 { 596 {
598 } 597 }
599 598
600 public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, 599 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
601 Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentid)
602 { 600 {
603 } 601 }
604 602
@@ -614,27 +612,11 @@ namespace OpenSim.Tests.Common.Mock
614 { 612 {
615 } 613 }
616 614
617 public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, 615 public virtual void SendPrimitiveToClient(SendPrimitiveData data)
618 PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel,
619 Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags,
620 UUID objectID, UUID ownerID, string text, byte[] color,
621 uint parentID,
622 byte[] particleSystem, byte clickAction, byte material)
623 { 616 {
624 } 617 }
625 public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, 618
626 PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, 619 public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data)
627 Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags,
628 UUID objectID, UUID ownerID, string text, byte[] color,
629 uint parentID,
630 byte[] particleSystem, byte clickAction, byte material, byte[] textureanimation,
631 bool attachment, uint AttachmentPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius)
632 {
633 }
634 public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID,
635 Vector3 position, Quaternion rotation, Vector3 velocity,
636 Vector3 rotationalvelocity, byte state, UUID AssetId,
637 UUID ownerID, int attachPoint)
638 { 620 {
639 } 621 }
640 622
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 002745d..ba797e6 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -1385,6 +1385,14 @@
1385 ; 1385 ;
1386 ;TextureDataLimit = 5 1386 ;TextureDataLimit = 5
1387 1387
1388[InterestManagement]
1389 ; This section controls how state updates are prioritized for each client
1390 UpdatePrioritizationScheme = Distance
1391 ReprioritizeUpdate = true
1392 RootUpdateReprioritizationDistance = 10.0
1393 ChildUpdateReprioritizationDistance = 20.0
1394 ReprioritizeUpdatesInterval = 5000.0
1395
1388;; 1396;;
1389;; These are defaults that are overwritten below in [Architecture]. 1397;; These are defaults that are overwritten below in [Architecture].
1390;; These defaults allow OpenSim to work out of the box with 1398;; These defaults allow OpenSim to work out of the box with