aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Client/MXP/ClientStack/MXPClientView.cs24
-rw-r--r--OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs5
-rw-r--r--OpenSim/Data/MySQL/MySQLLegacyRegionData.cs271
-rw-r--r--OpenSim/Framework/IClientAPI.cs215
-rw-r--r--OpenSim/Framework/Parallel.cs8
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs1151
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs55
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs48
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs134
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs5
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs4
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs3
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs4
16 files changed, 956 insertions, 983 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index ea29c41..204603d 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -999,16 +999,16 @@ namespace OpenSim.Client.MXP.ClientStack
999 public void SendAvatarData(SendAvatarData data) 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 = data.avatarID; 1002 UUID ownerID = data.AvatarID;
1003 MXPSendAvatarData(data.firstName + " " + data.lastName, ownerID, UUID.Zero, data.avatarID, data.avatarLocalID, data.Pos, data.rotation); 1003 MXPSendAvatarData(data.FirstName + " " + data.LastName, ownerID, UUID.Zero, data.AvatarID, data.AvatarLocalID, data.Position, data.Rotation);
1004 } 1004 }
1005 1005
1006 public void SendAvatarTerseUpdate(SendAvatarTerseData data) 1006 public void SendAvatarTerseUpdate(SendAvatarTerseData data)
1007 { 1007 {
1008 MovementEventMessage me = new MovementEventMessage(); 1008 MovementEventMessage me = new MovementEventMessage();
1009 me.ObjectIndex = data.localID; 1009 me.ObjectIndex = data.LocalID;
1010 me.Location = ToOmVector(data.position); 1010 me.Location = ToOmVector(data.Position);
1011 me.Orientation = ToOmQuaternion(data.rotation); 1011 me.Orientation = ToOmQuaternion(data.Rotation);
1012 1012
1013 Session.Send(me); 1013 Session.Send(me);
1014 } 1014 }
@@ -1030,18 +1030,24 @@ namespace OpenSim.Client.MXP.ClientStack
1030 1030
1031 public void SendPrimitiveToClient(SendPrimitiveData data) 1031 public void SendPrimitiveToClient(SendPrimitiveData data)
1032 { 1032 {
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); 1033 MXPSendPrimitive(data.localID, data.ownerID, data.acc, data.rvel, data.primShape, data.pos, data.objectID, data.vel,
1034 data.rotation, (uint)data.flags, data.text, data.color, data.parentID, data.particleSystem, data.clickAction,
1035 data.material, data.textureanim);
1034 } 1036 }
1035 1037
1036 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 1038 public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
1037 { 1039 {
1038 MovementEventMessage me = new MovementEventMessage(); 1040 MovementEventMessage me = new MovementEventMessage();
1039 me.ObjectIndex = data.localID; 1041 me.ObjectIndex = data.LocalID;
1040 me.Location = ToOmVector(data.position); 1042 me.Location = ToOmVector(data.Position);
1041 me.Orientation = ToOmQuaternion(data.rotation); 1043 me.Orientation = ToOmQuaternion(data.Rotation);
1042 Session.Send(me); 1044 Session.Send(me);
1043 } 1045 }
1044 1046
1047 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
1048 {
1049 }
1050
1045 public void FlushPrimUpdates() 1051 public void FlushPrimUpdates()
1046 { 1052 {
1047 } 1053 }
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
index d6990de..4a54c67 100644
--- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
+++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
@@ -596,6 +596,11 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
596 throw new System.NotImplementedException(); 596 throw new System.NotImplementedException();
597 } 597 }
598 598
599 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
600 {
601 throw new System.NotImplementedException();
602 }
603
599 public void FlushPrimUpdates() 604 public void FlushPrimUpdates()
600 { 605 {
601 throw new System.NotImplementedException(); 606 throw new System.NotImplementedException();
diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
index 6bc8bec..801d6b9 100644
--- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
+++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
@@ -403,26 +403,23 @@ namespace OpenSim.Data.MySQL
403 } 403 }
404 } 404 }
405 405
406 public List<SceneObjectGroup> LoadObjects(UUID regionUUID) 406 public List<SceneObjectGroup> LoadObjects(UUID regionID)
407 { 407 {
408 UUID lastGroupID = UUID.Zero; 408 const int ROWS_PER_QUERY = 5000;
409
410 Dictionary<UUID, SceneObjectPart> prims = new Dictionary<UUID, SceneObjectPart>(ROWS_PER_QUERY);
409 Dictionary<UUID, SceneObjectGroup> objects = new Dictionary<UUID, SceneObjectGroup>(); 411 Dictionary<UUID, SceneObjectGroup> objects = new Dictionary<UUID, SceneObjectGroup>();
410 Dictionary<UUID, SceneObjectPart> prims = new Dictionary<UUID, SceneObjectPart>();
411 SceneObjectGroup grp = null;
412 int count = 0; 412 int count = 0;
413 413
414 #region Prim Loading
415
414 lock (m_Connection) 416 lock (m_Connection)
415 { 417 {
416 using (MySqlCommand cmd = m_Connection.CreateCommand()) 418 using (MySqlCommand cmd = m_Connection.CreateCommand())
417 { 419 {
418 cmd.CommandText = "select *, " + 420 cmd.CommandText =
419 "case when prims.UUID = SceneGroupID " + 421 "SELECT * FROM prims LEFT JOIN primshapes ON prims.UUID = primshapes.UUID WHERE RegionUUID = ?RegionUUID";
420 "then 0 else 1 end as sort from prims " + 422 cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
421 "left join primshapes on prims.UUID = primshapes.UUID " +
422 "where RegionUUID = ?RegionUUID " +
423 "order by SceneGroupID asc, sort asc, LinkNumber asc";
424
425 cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString());
426 423
427 using (IDataReader reader = ExecuteReader(cmd)) 424 using (IDataReader reader = ExecuteReader(cmd))
428 { 425 {
@@ -434,56 +431,61 @@ namespace OpenSim.Data.MySQL
434 else 431 else
435 prim.Shape = BuildShape(reader); 432 prim.Shape = BuildShape(reader);
436 433
437 prims[prim.UUID] = prim; 434 UUID parentID = new UUID(reader["SceneGroupID"].ToString());
438 435 if (parentID != prim.UUID)
439 UUID groupID = new UUID(reader["SceneGroupID"].ToString()); 436 prim.ParentUUID = parentID;
440 437
441 if (groupID != lastGroupID) // New SOG 438 prims[prim.UUID] = prim;
442 {
443 if (grp != null)
444 objects[grp.UUID] = grp;
445 439
446 lastGroupID = groupID; 440 ++count;
441 if (count % ROWS_PER_QUERY == 0)
442 m_log.Debug("[REGION DB]: Loaded " + count + " prims...");
443 }
444 }
445 }
446 }
447 447
448 // There sometimes exist OpenSim bugs that 'orphan groups' so that none of the prims are 448 #endregion Prim Loading
449 // recorded as the root prim (for which the UUID must equal the persisted group UUID). In
450 // this case, force the UUID to be the same as the group UUID so that at least these can be
451 // deleted (we need to change the UUID so that any other prims in the linkset can also be
452 // deleted).
453 if (prim.UUID != groupID && groupID != UUID.Zero)
454 {
455 m_log.WarnFormat(
456 "[REGION DB]: Found root prim {0} {1} at {2} where group was actually {3}. Forcing UUID to group UUID",
457 prim.Name, prim.UUID, prim.GroupPosition, groupID);
458 449
459 prim.UUID = groupID; 450 #region SceneObjectGroup Creation
460 }
461 451
462 grp = new SceneObjectGroup(prim); 452 // Create all of the SOGs from the root prims first
463 } 453 foreach (SceneObjectPart prim in prims.Values)
464 else 454 {
465 { 455 if (prim.ParentUUID == UUID.Zero)
466 // Black magic to preserve link numbers 456 objects[prim.UUID] = new SceneObjectGroup(prim);
467 // 457 }
468 int link = prim.LinkNum;
469 458
470 grp.AddPart(prim); 459 // Add all of the children objects to the SOGs
460 foreach (SceneObjectPart prim in prims.Values)
461 {
462 SceneObjectGroup sog;
463 if (prim.UUID != prim.ParentUUID)
464 {
465 if (objects.TryGetValue(prim.ParentUUID, out sog))
466 {
467 int originalLinkNum = prim.LinkNum;
471 468
472 if (link != 0) 469 sog.AddPart(prim);
473 prim.LinkNum = link;
474 }
475 470
476 ++count; 471 // SceneObjectGroup.AddPart() tries to be smart and automatically set the LinkNum.
477 if (count % 5000 == 0) 472 // We override that here
478 m_log.Debug("[REGION DB]: Loaded " + count + " prims..."); 473 if (originalLinkNum != 0)
479 } 474 prim.LinkNum = originalLinkNum;
475 }
476 else
477 {
478 m_log.Warn("[REGION DB]: Database contains an orphan child prim " + prim.UUID + " pointing to missing parent " + prim.ParentUUID);
480 } 479 }
481
482 if (grp != null)
483 objects[grp.UUID] = grp;
484 } 480 }
485 } 481 }
486 482
483 #endregion SceneObjectGroup Creation
484
485 m_log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count);
486
487 #region Prim Inventory Loading
488
487 // Instead of attempting to LoadItems on every prim, 489 // Instead of attempting to LoadItems on every prim,
488 // most of which probably have no items... get a 490 // most of which probably have no items... get a
489 // list from DB of all prims which have items and 491 // list from DB of all prims which have items and
@@ -493,7 +495,7 @@ namespace OpenSim.Data.MySQL
493 { 495 {
494 using (MySqlCommand itemCmd = m_Connection.CreateCommand()) 496 using (MySqlCommand itemCmd = m_Connection.CreateCommand())
495 { 497 {
496 itemCmd.CommandText = "select distinct primID from primitems"; 498 itemCmd.CommandText = "SELECT DISTINCT primID FROM primitems";
497 using (IDataReader itemReader = ExecuteReader(itemCmd)) 499 using (IDataReader itemReader = ExecuteReader(itemCmd))
498 { 500 {
499 while (itemReader.Read()) 501 while (itemReader.Read())
@@ -502,9 +504,7 @@ namespace OpenSim.Data.MySQL
502 { 504 {
503 UUID primID = new UUID(itemReader["primID"].ToString()); 505 UUID primID = new UUID(itemReader["primID"].ToString());
504 if (prims.ContainsKey(primID)) 506 if (prims.ContainsKey(primID))
505 {
506 primsWithInventory.Add(prims[primID]); 507 primsWithInventory.Add(prims[primID]);
507 }
508 } 508 }
509 } 509 }
510 } 510 }
@@ -512,9 +512,14 @@ namespace OpenSim.Data.MySQL
512 } 512 }
513 513
514 foreach (SceneObjectPart prim in primsWithInventory) 514 foreach (SceneObjectPart prim in primsWithInventory)
515 {
515 LoadItems(prim); 516 LoadItems(prim);
517 }
518
519 #endregion Prim Inventory Loading
520
521 m_log.DebugFormat("[REGION DB]: Loaded inventory from {0} objects", primsWithInventory.Count);
516 522
517 m_log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count);
518 return new List<SceneObjectGroup>(objects.Values); 523 return new List<SceneObjectGroup>(objects.Values);
519 } 524 }
520 525
@@ -811,137 +816,137 @@ namespace OpenSim.Data.MySQL
811 private SceneObjectPart BuildPrim(IDataReader row) 816 private SceneObjectPart BuildPrim(IDataReader row)
812 { 817 {
813 SceneObjectPart prim = new SceneObjectPart(); 818 SceneObjectPart prim = new SceneObjectPart();
814 prim.UUID = new UUID((String) row["UUID"]); 819 prim.UUID = new UUID((string)row["UUID"]);
815 // explicit conversion of integers is required, which sort 820 // explicit conversion of integers is required, which sort
816 // of sucks. No idea if there is a shortcut here or not. 821 // of sucks. No idea if there is a shortcut here or not.
817 prim.CreationDate = Convert.ToInt32(row["CreationDate"]); 822 prim.CreationDate = (int)row["CreationDate"];
818 if (row["Name"] != DBNull.Value) 823 if (row["Name"] != DBNull.Value)
819 prim.Name = (String)row["Name"]; 824 prim.Name = (string)row["Name"];
820 else 825 else
821 prim.Name = string.Empty; 826 prim.Name = String.Empty;
822 // various text fields 827 // Various text fields
823 prim.Text = (String) row["Text"]; 828 prim.Text = (string)row["Text"];
824 prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]), 829 prim.Color = Color.FromArgb((int)row["ColorA"],
825 Convert.ToInt32(row["ColorR"]), 830 (int)row["ColorR"],
826 Convert.ToInt32(row["ColorG"]), 831 (int)row["ColorG"],
827 Convert.ToInt32(row["ColorB"])); 832 (int)row["ColorB"]);
828 prim.Description = (String) row["Description"]; 833 prim.Description = (string)row["Description"];
829 prim.SitName = (String) row["SitName"]; 834 prim.SitName = (string)row["SitName"];
830 prim.TouchName = (String) row["TouchName"]; 835 prim.TouchName = (string)row["TouchName"];
831 // permissions 836 // Permissions
832 prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]); 837 prim.ObjectFlags = (uint)(int)row["ObjectFlags"];
833 prim.CreatorID = new UUID((String) row["CreatorID"]); 838 prim.CreatorID = new UUID((string)row["CreatorID"]);
834 prim.OwnerID = new UUID((String) row["OwnerID"]); 839 prim.OwnerID = new UUID((string)row["OwnerID"]);
835 prim.GroupID = new UUID((String) row["GroupID"]); 840 prim.GroupID = new UUID((string)row["GroupID"]);
836 prim.LastOwnerID = new UUID((String) row["LastOwnerID"]); 841 prim.LastOwnerID = new UUID((string)row["LastOwnerID"]);
837 prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); 842 prim.OwnerMask = (uint)(int)row["OwnerMask"];
838 prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); 843 prim.NextOwnerMask = (uint)(int)row["NextOwnerMask"];
839 prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); 844 prim.GroupMask = (uint)(int)row["GroupMask"];
840 prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]); 845 prim.EveryoneMask = (uint)(int)row["EveryoneMask"];
841 prim.BaseMask = Convert.ToUInt32(row["BaseMask"]); 846 prim.BaseMask = (uint)(int)row["BaseMask"];
842 // vectors 847 // Vectors
843 prim.OffsetPosition = new Vector3( 848 prim.OffsetPosition = new Vector3(
844 Convert.ToSingle(row["PositionX"]), 849 (float)(double)row["PositionX"],
845 Convert.ToSingle(row["PositionY"]), 850 (float)(double)row["PositionY"],
846 Convert.ToSingle(row["PositionZ"]) 851 (float)(double)row["PositionZ"]
847 ); 852 );
848 prim.GroupPosition = new Vector3( 853 prim.GroupPosition = new Vector3(
849 Convert.ToSingle(row["GroupPositionX"]), 854 (float)(double)row["GroupPositionX"],
850 Convert.ToSingle(row["GroupPositionY"]), 855 (float)(double)row["GroupPositionY"],
851 Convert.ToSingle(row["GroupPositionZ"]) 856 (float)(double)row["GroupPositionZ"]
852 ); 857 );
853 prim.Velocity = new Vector3( 858 prim.Velocity = new Vector3(
854 Convert.ToSingle(row["VelocityX"]), 859 (float)(double)row["VelocityX"],
855 Convert.ToSingle(row["VelocityY"]), 860 (float)(double)row["VelocityY"],
856 Convert.ToSingle(row["VelocityZ"]) 861 (float)(double)row["VelocityZ"]
857 ); 862 );
858 prim.AngularVelocity = new Vector3( 863 prim.AngularVelocity = new Vector3(
859 Convert.ToSingle(row["AngularVelocityX"]), 864 (float)(double)row["AngularVelocityX"],
860 Convert.ToSingle(row["AngularVelocityY"]), 865 (float)(double)row["AngularVelocityY"],
861 Convert.ToSingle(row["AngularVelocityZ"]) 866 (float)(double)row["AngularVelocityZ"]
862 ); 867 );
863 prim.Acceleration = new Vector3( 868 prim.Acceleration = new Vector3(
864 Convert.ToSingle(row["AccelerationX"]), 869 (float)(double)row["AccelerationX"],
865 Convert.ToSingle(row["AccelerationY"]), 870 (float)(double)row["AccelerationY"],
866 Convert.ToSingle(row["AccelerationZ"]) 871 (float)(double)row["AccelerationZ"]
867 ); 872 );
868 // quaternions 873 // quaternions
869 prim.RotationOffset = new Quaternion( 874 prim.RotationOffset = new Quaternion(
870 Convert.ToSingle(row["RotationX"]), 875 (float)(double)row["RotationX"],
871 Convert.ToSingle(row["RotationY"]), 876 (float)(double)row["RotationY"],
872 Convert.ToSingle(row["RotationZ"]), 877 (float)(double)row["RotationZ"],
873 Convert.ToSingle(row["RotationW"]) 878 (float)(double)row["RotationW"]
874 ); 879 );
875 prim.SitTargetPositionLL = new Vector3( 880 prim.SitTargetPositionLL = new Vector3(
876 Convert.ToSingle(row["SitTargetOffsetX"]), 881 (float)(double)row["SitTargetOffsetX"],
877 Convert.ToSingle(row["SitTargetOffsetY"]), 882 (float)(double)row["SitTargetOffsetY"],
878 Convert.ToSingle(row["SitTargetOffsetZ"]) 883 (float)(double)row["SitTargetOffsetZ"]
879 ); 884 );
880 prim.SitTargetOrientationLL = new Quaternion( 885 prim.SitTargetOrientationLL = new Quaternion(
881 Convert.ToSingle(row["SitTargetOrientX"]), 886 (float)(double)row["SitTargetOrientX"],
882 Convert.ToSingle(row["SitTargetOrientY"]), 887 (float)(double)row["SitTargetOrientY"],
883 Convert.ToSingle(row["SitTargetOrientZ"]), 888 (float)(double)row["SitTargetOrientZ"],
884 Convert.ToSingle(row["SitTargetOrientW"]) 889 (float)(double)row["SitTargetOrientW"]
885 ); 890 );
886 891
887 prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]); 892 prim.PayPrice[0] = (int)row["PayPrice"];
888 prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]); 893 prim.PayPrice[1] = (int)row["PayButton1"];
889 prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]); 894 prim.PayPrice[2] = (int)row["PayButton2"];
890 prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]); 895 prim.PayPrice[3] = (int)row["PayButton3"];
891 prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]); 896 prim.PayPrice[4] = (int)row["PayButton4"];
892 897
893 prim.Sound = new UUID(row["LoopedSound"].ToString()); 898 prim.Sound = new UUID(row["LoopedSound"].ToString());
894 prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]); 899 prim.SoundGain = (float)(double)row["LoopedSoundGain"];
895 prim.SoundFlags = 1; // If it's persisted at all, it's looped 900 prim.SoundFlags = 1; // If it's persisted at all, it's looped
896 901
897 if (!(row["TextureAnimation"] is DBNull)) 902 if (!(row["TextureAnimation"] is DBNull))
898 prim.TextureAnimation = (Byte[])row["TextureAnimation"]; 903 prim.TextureAnimation = (byte[])row["TextureAnimation"];
899 if (!(row["ParticleSystem"] is DBNull)) 904 if (!(row["ParticleSystem"] is DBNull))
900 prim.ParticleSystem = (Byte[])row["ParticleSystem"]; 905 prim.ParticleSystem = (byte[])row["ParticleSystem"];
901 906
902 prim.RotationalVelocity = new Vector3( 907 prim.RotationalVelocity = new Vector3(
903 Convert.ToSingle(row["OmegaX"]), 908 (float)(double)row["OmegaX"],
904 Convert.ToSingle(row["OmegaY"]), 909 (float)(double)row["OmegaY"],
905 Convert.ToSingle(row["OmegaZ"]) 910 (float)(double)row["OmegaZ"]
906 ); 911 );
907 912
908 prim.SetCameraEyeOffset(new Vector3( 913 prim.SetCameraEyeOffset(new Vector3(
909 Convert.ToSingle(row["CameraEyeOffsetX"]), 914 (float)(double)row["CameraEyeOffsetX"],
910 Convert.ToSingle(row["CameraEyeOffsetY"]), 915 (float)(double)row["CameraEyeOffsetY"],
911 Convert.ToSingle(row["CameraEyeOffsetZ"]) 916 (float)(double)row["CameraEyeOffsetZ"]
912 )); 917 ));
913 918
914 prim.SetCameraAtOffset(new Vector3( 919 prim.SetCameraAtOffset(new Vector3(
915 Convert.ToSingle(row["CameraAtOffsetX"]), 920 (float)(double)row["CameraAtOffsetX"],
916 Convert.ToSingle(row["CameraAtOffsetY"]), 921 (float)(double)row["CameraAtOffsetY"],
917 Convert.ToSingle(row["CameraAtOffsetZ"]) 922 (float)(double)row["CameraAtOffsetZ"]
918 )); 923 ));
919 924
920 if (Convert.ToInt16(row["ForceMouselook"]) != 0) 925 if ((sbyte)row["ForceMouselook"] != 0)
921 prim.SetForceMouselook(true); 926 prim.SetForceMouselook(true);
922 927
923 prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]); 928 prim.ScriptAccessPin = (int)row["ScriptAccessPin"];
924 929
925 if (Convert.ToInt16(row["AllowedDrop"]) != 0) 930 if ((sbyte)row["AllowedDrop"] != 0)
926 prim.AllowedDrop = true; 931 prim.AllowedDrop = true;
927 932
928 if (Convert.ToInt16(row["DieAtEdge"]) != 0) 933 if ((sbyte)row["DieAtEdge"] != 0)
929 prim.DIE_AT_EDGE = true; 934 prim.DIE_AT_EDGE = true;
930 935
931 prim.SalePrice = Convert.ToInt32(row["SalePrice"]); 936 prim.SalePrice = (int)row["SalePrice"];
932 prim.ObjectSaleType = unchecked((byte)Convert.ToSByte(row["SaleType"])); 937 prim.ObjectSaleType = unchecked((byte)(sbyte)row["SaleType"]);
933 938
934 prim.Material = unchecked((byte)Convert.ToSByte(row["Material"])); 939 prim.Material = unchecked((byte)(sbyte)row["Material"]);
935 940
936 if (!(row["ClickAction"] is DBNull)) 941 if (!(row["ClickAction"] is DBNull))
937 prim.ClickAction = unchecked((byte)Convert.ToSByte(row["ClickAction"])); 942 prim.ClickAction = unchecked((byte)(sbyte)row["ClickAction"]);
938 943
939 prim.CollisionSound = new UUID(row["CollisionSound"].ToString()); 944 prim.CollisionSound = new UUID(row["CollisionSound"].ToString());
940 prim.CollisionSoundVolume = Convert.ToSingle(row["CollisionSoundVolume"]); 945 prim.CollisionSoundVolume = (float)(double)row["CollisionSoundVolume"];
941 946
942 if (Convert.ToInt16(row["PassTouches"]) != 0) 947 if ((sbyte)row["PassTouches"] != 0)
943 prim.PassTouches = true; 948 prim.PassTouches = true;
944 prim.LinkNum = Convert.ToInt32(row["LinkNumber"]); 949 prim.LinkNum = (int)row["LinkNumber"];
945 950
946 return prim; 951 return prim;
947 } 952 }
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 9aa3af1..d304345 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -448,6 +448,10 @@ namespace OpenSim.Framework
448 public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages); 448 public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
449 public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client); 449 public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client);
450 450
451 public delegate void AgentFOV(IClientAPI client, float verticalAngle);
452
453 public delegate double UpdatePriorityHandler(UpdatePriorityData data);
454
451 #endregion 455 #endregion
452 456
453 public struct DirPlacesReplyData 457 public struct DirPlacesReplyData
@@ -519,124 +523,100 @@ namespace OpenSim.Framework
519 523
520 public struct SendAvatarData 524 public struct SendAvatarData
521 { 525 {
522 private ulong m_regionHandle; 526 public readonly ulong RegionHandle;
523 private string m_firstName; 527 public readonly string FirstName;
524 private string m_lastName; 528 public readonly string LastName;
525 private string m_grouptitle; 529 public readonly string GroupTitle;
526 private UUID m_avatarID; 530 public readonly UUID AvatarID;
527 private uint m_avatarLocalID; 531 public readonly uint AvatarLocalID;
528 private Vector3 m_Pos; 532 public readonly Vector3 Position;
529 private byte[] m_textureEntry; 533 public readonly byte[] TextureEntry;
530 private uint m_parentID; 534 public readonly uint ParentID;
531 private Quaternion m_rotation; 535 public readonly Quaternion Rotation;
532 536
533 public SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, 537 public SendAvatarData(ulong regionHandle, string firstName, string lastName, string groupTitle, UUID avatarID,
534 uint avatarLocalID, 538 uint avatarLocalID, Vector3 position, byte[] textureEntry, uint parentID, Quaternion rotation)
535 Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation)
536 { 539 {
537 this.m_regionHandle = regionHandle; 540 RegionHandle = regionHandle;
538 this.m_firstName = firstName; 541 FirstName = firstName;
539 this.m_lastName = lastName; 542 LastName = lastName;
540 this.m_grouptitle = grouptitle; 543 GroupTitle = groupTitle;
541 this.m_avatarID = avatarID; 544 AvatarID = avatarID;
542 this.m_avatarLocalID = avatarLocalID; 545 AvatarLocalID = avatarLocalID;
543 this.m_Pos = Pos; 546 Position = position;
544 this.m_textureEntry = textureEntry; 547 TextureEntry = textureEntry;
545 this.m_parentID = parentID; 548 ParentID = parentID;
546 this.m_rotation = rotation; 549 Rotation = rotation;
547 } 550 }
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 } 551 }
560 552
561 public struct SendAvatarTerseData 553 public struct SendAvatarTerseData
562 { 554 {
563 private ulong m_regionHandle; 555 public readonly ulong RegionHandle;
564 private ushort m_timeDilation; 556 public readonly ushort TimeDilation;
565 private uint m_localID; 557 public readonly uint LocalID;
566 private Vector3 m_position; 558 public readonly Vector3 Position;
567 private Vector3 m_velocity; 559 public readonly Vector3 Velocity;
568 private Quaternion m_rotation; 560 public readonly Vector3 Acceleration;
569 private UUID m_agentid; 561 public readonly Quaternion Rotation;
570 private double m_priority; 562 public readonly Vector4 CollisionPlane;
571 563 public readonly UUID AgentID;
572 public SendAvatarTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, 564 public readonly byte[] TextureEntry;
573 Vector3 velocity, Quaternion rotation, UUID agentid, double priority) 565 public readonly double Priority;
566
567 public SendAvatarTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity,
568 Vector3 acceleration, Quaternion rotation, Vector4 collisionPlane, UUID agentid, byte[] textureEntry, double priority)
574 { 569 {
575 this.m_regionHandle = regionHandle; 570 RegionHandle = regionHandle;
576 this.m_timeDilation = timeDilation; 571 TimeDilation = timeDilation;
577 this.m_localID = localID; 572 LocalID = localID;
578 this.m_position = position; 573 Position = position;
579 this.m_velocity = velocity; 574 Velocity = velocity;
580 this.m_rotation = rotation; 575 Acceleration = acceleration;
581 this.m_agentid = agentid; 576 Rotation = rotation;
582 this.m_priority = priority; 577 CollisionPlane = collisionPlane;
578 AgentID = agentid;
579 TextureEntry = textureEntry;
580 Priority = priority;
583 } 581 }
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 } 582 }
594 583
595 public struct SendPrimitiveTerseData 584 public struct SendPrimitiveTerseData
596 { 585 {
597 private ulong m_regionHandle; 586 public readonly ulong RegionHandle;
598 private ushort m_timeDilation; 587 public readonly ushort TimeDilation;
599 private uint m_localID; 588 public readonly uint LocalID;
600 private Vector3 m_position; 589 public readonly Vector3 Position;
601 private Quaternion m_rotation; 590 public readonly Quaternion Rotation;
602 private Vector3 m_velocity; 591 public readonly Vector3 Velocity;
603 private Vector3 m_rotationalvelocity; 592 public readonly Vector3 Acceleration;
604 private byte m_state; 593 public readonly Vector3 AngularVelocity;
605 private UUID m_AssetId; 594 public readonly byte State;
606 private UUID m_owner; 595 public readonly UUID AssetID;
607 private int m_attachPoint; 596 public readonly UUID OwnerID;
608 private double m_priority; 597 public readonly int AttachPoint;
598 public readonly byte[] TextureEntry;
599 public readonly double Priority;
609 600
610 public SendPrimitiveTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, 601 public SendPrimitiveTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
611 Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, 602 Quaternion rotation, Vector3 velocity, Vector3 acceleration, Vector3 rotationalvelocity, byte state,
612 UUID AssetId, UUID owner, int attachPoint, double priority) 603 UUID assetID, UUID ownerID, int attachPoint, byte[] textureEntry, double priority)
613 { 604 {
614 this.m_regionHandle = regionHandle; 605 RegionHandle = regionHandle;
615 this.m_timeDilation = timeDilation; 606 TimeDilation = timeDilation;
616 this.m_localID = localID; 607 LocalID = localID;
617 this.m_position = position; 608 Position = position;
618 this.m_rotation = rotation; 609 Rotation = rotation;
619 this.m_velocity = velocity; 610 Velocity = velocity;
620 this.m_rotationalvelocity = rotationalvelocity; 611 Acceleration = acceleration;
621 this.m_state = state; 612 AngularVelocity = rotationalvelocity;
622 this.m_AssetId = AssetId; 613 State = state;
623 this.m_owner = owner; 614 AssetID = assetID;
624 this.m_attachPoint = attachPoint; 615 OwnerID = ownerID;
625 this.m_priority = priority; 616 AttachPoint = attachPoint;
617 TextureEntry = textureEntry;
618 Priority = priority;
626 } 619 }
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 } 620 }
641 621
642 public struct SendPrimitiveData 622 public struct SendPrimitiveData
@@ -650,7 +630,7 @@ namespace OpenSim.Framework
650 private Vector3 m_acc; 630 private Vector3 m_acc;
651 private Quaternion m_rotation; 631 private Quaternion m_rotation;
652 private Vector3 m_rvel; 632 private Vector3 m_rvel;
653 private uint m_flags; 633 private PrimFlags m_flags;
654 private UUID m_objectID; 634 private UUID m_objectID;
655 private UUID m_ownerID; 635 private UUID m_ownerID;
656 private string m_text; 636 private string m_text;
@@ -695,7 +675,7 @@ namespace OpenSim.Framework
695 this.m_acc = acc; 675 this.m_acc = acc;
696 this.m_rotation = rotation; 676 this.m_rotation = rotation;
697 this.m_rvel = rvel; 677 this.m_rvel = rvel;
698 this.m_flags = flags; 678 this.m_flags = (PrimFlags)flags;
699 this.m_objectID = objectID; 679 this.m_objectID = objectID;
700 this.m_ownerID = ownerID; 680 this.m_ownerID = ownerID;
701 this.m_text = text; 681 this.m_text = text;
@@ -724,7 +704,7 @@ namespace OpenSim.Framework
724 public Vector3 acc { get { return this.m_acc; } } 704 public Vector3 acc { get { return this.m_acc; } }
725 public Quaternion rotation { get { return this.m_rotation; } } 705 public Quaternion rotation { get { return this.m_rotation; } }
726 public Vector3 rvel { get { return this.m_rvel; } } 706 public Vector3 rvel { get { return this.m_rvel; } }
727 public uint flags { get { return this.m_flags; } } 707 public PrimFlags flags { get { return this.m_flags; } }
728 public UUID objectID { get { return this.m_objectID; } } 708 public UUID objectID { get { return this.m_objectID; } }
729 public UUID ownerID { get { return this.m_ownerID; } } 709 public UUID ownerID { get { return this.m_ownerID; } }
730 public string text { get { return this.m_text; } } 710 public string text { get { return this.m_text; } }
@@ -744,6 +724,29 @@ namespace OpenSim.Framework
744 public double priority { get { return this.m_priority; } } 724 public double priority { get { return this.m_priority; } }
745 } 725 }
746 726
727 public struct UpdatePriorityData {
728 private double m_priority;
729 private uint m_localID;
730
731 public UpdatePriorityData(double priority, uint localID) {
732 this.m_priority = priority;
733 this.m_localID = localID;
734 }
735
736 public double priority { get { return this.m_priority; } }
737 public uint localID { get { return this.m_localID; } }
738 }
739
740 [Flags]
741 public enum StateUpdateTypes
742 {
743 None = 0,
744 AvatarTerse = 1,
745 PrimitiveTerse = AvatarTerse << 1,
746 PrimitiveFull = PrimitiveTerse << 1,
747 All = AvatarTerse | PrimitiveTerse | PrimitiveFull,
748 }
749
747 public interface IClientAPI 750 public interface IClientAPI
748 { 751 {
749 Vector3 StartPos { get; set; } 752 Vector3 StartPos { get; set; }
@@ -1118,6 +1121,8 @@ namespace OpenSim.Framework
1118 1121
1119 void SendPrimTerseUpdate(SendPrimitiveTerseData data); 1122 void SendPrimTerseUpdate(SendPrimitiveTerseData data);
1120 1123
1124 void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler);
1125
1121 void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, 1126 void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items,
1122 List<InventoryFolderBase> folders, bool fetchFolders, 1127 List<InventoryFolderBase> folders, bool fetchFolders,
1123 bool fetchItems); 1128 bool fetchItems);
diff --git a/OpenSim/Framework/Parallel.cs b/OpenSim/Framework/Parallel.cs
index 6efdad0..cf4f773 100644
--- a/OpenSim/Framework/Parallel.cs
+++ b/OpenSim/Framework/Parallel.cs
@@ -36,7 +36,7 @@ namespace OpenSim.Framework
36 /// </summary> 36 /// </summary>
37 public static class Parallel 37 public static class Parallel
38 { 38 {
39 private static readonly int processorCount = System.Environment.ProcessorCount; 39 public static readonly int ProcessorCount = System.Environment.ProcessorCount;
40 40
41 /// <summary> 41 /// <summary>
42 /// Executes a for loop in which iterations may run in parallel 42 /// Executes a for loop in which iterations may run in parallel
@@ -46,7 +46,7 @@ namespace OpenSim.Framework
46 /// <param name="body">Method body to run for each iteration of the loop</param> 46 /// <param name="body">Method body to run for each iteration of the loop</param>
47 public static void For(int fromInclusive, int toExclusive, Action<int> body) 47 public static void For(int fromInclusive, int toExclusive, Action<int> body)
48 { 48 {
49 For(processorCount, fromInclusive, toExclusive, body); 49 For(ProcessorCount, fromInclusive, toExclusive, body);
50 } 50 }
51 51
52 /// <summary> 52 /// <summary>
@@ -103,7 +103,7 @@ namespace OpenSim.Framework
103 /// <param name="body">Method body to run for each object in the collection</param> 103 /// <param name="body">Method body to run for each object in the collection</param>
104 public static void ForEach<T>(IEnumerable<T> enumerable, Action<T> body) 104 public static void ForEach<T>(IEnumerable<T> enumerable, Action<T> body)
105 { 105 {
106 ForEach<T>(processorCount, enumerable, body); 106 ForEach<T>(ProcessorCount, enumerable, body);
107 } 107 }
108 108
109 /// <summary> 109 /// <summary>
@@ -161,7 +161,7 @@ namespace OpenSim.Framework
161 /// <param name="actions">A series of method bodies to execute</param> 161 /// <param name="actions">A series of method bodies to execute</param>
162 public static void Invoke(params Action[] actions) 162 public static void Invoke(params Action[] actions)
163 { 163 {
164 Invoke(processorCount, actions); 164 Invoke(ProcessorCount, actions);
165 } 165 }
166 166
167 /// <summary> 167 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 43c3c7c..1c463ea 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -295,6 +295,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
295 public event MuteListRequest OnMuteListRequest; 295 public event MuteListRequest OnMuteListRequest;
296 public event AvatarInterestUpdate OnAvatarInterestUpdate; 296 public event AvatarInterestUpdate OnAvatarInterestUpdate;
297 public event PlacesQuery OnPlacesQuery; 297 public event PlacesQuery OnPlacesQuery;
298 public event AgentFOV OnAgentFOV;
298 299
299 #endregion Events 300 #endregion Events
300 301
@@ -341,11 +342,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
341 protected Thread m_clientThread; 342 protected Thread m_clientThread;
342 protected Vector3 m_startpos; 343 protected Vector3 m_startpos;
343 protected EndPoint m_userEndPoint; 344 protected EndPoint m_userEndPoint;
344 protected UUID m_activeGroupID = UUID.Zero; 345 protected UUID m_activeGroupID;
345 protected string m_activeGroupName = String.Empty; 346 protected string m_activeGroupName = String.Empty;
346 protected ulong m_activeGroupPowers; 347 protected ulong m_activeGroupPowers;
347 protected Dictionary<UUID,ulong> m_groupPowers = new Dictionary<UUID, ulong>(); 348 protected Dictionary<UUID,ulong> m_groupPowers = new Dictionary<UUID, ulong>();
348 protected int m_terrainCheckerCount; 349 protected int m_terrainCheckerCount;
350 protected uint m_agentFOVCounter;
349 351
350 // These numbers are guesses at a decent tradeoff between responsiveness 352 // These numbers are guesses at a decent tradeoff between responsiveness
351 // of the interest list and throughput. Lower is more responsive, higher 353 // of the interest list and throughput. Lower is more responsive, higher
@@ -420,7 +422,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
420 m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>(); 422 m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>();
421 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); 423 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
422 m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>()); 424 m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>());
423 m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); 425 m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion());
424 m_agentId = agentId; 426 m_agentId = agentId;
425 m_sessionId = sessionId; 427 m_sessionId = sessionId;
426 m_secureSessionId = sessionInfo.LoginInfo.SecureSession; 428 m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
@@ -496,7 +498,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
496 kupack.UserInfo.SessionID = SessionId; 498 kupack.UserInfo.SessionID = SessionId;
497 kupack.TargetBlock.TargetIP = 0; 499 kupack.TargetBlock.TargetIP = 0;
498 kupack.TargetBlock.TargetPort = 0; 500 kupack.TargetBlock.TargetPort = 0;
499 kupack.UserInfo.Reason = Utils.StringToBytes(message); 501 kupack.UserInfo.Reason = Util.StringToBytes256(message);
500 OutPacket(kupack, ThrottleOutPacketType.Task); 502 OutPacket(kupack, ThrottleOutPacketType.Task);
501 // You must sleep here or users get no message! 503 // You must sleep here or users get no message!
502 Thread.Sleep(500); 504 Thread.Sleep(500);
@@ -641,7 +643,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
641 handshake.RegionInfo.WaterHeight = args.waterHeight; 643 handshake.RegionInfo.WaterHeight = args.waterHeight;
642 644
643 handshake.RegionInfo.RegionFlags = args.regionFlags; 645 handshake.RegionInfo.RegionFlags = args.regionFlags;
644 handshake.RegionInfo.SimName = Utils.StringToBytes(args.regionName); 646 handshake.RegionInfo.SimName = Util.StringToBytes256(args.regionName);
645 handshake.RegionInfo.SimOwner = args.SimOwner; 647 handshake.RegionInfo.SimOwner = args.SimOwner;
646 handshake.RegionInfo.TerrainBase0 = args.terrainBase0; 648 handshake.RegionInfo.TerrainBase0 = args.terrainBase0;
647 handshake.RegionInfo.TerrainBase1 = args.terrainBase1; 649 handshake.RegionInfo.TerrainBase1 = args.terrainBase1;
@@ -697,11 +699,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
697 { 699 {
698 ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator); 700 ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator);
699 reply.ChatData.Audible = audible; 701 reply.ChatData.Audible = audible;
700 reply.ChatData.Message = Utils.StringToBytes(message); 702 reply.ChatData.Message = Util.StringToBytes1024(message);
701 reply.ChatData.ChatType = type; 703 reply.ChatData.ChatType = type;
702 reply.ChatData.SourceType = source; 704 reply.ChatData.SourceType = source;
703 reply.ChatData.Position = fromPos; 705 reply.ChatData.Position = fromPos;
704 reply.ChatData.FromName = Utils.StringToBytes(fromName); 706 reply.ChatData.FromName = Util.StringToBytes256(fromName);
705 reply.ChatData.OwnerID = fromAgentID; 707 reply.ChatData.OwnerID = fromAgentID;
706 reply.ChatData.SourceID = fromAgentID; 708 reply.ChatData.SourceID = fromAgentID;
707 709
@@ -722,7 +724,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
722 724
723 msg.AgentData.AgentID = new UUID(im.fromAgentID); 725 msg.AgentData.AgentID = new UUID(im.fromAgentID);
724 msg.AgentData.SessionID = UUID.Zero; 726 msg.AgentData.SessionID = UUID.Zero;
725 msg.MessageBlock.FromAgentName = Utils.StringToBytes(im.fromAgentName); 727 msg.MessageBlock.FromAgentName = Util.StringToBytes256(im.fromAgentName);
726 msg.MessageBlock.Dialog = im.dialog; 728 msg.MessageBlock.Dialog = im.dialog;
727 msg.MessageBlock.FromGroup = im.fromGroup; 729 msg.MessageBlock.FromGroup = im.fromGroup;
728 if (im.imSessionID == UUID.Zero.Guid) 730 if (im.imSessionID == UUID.Zero.Guid)
@@ -735,12 +737,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
735 msg.MessageBlock.RegionID = new UUID(im.RegionID); 737 msg.MessageBlock.RegionID = new UUID(im.RegionID);
736 msg.MessageBlock.Timestamp = im.timestamp; 738 msg.MessageBlock.Timestamp = im.timestamp;
737 msg.MessageBlock.ToAgentID = new UUID(im.toAgentID); 739 msg.MessageBlock.ToAgentID = new UUID(im.toAgentID);
738 // Cap the message length at 1099. There is a limit in ImprovedInstantMessagePacket 740 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
739 // the limit is 1100 but a 0 byte gets added to mark the end of the string
740 if (im.message != null && im.message.Length > 1099)
741 msg.MessageBlock.Message = Utils.StringToBytes(im.message.Substring(0, 1099));
742 else
743 msg.MessageBlock.Message = Utils.StringToBytes(im.message);
744 msg.MessageBlock.BinaryBucket = im.binaryBucket; 741 msg.MessageBlock.BinaryBucket = im.binaryBucket;
745 742
746 if (im.message.StartsWith("[grouptest]")) 743 if (im.message.StartsWith("[grouptest]"))
@@ -758,7 +755,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
758 eq.ChatterboxInvitation( 755 eq.ChatterboxInvitation(
759 new UUID("00000000-68f9-1111-024e-222222111123"), 756 new UUID("00000000-68f9-1111-024e-222222111123"),
760 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0, 757 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
761 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Utils.StringToBytes("OpenSimulator Testing")); 758 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
762 759
763 eq.ChatterBoxSessionAgentListUpdates( 760 eq.ChatterBoxSessionAgentListUpdates(
764 new UUID("00000000-68f9-1111-024e-222222111123"), 761 new UUID("00000000-68f9-1111-024e-222222111123"),
@@ -775,13 +772,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
775 public void SendGenericMessage(string method, List<string> message) 772 public void SendGenericMessage(string method, List<string> message)
776 { 773 {
777 GenericMessagePacket gmp = new GenericMessagePacket(); 774 GenericMessagePacket gmp = new GenericMessagePacket();
778 gmp.MethodData.Method = Utils.StringToBytes(method); 775 gmp.MethodData.Method = Util.StringToBytes256(method);
779 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; 776 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count];
780 int i = 0; 777 int i = 0;
781 foreach (string val in message) 778 foreach (string val in message)
782 { 779 {
783 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock(); 780 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock();
784 gmp.ParamList[i++].Parameter = Utils.StringToBytes(val); 781 gmp.ParamList[i++].Parameter = Util.StringToBytes256(val);
785 } 782 }
786 OutPacket(gmp, ThrottleOutPacketType.Task); 783 OutPacket(gmp, ThrottleOutPacketType.Task);
787 } 784 }
@@ -1045,7 +1042,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1045 newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8; 1042 newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8;
1046 newSimPack.RegionData.SimIP += (uint)byteIP[0]; 1043 newSimPack.RegionData.SimIP += (uint)byteIP[0];
1047 newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port; 1044 newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port;
1048 newSimPack.RegionData.SeedCapability = Utils.StringToBytes(capsURL); 1045 newSimPack.RegionData.SeedCapability = Util.StringToBytes256(capsURL);
1049 1046
1050 // Hack to get this out immediately and skip throttles 1047 // Hack to get this out immediately and skip throttles
1051 OutPacket(newSimPack, ThrottleOutPacketType.Unknown); 1048 OutPacket(newSimPack, ThrottleOutPacketType.Unknown);
@@ -1123,7 +1120,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1123 teleport.Info.RegionHandle = regionHandle; 1120 teleport.Info.RegionHandle = regionHandle;
1124 teleport.Info.SimAccess = simAccess; 1121 teleport.Info.SimAccess = simAccess;
1125 1122
1126 teleport.Info.SeedCapability = Utils.StringToBytes(capsURL); 1123 teleport.Info.SeedCapability = Util.StringToBytes256(capsURL);
1127 1124
1128 IPAddress oIP = newRegionEndPoint.Address; 1125 IPAddress oIP = newRegionEndPoint.Address;
1129 byte[] byteIP = oIP.GetAddressBytes(); 1126 byte[] byteIP = oIP.GetAddressBytes();
@@ -1148,7 +1145,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1148 { 1145 {
1149 TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed); 1146 TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed);
1150 tpFailed.Info.AgentID = AgentId; 1147 tpFailed.Info.AgentID = AgentId;
1151 tpFailed.Info.Reason = Utils.StringToBytes(reason); 1148 tpFailed.Info.Reason = Util.StringToBytes256(reason);
1152 tpFailed.AlertInfo = new TeleportFailedPacket.AlertInfoBlock[0]; 1149 tpFailed.AlertInfo = new TeleportFailedPacket.AlertInfoBlock[0];
1153 1150
1154 // Hack to get this out immediately and skip throttles 1151 // Hack to get this out immediately and skip throttles
@@ -1880,11 +1877,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1880 AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate); 1877 AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate);
1881 sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid; 1878 sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid;
1882 sendAgentDataUpdate.AgentData.AgentID = agentid; 1879 sendAgentDataUpdate.AgentData.AgentID = agentid;
1883 sendAgentDataUpdate.AgentData.FirstName = Utils.StringToBytes(firstname); 1880 sendAgentDataUpdate.AgentData.FirstName = Util.StringToBytes256(firstname);
1884 sendAgentDataUpdate.AgentData.GroupName = Utils.StringToBytes(groupname); 1881 sendAgentDataUpdate.AgentData.GroupName = Util.StringToBytes256(groupname);
1885 sendAgentDataUpdate.AgentData.GroupPowers = grouppowers; 1882 sendAgentDataUpdate.AgentData.GroupPowers = grouppowers;
1886 sendAgentDataUpdate.AgentData.GroupTitle = Utils.StringToBytes(grouptitle); 1883 sendAgentDataUpdate.AgentData.GroupTitle = Util.StringToBytes256(grouptitle);
1887 sendAgentDataUpdate.AgentData.LastName = Utils.StringToBytes(lastname); 1884 sendAgentDataUpdate.AgentData.LastName = Util.StringToBytes256(lastname);
1888 OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task); 1885 OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task);
1889 } 1886 }
1890 1887
@@ -1897,7 +1894,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1897 { 1894 {
1898 AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage); 1895 AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage);
1899 alertPack.AlertData = new AlertMessagePacket.AlertDataBlock(); 1896 alertPack.AlertData = new AlertMessagePacket.AlertDataBlock();
1900 alertPack.AlertData.Message = Utils.StringToBytes(message); 1897 alertPack.AlertData.Message = Util.StringToBytes256(message);
1901 alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[0]; 1898 alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[0];
1902 OutPacket(alertPack, ThrottleOutPacketType.Task); 1899 OutPacket(alertPack, ThrottleOutPacketType.Task);
1903 } 1900 }
@@ -1924,7 +1921,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1924 { 1921 {
1925 AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); 1922 AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage);
1926 alertPack.AgentData.AgentID = AgentId; 1923 alertPack.AgentData.AgentID = AgentId;
1927 alertPack.AlertData.Message = Utils.StringToBytes(message); 1924 alertPack.AlertData.Message = Util.StringToBytes256(message);
1928 alertPack.AlertData.Modal = modal; 1925 alertPack.AlertData.Modal = modal;
1929 1926
1930 return alertPack; 1927 return alertPack;
@@ -1934,12 +1931,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1934 string url) 1931 string url)
1935 { 1932 {
1936 LoadURLPacket loadURL = (LoadURLPacket)PacketPool.Instance.GetPacket(PacketType.LoadURL); 1933 LoadURLPacket loadURL = (LoadURLPacket)PacketPool.Instance.GetPacket(PacketType.LoadURL);
1937 loadURL.Data.ObjectName = Utils.StringToBytes(objectname); 1934 loadURL.Data.ObjectName = Util.StringToBytes256(objectname);
1938 loadURL.Data.ObjectID = objectID; 1935 loadURL.Data.ObjectID = objectID;
1939 loadURL.Data.OwnerID = ownerID; 1936 loadURL.Data.OwnerID = ownerID;
1940 loadURL.Data.OwnerIsGroup = groupOwned; 1937 loadURL.Data.OwnerIsGroup = groupOwned;
1941 loadURL.Data.Message = Utils.StringToBytes(message); 1938 loadURL.Data.Message = Util.StringToBytes256(message);
1942 loadURL.Data.URL = Utils.StringToBytes(url); 1939 loadURL.Data.URL = Util.StringToBytes256(url);
1943 OutPacket(loadURL, ThrottleOutPacketType.Task); 1940 OutPacket(loadURL, ThrottleOutPacketType.Task);
1944 } 1941 }
1945 1942
@@ -1947,18 +1944,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1947 { 1944 {
1948 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); 1945 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
1949 dialog.Data.ObjectID = objectID; 1946 dialog.Data.ObjectID = objectID;
1950 dialog.Data.ObjectName = Utils.StringToBytes(objectname); 1947 dialog.Data.ObjectName = Util.StringToBytes256(objectname);
1951 // this is the username of the *owner* 1948 // this is the username of the *owner*
1952 dialog.Data.FirstName = Utils.StringToBytes(ownerFirstName); 1949 dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName);
1953 dialog.Data.LastName = Utils.StringToBytes(ownerLastName); 1950 dialog.Data.LastName = Util.StringToBytes256(ownerLastName);
1954 dialog.Data.Message = Utils.StringToBytes(msg); 1951 dialog.Data.Message = Util.StringToBytes1024(msg);
1955 dialog.Data.ImageID = textureID; 1952 dialog.Data.ImageID = textureID;
1956 dialog.Data.ChatChannel = ch; 1953 dialog.Data.ChatChannel = ch;
1957 ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length]; 1954 ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length];
1958 for (int i = 0; i < buttonlabels.Length; i++) 1955 for (int i = 0; i < buttonlabels.Length; i++)
1959 { 1956 {
1960 buttons[i] = new ScriptDialogPacket.ButtonsBlock(); 1957 buttons[i] = new ScriptDialogPacket.ButtonsBlock();
1961 buttons[i].ButtonLabel = Utils.StringToBytes(buttonlabels[i]); 1958 buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]);
1962 } 1959 }
1963 dialog.Buttons = buttons; 1960 dialog.Buttons = buttons;
1964 OutPacket(dialog, ThrottleOutPacketType.Task); 1961 OutPacket(dialog, ThrottleOutPacketType.Task);
@@ -2114,19 +2111,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2114 avatarReply.AgentData.AgentID = AgentId; 2111 avatarReply.AgentData.AgentID = AgentId;
2115 avatarReply.AgentData.AvatarID = avatarID; 2112 avatarReply.AgentData.AvatarID = avatarID;
2116 if (aboutText != null) 2113 if (aboutText != null)
2117 avatarReply.PropertiesData.AboutText = Utils.StringToBytes(aboutText); 2114 avatarReply.PropertiesData.AboutText = Util.StringToBytes1024(aboutText);
2118 else 2115 else
2119 avatarReply.PropertiesData.AboutText = Utils.StringToBytes(""); 2116 avatarReply.PropertiesData.AboutText = Utils.EmptyBytes;
2120 avatarReply.PropertiesData.BornOn = Utils.StringToBytes(bornOn); 2117 avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn);
2121 avatarReply.PropertiesData.CharterMember = charterMember; 2118 avatarReply.PropertiesData.CharterMember = charterMember;
2122 if (flAbout != null) 2119 if (flAbout != null)
2123 avatarReply.PropertiesData.FLAboutText = Utils.StringToBytes(flAbout); 2120 avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout);
2124 else 2121 else
2125 avatarReply.PropertiesData.FLAboutText = Utils.StringToBytes(""); 2122 avatarReply.PropertiesData.FLAboutText = Utils.EmptyBytes;
2126 avatarReply.PropertiesData.Flags = flags; 2123 avatarReply.PropertiesData.Flags = flags;
2127 avatarReply.PropertiesData.FLImageID = flImageID; 2124 avatarReply.PropertiesData.FLImageID = flImageID;
2128 avatarReply.PropertiesData.ImageID = imageID; 2125 avatarReply.PropertiesData.ImageID = imageID;
2129 avatarReply.PropertiesData.ProfileURL = Utils.StringToBytes(profileURL); 2126 avatarReply.PropertiesData.ProfileURL = Util.StringToBytes256(profileURL);
2130 avatarReply.PropertiesData.PartnerID = partnerID; 2127 avatarReply.PropertiesData.PartnerID = partnerID;
2131 OutPacket(avatarReply, ThrottleOutPacketType.Task); 2128 OutPacket(avatarReply, ThrottleOutPacketType.Task);
2132 } 2129 }
@@ -2253,7 +2250,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2253 Group.Contribution = GroupMembership[i].Contribution; 2250 Group.Contribution = GroupMembership[i].Contribution;
2254 Group.GroupID = GroupMembership[i].GroupID; 2251 Group.GroupID = GroupMembership[i].GroupID;
2255 Group.GroupInsigniaID = GroupMembership[i].GroupPicture; 2252 Group.GroupInsigniaID = GroupMembership[i].GroupPicture;
2256 Group.GroupName = Utils.StringToBytes(GroupMembership[i].GroupName); 2253 Group.GroupName = Util.StringToBytes256(GroupMembership[i].GroupName);
2257 Group.GroupPowers = GroupMembership[i].GroupPowers; 2254 Group.GroupPowers = GroupMembership[i].GroupPowers;
2258 Groups[i] = Group; 2255 Groups[i] = Group;
2259 2256
@@ -2287,7 +2284,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2287 UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; 2284 UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1];
2288 UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); 2285 UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock();
2289 uidnamebloc.ID = groupLLUID; 2286 uidnamebloc.ID = groupLLUID;
2290 uidnamebloc.GroupName = Utils.StringToBytes(GroupName); 2287 uidnamebloc.GroupName = Util.StringToBytes256(GroupName);
2291 uidnameblock[0] = uidnamebloc; 2288 uidnameblock[0] = uidnamebloc;
2292 pack.UUIDNameBlock = uidnameblock; 2289 pack.UUIDNameBlock = uidnameblock;
2293 OutPacket(pack, ThrottleOutPacketType.Task); 2290 OutPacket(pack, ThrottleOutPacketType.Task);
@@ -2312,8 +2309,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2312 lsrepdb.Score = lsrpia[i].Score; 2309 lsrepdb.Score = lsrpia[i].Score;
2313 lsrepdb.TaskID = lsrpia[i].TaskID; 2310 lsrepdb.TaskID = lsrpia[i].TaskID;
2314 lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; 2311 lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID;
2315 lsrepdb.TaskName = Utils.StringToBytes(lsrpia[i].TaskName); 2312 lsrepdb.TaskName = Util.StringToBytes256(lsrpia[i].TaskName);
2316 lsrepdb.OwnerName = Utils.StringToBytes(lsrpia[i].OwnerName); 2313 lsrepdb.OwnerName = Util.StringToBytes256(lsrpia[i].OwnerName);
2317 lsrepdba[i] = lsrepdb; 2314 lsrepdba[i] = lsrepdb;
2318 } 2315 }
2319 lsrp.ReportData = lsrepdba; 2316 lsrp.ReportData = lsrepdba;
@@ -3255,127 +3252,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3255 canUseImproved = false; 3252 canUseImproved = false;
3256 } 3253 }
3257 } 3254 }
3258 }
3259
3260 static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlockFromPrim(SceneObjectPart prim, UUID assetID, PrimFlags flags, uint crc)
3261 {
3262 byte[] objectData = new byte[60];
3263 prim.OffsetPosition.ToBytes(objectData, 0);
3264 prim.Velocity.ToBytes(objectData, 12);
3265 prim.Acceleration.ToBytes(objectData, 24);
3266 prim.RotationOffset.ToBytes(objectData, 36);
3267 prim.AngularVelocity.ToBytes(objectData, 48);
3268
3269 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
3270 update.ClickAction = (byte)prim.ClickAction;
3271 update.CRC = crc;
3272 update.ExtraParams = prim.Shape.ExtraParams ?? Utils.EmptyBytes;
3273 update.Flags = (byte)flags;
3274 update.FullID = prim.UUID;
3275 update.ID = prim.LocalId;
3276 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
3277 //update.JointPivot = Vector3.Zero;
3278 //update.JointType = 0;
3279 update.Material = prim.Material;
3280 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
3281 if (prim.IsAttachment)
3282 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + assetID);
3283 else
3284 update.NameValue = Utils.EmptyBytes;
3285 update.ObjectData = objectData;
3286 update.ParentID = prim.ParentID;
3287 update.PathBegin = prim.Shape.PathBegin;
3288 update.PathCurve = prim.Shape.PathCurve;
3289 update.PathEnd = prim.Shape.PathEnd;
3290 update.PathRadiusOffset = prim.Shape.PathRadiusOffset;
3291 update.PathRevolutions = prim.Shape.PathRevolutions;
3292 update.PathScaleX = prim.Shape.PathScaleX;
3293 update.PathScaleY = prim.Shape.PathScaleY;
3294 update.PathShearX = prim.Shape.PathShearX;
3295 update.PathShearY = prim.Shape.PathShearY;
3296 update.PathSkew = prim.Shape.PathSkew;
3297 update.PathTaperX = prim.Shape.PathTaperX;
3298 update.PathTaperY = prim.Shape.PathTaperY;
3299 update.PathTwist = prim.Shape.PathTwist;
3300 update.PathTwistBegin = prim.Shape.PathTwistBegin;
3301 update.PCode = prim.Shape.PCode;
3302 update.ProfileBegin = prim.Shape.ProfileBegin;
3303 update.ProfileCurve = prim.Shape.ProfileCurve;
3304 update.ProfileEnd = prim.Shape.ProfileEnd;
3305 update.ProfileHollow = prim.Shape.ProfileHollow;
3306 update.PSBlock = prim.ParticleSystem ?? Utils.EmptyBytes;
3307 update.TextColor = new Color4(prim.Color).GetBytes(true);
3308 update.TextureAnim = prim.TextureAnimation ?? Utils.EmptyBytes;
3309 update.TextureEntry = prim.Shape.TextureEntry ?? Utils.EmptyBytes;
3310 update.Scale = prim.Scale;
3311 update.State = prim.Shape.State;
3312 update.Text = Util.StringToBytes256(prim.Text);
3313 update.UpdateFlags = (uint)flags;
3314
3315 if (prim.Sound != UUID.Zero)
3316 {
3317 update.Sound = prim.Sound;
3318 update.OwnerID = prim.OwnerID;
3319 update.Gain = (float)prim.SoundGain;
3320 update.Radius = (float)prim.SoundRadius;
3321 }
3322
3323 switch ((PCode)prim.Shape.PCode)
3324 {
3325 case PCode.Grass:
3326 case PCode.Tree:
3327 case PCode.NewTree:
3328 update.Data = new byte[] { prim.Shape.State };
3329 break;
3330 default:
3331 // TODO: Support ScratchPad
3332 //if (prim.ScratchPad != null)
3333 //{
3334 // update.Data = new byte[prim.ScratchPad.Length];
3335 // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length);
3336 //}
3337 //else
3338 //{
3339 // update.Data = Utils.EmptyBytes;
3340 //}
3341 update.Data = Utils.EmptyBytes;
3342 break;
3343 }
3344
3345 return update;
3346 }*/ 3255 }*/
3347 3256
3348 #endregion Prim/Avatar Updates 3257 #endregion Prim/Avatar Updates
3349 3258
3350 #region Avatar Packet/data sending Methods 3259 #region Avatar Packet/Data Sending Methods
3351 3260
3352 /// <summary> 3261 /// <summary>
3353 /// send a objectupdate packet with information about the clients avatar 3262 /// Send an ObjectUpdate packet with information about an avatar
3354 /// </summary> 3263 /// </summary>
3355 public void SendAvatarData(SendAvatarData data) 3264 public void SendAvatarData(SendAvatarData data)
3356 { 3265 {
3357 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3266 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3358 // TODO: don't create new blocks if recycling an old packet 3267 objupdate.Header.Zerocoded = true;
3359 objupdate.RegionData.RegionHandle = data.regionHandle; 3268
3269 objupdate.RegionData.RegionHandle = data.RegionHandle;
3360 objupdate.RegionData.TimeDilation = ushort.MaxValue; 3270 objupdate.RegionData.TimeDilation = ushort.MaxValue;
3271
3361 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3272 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3362 objupdate.ObjectData[0] = CreateDefaultAvatarPacket(data.textureEntry); 3273 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data);
3363
3364 //give this avatar object a local id and assign the user a name
3365 objupdate.ObjectData[0].ID = data.avatarLocalID;
3366 objupdate.ObjectData[0].FullID = data.avatarID;
3367 objupdate.ObjectData[0].ParentID = data.parentID;
3368 objupdate.ObjectData[0].NameValue =
3369 Utils.StringToBytes("FirstName STRING RW SV " + data.firstName + "\nLastName STRING RW SV " + data.lastName + "\nTitle STRING RW SV " + data.grouptitle);
3370
3371 Vector3 pos2 = new Vector3(data.Pos.X, data.Pos.Y, data.Pos.Z);
3372 byte[] pb = pos2.GetBytes();
3373 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
3374 3274
3375 byte[] rot = data.rotation.GetBytes();
3376 Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length);
3377
3378 objupdate.Header.Zerocoded = true;
3379 OutPacket(objupdate, ThrottleOutPacketType.Task); 3275 OutPacket(objupdate, ThrottleOutPacketType.Task);
3380 } 3276 }
3381 3277
@@ -3385,49 +3281,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3385 /// </summary> 3281 /// </summary>
3386 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) 3282 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
3387 { 3283 {
3388 if (data.priority == double.NaN) 3284 if (data.Priority == double.NaN)
3389 { 3285 {
3390 m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update"); 3286 m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update");
3391 return; 3287 return;
3392 } 3288 }
3393 3289
3394 Quaternion rotation = data.rotation; 3290 Quaternion rotation = data.Rotation;
3395 3291
3396 if (rotation.X == rotation.Y && 3292 if (rotation.X == rotation.Y &&
3397 rotation.Y == rotation.Z && 3293 rotation.Y == rotation.Z &&
3398 rotation.Z == rotation.W && rotation.W == 0) 3294 rotation.Z == rotation.W && rotation.W == 0.0f)
3399 rotation = Quaternion.Identity; 3295 rotation = Quaternion.Identity;
3400 3296
3401 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = 3297 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data);
3402 CreateAvatarImprovedBlock(data.localID, data.position, data.velocity, rotation); 3298
3403
3404 lock (m_avatarTerseUpdates.SyncRoot) 3299 lock (m_avatarTerseUpdates.SyncRoot)
3405 m_avatarTerseUpdates.Enqueue(data.priority, terseBlock, data.localID); 3300 m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID);
3301
3302 // If we received an update about our own avatar, process the avatar update priority queue immediately
3303 if (data.AgentID == m_agentId)
3304 ProcessAvatarTerseUpdates();
3406 } 3305 }
3407 3306
3408 private void ProcessAvatarTerseUpdates() 3307 private void ProcessAvatarTerseUpdates()
3409 { 3308 {
3410 lock (m_avatarTerseUpdates.SyncRoot) 3309 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3411 { 3310 terse.Header.Reliable = false;
3412 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 3311 terse.Header.Zerocoded = true;
3413
3414 terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
3415 3312
3416 terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; 3313 //terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
3417 terse.RegionData.TimeDilation = 3314 terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
3418 (ushort)(Scene.TimeDilation * ushort.MaxValue); 3315 terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3419 3316
3317 lock (m_avatarTerseUpdates.SyncRoot)
3318 {
3420 int count = Math.Min(m_avatarTerseUpdates.Count, m_avatarTerseUpdatesPerPacket); 3319 int count = Math.Min(m_avatarTerseUpdates.Count, m_avatarTerseUpdatesPerPacket);
3320 if (count == 0)
3321 return;
3421 3322
3422 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; 3323 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
3423 for (int i = 0; i < count; i++) 3324 for (int i = 0; i < count; i++)
3424 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); 3325 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3425
3426 terse.Header.Reliable = false;
3427 terse.Header.Zerocoded = true;
3428
3429 OutPacket(terse, ThrottleOutPacketType.Task);
3430 } 3326 }
3327
3328 OutPacket(terse, ThrottleOutPacketType.Task);
3431 } 3329 }
3432 3330
3433 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 3331 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
@@ -3466,33 +3364,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3466 OutPacket(loc, ThrottleOutPacketType.Task); 3364 OutPacket(loc, ThrottleOutPacketType.Task);
3467 } 3365 }
3468 3366
3469 #endregion 3367 #endregion Avatar Packet/Data Sending Methods
3470 3368
3471 #region Primitive Packet/data Sending Methods 3369 #region Primitive Packet/Data Sending Methods
3472
3473 /// <summary>
3474 ///
3475 /// </summary>
3476 /// <param name="localID"></param>
3477 /// <param name="rotation"></param>
3478 /// <param name="attachPoint"></param>
3479 public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID)
3480 {
3481 if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD
3482 return;
3483
3484 ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach);
3485 // TODO: don't create new blocks if recycling an old packet
3486 attach.AgentData.AgentID = AgentId;
3487 attach.AgentData.SessionID = m_sessionId;
3488 attach.AgentData.AttachmentPoint = attachPoint;
3489 attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
3490 attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
3491 attach.ObjectData[0].ObjectLocalID = localID;
3492 attach.ObjectData[0].Rotation = rotation;
3493 attach.Header.Zerocoded = true;
3494 OutPacket(attach, ThrottleOutPacketType.Task);
3495 }
3496 3370
3497 public void SendPrimitiveToClient(SendPrimitiveData data) 3371 public void SendPrimitiveToClient(SendPrimitiveData data)
3498 { 3372 {
@@ -3508,198 +3382,115 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3508 return; 3382 return;
3509 if (data.primShape.PCode == 9 && data.primShape.State != 0 && data.parentID == 0) 3383 if (data.primShape.PCode == 9 && data.primShape.State != 0 && data.parentID == 0)
3510 return; 3384 return;
3511 3385
3512 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0.0f) 3386 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0.0f)
3513 rotation = Quaternion.Identity; 3387 rotation = Quaternion.Identity;
3514 3388
3515 ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data.primShape, data.flags); 3389 ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data);
3516
3517 objectData.ID = data.localID;
3518 objectData.FullID = data.objectID;
3519 objectData.OwnerID = data.ownerID;
3520
3521 objectData.Text = Util.StringToBytes256(data.text);
3522 objectData.TextColor[0] = data.color[0];
3523 objectData.TextColor[1] = data.color[1];
3524 objectData.TextColor[2] = data.color[2];
3525 objectData.TextColor[3] = data.color[3];
3526 objectData.ParentID = data.parentID;
3527 objectData.PSBlock = data.particleSystem;
3528 objectData.ClickAction = data.clickAction;
3529 objectData.Material = data.material;
3530 objectData.Flags = 0;
3531
3532 if (data.attachment)
3533 {
3534 // Necessary???
3535 objectData.JointAxisOrAnchor = new Vector3(0, 0, 2);
3536 objectData.JointPivot = new Vector3(0, 0, 0);
3537
3538 // Item from inventory???
3539 objectData.NameValue =
3540 Utils.StringToBytes("AttachItemID STRING RW SV " + data.AssetId.Guid);
3541 objectData.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16));
3542 }
3543
3544 // Xantor 20080528: Send sound info as well
3545 // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again
3546 objectData.Sound = data.SoundId;
3547 if (data.SoundId == UUID.Zero)
3548 {
3549 objectData.OwnerID = UUID.Zero;
3550 objectData.Gain = 0.0f;
3551 objectData.Radius = 0.0f;
3552 objectData.Flags = 0;
3553 }
3554 else
3555 {
3556 objectData.OwnerID = data.ownerID;
3557 objectData.Gain = (float)data.SoundVolume;
3558 objectData.Radius = (float)data.SoundRadius;
3559 objectData.Flags = data.SoundFlags;
3560 }
3561
3562 byte[] pb = data.pos.GetBytes();
3563 Buffer.BlockCopy(pb, 0, objectData.ObjectData, 0, pb.Length);
3564
3565 byte[] vel = data.vel.GetBytes();
3566 Buffer.BlockCopy(vel, 0, objectData.ObjectData, pb.Length, vel.Length);
3567
3568 byte[] rot = rotation.GetBytes();
3569 Buffer.BlockCopy(rot, 0, objectData.ObjectData, 36, rot.Length);
3570
3571 byte[] rvel = data.rvel.GetBytes();
3572 Buffer.BlockCopy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length);
3573
3574 if (data.textureanim.Length > 0)
3575 {
3576 objectData.TextureAnim = data.textureanim;
3577 }
3578 3390
3579 lock (m_primFullUpdates.SyncRoot) 3391 lock (m_primFullUpdates.SyncRoot)
3580 m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); 3392 m_primFullUpdates.Enqueue(data.priority, objectData, data.localID);
3581 } 3393 }
3582 3394
3583 void HandleQueueEmpty(ThrottleOutPacketType queue) 3395 void ProcessPrimFullUpdates()
3584 { 3396 {
3585 int count = 0; 3397 ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3398 outPacket.Header.Zerocoded = true;
3586 3399
3587 switch (queue) 3400 //outPacket.RegionData = new ObjectUpdatePacket.RegionDataBlock();
3588 { 3401 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
3589 case ThrottleOutPacketType.Texture: 3402 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3590 ProcessTextureRequests();
3591 break;
3592 case ThrottleOutPacketType.Task:
3593 lock (m_avatarTerseUpdates.SyncRoot)
3594 count = m_avatarTerseUpdates.Count;
3595 if (count > 0)
3596 {
3597 ProcessAvatarTerseUpdates();
3598 return;
3599 }
3600 break;
3601 case ThrottleOutPacketType.State:
3602 lock (m_primFullUpdates.SyncRoot)
3603 count = m_primFullUpdates.Count;
3604 if (count > 0)
3605 {
3606 ProcessPrimFullUpdates();
3607 return;
3608 }
3609
3610 lock (m_primTerseUpdates.SyncRoot)
3611 count = m_primTerseUpdates.Count;
3612 if (count > 0)
3613 {
3614 ProcessPrimTerseUpdates();
3615 return;
3616 }
3617 break;
3618 }
3619 }
3620 3403
3621 void ProcessTextureRequests()
3622 {
3623 if (m_imageManager != null)
3624 m_imageManager.ProcessImageQueue(m_textureSendLimit);
3625 }
3626
3627 void ProcessPrimFullUpdates()
3628 {
3629 lock (m_primFullUpdates.SyncRoot) 3404 lock (m_primFullUpdates.SyncRoot)
3630 { 3405 {
3631 ObjectUpdatePacket outPacket =
3632 (ObjectUpdatePacket)PacketPool.Instance.GetPacket(
3633 PacketType.ObjectUpdate);
3634
3635 outPacket.RegionData.RegionHandle =
3636 Scene.RegionInfo.RegionHandle;
3637 outPacket.RegionData.TimeDilation =
3638 (ushort)(Scene.TimeDilation * ushort.MaxValue);
3639
3640 int count = Math.Min(m_primFullUpdates.Count, m_primFullUpdatesPerPacket); 3406 int count = Math.Min(m_primFullUpdates.Count, m_primFullUpdatesPerPacket);
3407 if (count == 0)
3408 return;
3641 3409
3642 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[count]; 3410 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[count];
3643 for (int i = 0; i < count; i++) 3411 for (int i = 0; i < count; i++)
3644 outPacket.ObjectData[i] = m_primFullUpdates.Dequeue(); 3412 outPacket.ObjectData[i] = m_primFullUpdates.Dequeue();
3645
3646 outPacket.Header.Zerocoded = true;
3647 OutPacket(outPacket, ThrottleOutPacketType.State);
3648 } 3413 }
3414
3415 OutPacket(outPacket, ThrottleOutPacketType.State);
3649 } 3416 }
3650 3417
3651 /// <summary>
3652 ///
3653 /// </summary>
3654 //public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
3655 // Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint)
3656 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 3418 public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
3657 { 3419 {
3658 if (data.priority == double.NaN) 3420 if (data.Priority == double.NaN)
3659 { 3421 {
3660 m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); 3422 m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update");
3661 return; 3423 return;
3662 } 3424 }
3663 3425
3664 Quaternion rotation = data.rotation; 3426 Quaternion rotation = data.Rotation;
3665 3427
3666 if (data.attachPoint > 30 && data.owner != AgentId) // Someone else's HUD 3428 if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD
3667 return; 3429 return;
3668 3430
3669 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) 3431 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0)
3670 rotation = Quaternion.Identity; 3432 rotation = Quaternion.Identity;
3671 3433
3672 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = 3434 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data);
3673 CreatePrimImprovedBlock(data.localID, data.position, rotation,
3674 data.velocity, data.rotationalvelocity, data.state);
3675 3435
3676 lock (m_primTerseUpdates.SyncRoot) 3436 lock (m_primTerseUpdates.SyncRoot)
3677 m_primTerseUpdates.Enqueue(data.priority, objectData, data.localID); 3437 m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID);
3678 } 3438 }
3679 3439
3680 void ProcessPrimTerseUpdates() 3440 void ProcessPrimTerseUpdates()
3681 { 3441 {
3682 lock (m_primTerseUpdates.SyncRoot) 3442 ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3683 { 3443 outPacket.Header.Reliable = false;
3684 ImprovedTerseObjectUpdatePacket outPacket = 3444 outPacket.Header.Zerocoded = true;
3685 (ImprovedTerseObjectUpdatePacket)
3686 PacketPool.Instance.GetPacket(
3687 PacketType.ImprovedTerseObjectUpdate);
3688 3445
3689 outPacket.RegionData.RegionHandle = 3446 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
3690 Scene.RegionInfo.RegionHandle; 3447 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3691 outPacket.RegionData.TimeDilation =
3692 (ushort)(Scene.TimeDilation * ushort.MaxValue);
3693 3448
3449 lock (m_primTerseUpdates.SyncRoot)
3450 {
3694 int count = Math.Min(m_primTerseUpdates.Count, m_primTerseUpdatesPerPacket); 3451 int count = Math.Min(m_primTerseUpdates.Count, m_primTerseUpdatesPerPacket);
3452 if (count == 0)
3453 return;
3695 3454
3696 outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; 3455 outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
3697 for (int i = 0; i < count; i++) 3456 for (int i = 0; i < count; i++)
3698 outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue(); 3457 outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue();
3458 }
3459
3460 OutPacket(outPacket, ThrottleOutPacketType.State);
3461 }
3462
3463 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
3464 {
3465 PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler =
3466 delegate(ref double priority, uint local_id)
3467 {
3468 priority = handler(new UpdatePriorityData(priority, local_id));
3469 return priority != double.NaN;
3470 };
3471 PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler =
3472 delegate(ref double priority, uint local_id)
3473 {
3474 priority = handler(new UpdatePriorityData(priority, local_id));
3475 return priority != double.NaN;
3476 };
3699 3477
3700 outPacket.Header.Reliable = false; 3478 if ((type & StateUpdateTypes.AvatarTerse) != 0)
3701 outPacket.Header.Zerocoded = true; 3479 {
3702 OutPacket(outPacket, ThrottleOutPacketType.State); 3480 lock (m_avatarTerseUpdates.SyncRoot)
3481 m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler);
3482 }
3483
3484 if ((type & StateUpdateTypes.PrimitiveFull) != 0)
3485 {
3486 lock (m_primFullUpdates.SyncRoot)
3487 m_primFullUpdates.Reprioritize(update_priority_handler);
3488 }
3489
3490 if ((type & StateUpdateTypes.PrimitiveTerse) != 0)
3491 {
3492 lock (m_primTerseUpdates.SyncRoot)
3493 m_primTerseUpdates.Reprioritize(terse_update_priority_handler);
3703 } 3494 }
3704 } 3495 }
3705 3496
@@ -3719,6 +3510,90 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3719 } 3510 }
3720 } 3511 }
3721 3512
3513 #endregion Primitive Packet/Data Sending Methods
3514
3515 /// <summary>
3516 ///
3517 /// </summary>
3518 /// <param name="localID"></param>
3519 /// <param name="rotation"></param>
3520 /// <param name="attachPoint"></param>
3521 public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID)
3522 {
3523 if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD
3524 return;
3525
3526 ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach);
3527 // TODO: don't create new blocks if recycling an old packet
3528 attach.AgentData.AgentID = AgentId;
3529 attach.AgentData.SessionID = m_sessionId;
3530 attach.AgentData.AttachmentPoint = attachPoint;
3531 attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
3532 attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
3533 attach.ObjectData[0].ObjectLocalID = localID;
3534 attach.ObjectData[0].Rotation = rotation;
3535 attach.Header.Zerocoded = true;
3536 OutPacket(attach, ThrottleOutPacketType.Task);
3537 }
3538
3539 void HandleQueueEmpty(ThrottleOutPacketType queue)
3540 {
3541 switch (queue)
3542 {
3543 case ThrottleOutPacketType.Texture:
3544 ProcessTextureRequests();
3545 break;
3546 case ThrottleOutPacketType.Task:
3547 if (Monitor.TryEnter(m_avatarTerseUpdates.SyncRoot, 1))
3548 {
3549 try
3550 {
3551 if (m_avatarTerseUpdates.Count > 0)
3552 {
3553
3554 ProcessAvatarTerseUpdates();
3555 return;
3556 }
3557 }
3558 finally { Monitor.Exit(m_avatarTerseUpdates.SyncRoot); }
3559 }
3560 break;
3561 case ThrottleOutPacketType.State:
3562 if (Monitor.TryEnter(m_primFullUpdates.SyncRoot, 1))
3563 {
3564 try
3565 {
3566 if (m_primFullUpdates.Count > 0)
3567 {
3568 ProcessPrimFullUpdates();
3569 return;
3570 }
3571 }
3572 finally { Monitor.Exit(m_primFullUpdates.SyncRoot); }
3573 }
3574
3575 if (Monitor.TryEnter(m_primTerseUpdates.SyncRoot, 1))
3576 {
3577 try
3578 {
3579 if (m_primTerseUpdates.Count > 0)
3580 {
3581 ProcessPrimTerseUpdates();
3582 return;
3583 }
3584 }
3585 finally { Monitor.Exit(m_primTerseUpdates.SyncRoot); }
3586 }
3587 break;
3588 }
3589 }
3590
3591 void ProcessTextureRequests()
3592 {
3593 if (m_imageManager != null)
3594 m_imageManager.ProcessImageQueue(m_textureSendLimit);
3595 }
3596
3722 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 3597 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
3723 { 3598 {
3724 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); 3599 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
@@ -3900,8 +3775,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3900 OutPacket(proper, ThrottleOutPacketType.Task); 3775 OutPacket(proper, ThrottleOutPacketType.Task);
3901 } 3776 }
3902 3777
3903 #endregion
3904
3905 #region Estate Data Sending Methods 3778 #region Estate Data Sending Methods
3906 3779
3907 private static bool convertParamStringToBool(byte[] field) 3780 private static bool convertParamStringToBool(byte[] field)
@@ -4308,325 +4181,221 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4308 4181
4309 #region Helper Methods 4182 #region Helper Methods
4310 4183
4311 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, Vector3 pos, 4184 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data)
4312 Vector3 velocity,
4313 Quaternion rotation)
4314 { 4185 {
4315 byte[] bytes = new byte[60]; 4186 return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity,
4316 int i = 0; 4187 data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry);
4317 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = PacketPool.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
4318
4319 dat.TextureEntry = new byte[0]; // AvatarTemplate.TextureEntry;
4320
4321 uint ID = localID;
4322
4323 bytes[i++] = (byte)(ID % 256);
4324 bytes[i++] = (byte)((ID >> 8) % 256);
4325 bytes[i++] = (byte)((ID >> 16) % 256);
4326 bytes[i++] = (byte)((ID >> 24) % 256);
4327 bytes[i++] = 0;
4328 bytes[i++] = 1;
4329 i += 14;
4330 bytes[i++] = 128;
4331 bytes[i++] = 63;
4332
4333 byte[] pb = pos.GetBytes();
4334 Array.Copy(pb, 0, bytes, i, pb.Length);
4335 i += 12;
4336
4337 Vector3 internDirec = new Vector3(velocity.X, velocity.Y, velocity.Z);
4338
4339 internDirec = internDirec / 128.0f;
4340 internDirec.X += 1;
4341 internDirec.Y += 1;
4342 internDirec.Z += 1;
4343
4344 ushort InternVelocityX = (ushort)(32768 * internDirec.X);
4345 ushort InternVelocityY = (ushort)(32768 * internDirec.Y);
4346 ushort InternVelocityZ = (ushort)(32768 * internDirec.Z);
4347
4348 ushort ac = 32767;
4349 bytes[i++] = (byte)(InternVelocityX % 256);
4350 bytes[i++] = (byte)((InternVelocityX >> 8) % 256);
4351 bytes[i++] = (byte)(InternVelocityY % 256);
4352 bytes[i++] = (byte)((InternVelocityY >> 8) % 256);
4353 bytes[i++] = (byte)(InternVelocityZ % 256);
4354 bytes[i++] = (byte)((InternVelocityZ >> 8) % 256);
4355
4356 //accel
4357 bytes[i++] = (byte)(ac % 256);
4358 bytes[i++] = (byte)((ac >> 8) % 256);
4359 bytes[i++] = (byte)(ac % 256);
4360 bytes[i++] = (byte)((ac >> 8) % 256);
4361 bytes[i++] = (byte)(ac % 256);
4362 bytes[i++] = (byte)((ac >> 8) % 256);
4363
4364 //rotation
4365 ushort rw, rx, ry, rz;
4366 rw = (ushort)(32768 * (rotation.W + 1));
4367 rx = (ushort)(32768 * (rotation.X + 1));
4368 ry = (ushort)(32768 * (rotation.Y + 1));
4369 rz = (ushort)(32768 * (rotation.Z + 1));
4370
4371 //rot
4372 bytes[i++] = (byte)(rx % 256);
4373 bytes[i++] = (byte)((rx >> 8) % 256);
4374 bytes[i++] = (byte)(ry % 256);
4375 bytes[i++] = (byte)((ry >> 8) % 256);
4376 bytes[i++] = (byte)(rz % 256);
4377 bytes[i++] = (byte)((rz >> 8) % 256);
4378 bytes[i++] = (byte)(rw % 256);
4379 bytes[i++] = (byte)((rw >> 8) % 256);
4380
4381 //rotation vel
4382 bytes[i++] = (byte)(ac % 256);
4383 bytes[i++] = (byte)((ac >> 8) % 256);
4384 bytes[i++] = (byte)(ac % 256);
4385 bytes[i++] = (byte)((ac >> 8) % 256);
4386 bytes[i++] = (byte)(ac % 256);
4387 bytes[i++] = (byte)((ac >> 8) % 256);
4388
4389 dat.Data = bytes;
4390
4391 return (dat);
4392 } 4188 }
4393 4189
4394 /// <summary> 4190 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data)
4395 ///
4396 /// </summary>
4397 /// <param name="localID"></param>
4398 /// <param name="position"></param>
4399 /// <param name="rotation"></param>
4400 /// <returns></returns>
4401 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID,
4402 Vector3 position,
4403 Quaternion rotation,
4404 Vector3 velocity,
4405 Vector3 rotationalvelocity,
4406 byte state)
4407 { 4191 {
4408 uint ID = localID; 4192 return CreateImprovedTerseBlock(false, data.LocalID, data.State, Vector4.Zero, data.Position, data.Velocity,
4409 byte[] bytes = new byte[60]; 4193 data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry);
4410
4411 int i = 0;
4412 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = PacketPool.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
4413 dat.TextureEntry = new byte[0];
4414 bytes[i++] = (byte)(ID % 256);
4415 bytes[i++] = (byte)((ID >> 8) % 256);
4416 bytes[i++] = (byte)((ID >> 16) % 256);
4417 bytes[i++] = (byte)((ID >> 24) % 256);
4418 bytes[i++] = (byte)(((state & 0xf0) >> 4) | ((state & 0x0f) << 4));
4419 bytes[i++] = 0;
4420
4421 byte[] pb = position.GetBytes();
4422 Array.Copy(pb, 0, bytes, i, pb.Length);
4423 i += 12;
4424 ushort ac = 32767;
4425
4426 ushort velx, vely, velz;
4427 Vector3 vel = new Vector3(velocity.X, velocity.Y, velocity.Z);
4428
4429 vel = vel / 128.0f;
4430 vel.X += 1;
4431 vel.Y += 1;
4432 vel.Z += 1;
4433 //vel
4434 velx = (ushort)(32768 * (vel.X));
4435 vely = (ushort)(32768 * (vel.Y));
4436 velz = (ushort)(32768 * (vel.Z));
4437
4438 bytes[i++] = (byte)(velx % 256);
4439 bytes[i++] = (byte)((velx >> 8) % 256);
4440 bytes[i++] = (byte)(vely % 256);
4441 bytes[i++] = (byte)((vely >> 8) % 256);
4442 bytes[i++] = (byte)(velz % 256);
4443 bytes[i++] = (byte)((velz >> 8) % 256);
4444
4445 //accel
4446 bytes[i++] = (byte)(ac % 256);
4447 bytes[i++] = (byte)((ac >> 8) % 256);
4448 bytes[i++] = (byte)(ac % 256);
4449 bytes[i++] = (byte)((ac >> 8) % 256);
4450 bytes[i++] = (byte)(ac % 256);
4451 bytes[i++] = (byte)((ac >> 8) % 256);
4452
4453 ushort rw, rx, ry, rz;
4454 rw = (ushort)(32768 * (rotation.W + 1));
4455 rx = (ushort)(32768 * (rotation.X + 1));
4456 ry = (ushort)(32768 * (rotation.Y + 1));
4457 rz = (ushort)(32768 * (rotation.Z + 1));
4458
4459 //rot
4460 bytes[i++] = (byte)(rx % 256);
4461 bytes[i++] = (byte)((rx >> 8) % 256);
4462 bytes[i++] = (byte)(ry % 256);
4463 bytes[i++] = (byte)((ry >> 8) % 256);
4464 bytes[i++] = (byte)(rz % 256);
4465 bytes[i++] = (byte)((rz >> 8) % 256);
4466 bytes[i++] = (byte)(rw % 256);
4467 bytes[i++] = (byte)((rw >> 8) % 256);
4468
4469 //rotation vel
4470 Vector3 rvel = new Vector3(rotationalvelocity.X, rotationalvelocity.Y, rotationalvelocity.Z);
4471
4472 rvel = rvel / 128.0f;
4473 rvel.X += 1;
4474 rvel.Y += 1;
4475 rvel.Z += 1;
4476 //vel
4477 ushort rvelx = (ushort)(32768 * (rvel.X));
4478 ushort rvely = (ushort)(32768 * (rvel.Y));
4479 ushort rvelz = (ushort)(32768 * (rvel.Z));
4480
4481 bytes[i++] = (byte)(rvelx % 256);
4482 bytes[i++] = (byte)((rvelx >> 8) % 256);
4483 bytes[i++] = (byte)(rvely % 256);
4484 bytes[i++] = (byte)((rvely >> 8) % 256);
4485 bytes[i++] = (byte)(rvelz % 256);
4486 bytes[i++] = (byte)((rvelz >> 8) % 256);
4487 dat.Data = bytes;
4488
4489 return dat;
4490 } 4194 }
4491 4195
4492 /// <summary> 4196 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, byte state,
4493 /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive) 4197 Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation,
4494 /// </summary> 4198 Vector3 angularVelocity, byte[] textureEntry)
4495 /// <param name="primData"></param> 4199 {
4496 /// <returns></returns> 4200 int pos = 0;
4497 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimitiveBaseShape primShape, uint flags) 4201 byte[] data = new byte[(avatar ? 60 : 44)];
4498 { 4202
4499 ObjectUpdatePacket.ObjectDataBlock objupdate = PacketPool.GetDataBlock<ObjectUpdatePacket.ObjectDataBlock>(); 4203 // LocalID
4500 SetDefaultPrimPacketValues(objupdate); 4204 Utils.UIntToBytes(localID, data, pos);
4501 objupdate.UpdateFlags = flags; 4205 pos += 4;
4502 SetPrimPacketShapeData(objupdate, primShape); 4206
4503 4207 // Avatar/CollisionPlane
4504 if ((primShape.PCode == (byte)PCode.NewTree) || (primShape.PCode == (byte)PCode.Tree) || (primShape.PCode == (byte)PCode.Grass)) 4208 data[pos++] = state;
4505 { 4209 if (avatar)
4506 objupdate.Data = new byte[1]; 4210 {
4507 objupdate.Data[0] = primShape.State; 4211 data[pos++] = 1;
4508 } 4212
4509 return objupdate; 4213 if (collisionPlane == Vector4.Zero)
4510 } 4214 collisionPlane = Vector4.UnitW;
4511 4215
4512 protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimitiveBaseShape primData) 4216 collisionPlane.ToBytes(data, pos);
4513 { 4217 pos += 16;
4514 objectData.TextureEntry = primData.TextureEntry; 4218 }
4515 objectData.PCode = primData.PCode; 4219 else
4516 objectData.State = primData.State; 4220 {
4517 objectData.PathBegin = primData.PathBegin; 4221 ++pos;
4518 objectData.PathEnd = primData.PathEnd; 4222 }
4519 objectData.PathScaleX = primData.PathScaleX; 4223
4520 objectData.PathScaleY = primData.PathScaleY; 4224 // Position
4521 objectData.PathShearX = primData.PathShearX; 4225 position.ToBytes(data, pos);
4522 objectData.PathShearY = primData.PathShearY; 4226 pos += 12;
4523 objectData.PathSkew = primData.PathSkew; 4227
4524 objectData.ProfileBegin = primData.ProfileBegin; 4228 // Velocity
4525 objectData.ProfileEnd = primData.ProfileEnd; 4229 Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2;
4526 objectData.Scale = primData.Scale; 4230 Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2;
4527 objectData.PathCurve = primData.PathCurve; 4231 Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2;
4528 objectData.ProfileCurve = primData.ProfileCurve; 4232
4529 objectData.ProfileHollow = primData.ProfileHollow; 4233 // Acceleration
4530 objectData.PathRadiusOffset = primData.PathRadiusOffset; 4234 Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2;
4531 objectData.PathRevolutions = primData.PathRevolutions; 4235 Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2;
4532 objectData.PathTaperX = primData.PathTaperX; 4236 Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2;
4533 objectData.PathTaperY = primData.PathTaperY; 4237
4534 objectData.PathTwist = primData.PathTwist; 4238 // Rotation
4535 objectData.PathTwistBegin = primData.PathTwistBegin; 4239 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.X, -1.0f, 1.0f), data, pos); pos += 2;
4536 objectData.ExtraParams = primData.ExtraParams; 4240 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Y, -1.0f, 1.0f), data, pos); pos += 2;
4241 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Z, -1.0f, 1.0f), data, pos); pos += 2;
4242 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2;
4243
4244 // Angular Velocity
4245 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2;
4246 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
4247 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
4248
4249 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
4250 block.Data = data;
4251
4252 if (textureEntry != null && textureEntry.Length > 0)
4253 {
4254 byte[] teBytesFinal = new byte[textureEntry.Length + 4];
4255
4256 // Texture Length
4257 Utils.IntToBytes(textureEntry.Length, textureEntry, 0);
4258 // Texture
4259 Buffer.BlockCopy(textureEntry, 0, teBytesFinal, 4, textureEntry.Length);
4260
4261 block.TextureEntry = teBytesFinal;
4262 }
4263 else
4264 {
4265 block.TextureEntry = Utils.EmptyBytes;
4266 }
4267
4268 return block;
4537 } 4269 }
4538 4270
4539 /// <summary> 4271 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data)
4540 /// Set some default values in a ObjectUpdatePacket 4272 {
4541 /// </summary> 4273 byte[] objectData = new byte[60];
4542 /// <param name="objdata"></param> 4274 data.Position.ToBytes(objectData, 0);
4543 protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata) 4275 //data.Velocity.ToBytes(objectData, 12);
4544 { 4276 //data.Acceleration.ToBytes(objectData, 24);
4545 objdata.PSBlock = new byte[0]; 4277 data.Rotation.ToBytes(objectData, 36);
4546 objdata.ExtraParams = new byte[1]; 4278 //data.AngularVelocity.ToBytes(objectData, 48);
4547 objdata.MediaURL = new byte[0]; 4279
4548 objdata.NameValue = new byte[0]; 4280 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
4549 objdata.Text = new byte[0]; 4281
4550 objdata.TextColor = new byte[4]; 4282 update.Data = Utils.EmptyBytes;
4551 objdata.JointAxisOrAnchor = new Vector3(0, 0, 0); 4283 update.ExtraParams = new byte[1];
4552 objdata.JointPivot = new Vector3(0, 0, 0); 4284 update.FullID = data.AvatarID;
4553 objdata.Material = 3; 4285 update.ID = data.AvatarLocalID;
4554 objdata.TextureAnim = new byte[0]; 4286 update.Material = (byte)Material.Flesh;
4555 objdata.Sound = UUID.Zero; 4287 update.MediaURL = Utils.EmptyBytes;
4556 objdata.State = 0; 4288 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " +
4557 objdata.Data = new byte[0]; 4289 data.LastName + "\nTitle STRING RW SV " + data.GroupTitle);
4558 4290 update.ObjectData = objectData;
4559 objdata.ObjectData = new byte[60]; 4291 update.ParentID = data.ParentID;
4560 objdata.ObjectData[46] = 128; 4292 update.PathCurve = 16;
4561 objdata.ObjectData[47] = 63; 4293 update.PathScaleX = 100;
4294 update.PathScaleY = 100;
4295 update.PCode = (byte)PCode.Avatar;
4296 update.ProfileCurve = 1;
4297 update.PSBlock = Utils.EmptyBytes;
4298 update.Scale = Vector3.One;
4299 update.Text = Utils.EmptyBytes;
4300 update.TextColor = new byte[4];
4301 update.TextureAnim = Utils.EmptyBytes;
4302 update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes;
4303 update.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); // TODO: Replace these numbers with PrimFlags
4304
4305 return update;
4562 } 4306 }
4563 4307
4564 /// <summary> 4308 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data)
4565 ///
4566 /// </summary>
4567 /// <returns></returns>
4568 public ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket(byte[] textureEntry)
4569 { 4309 {
4570 ObjectUpdatePacket.ObjectDataBlock objdata = PacketPool.GetDataBlock<ObjectUpdatePacket.ObjectDataBlock>(); 4310 byte[] objectData = new byte[60];
4571 // new OpenMetaverse.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); 4311 data.pos.ToBytes(objectData, 0);
4312 data.vel.ToBytes(objectData, 12);
4313 data.acc.ToBytes(objectData, 24);
4314 data.rotation.ToBytes(objectData, 36);
4315 data.rvel.ToBytes(objectData, 48);
4572 4316
4573 SetDefaultAvatarPacketValues(ref objdata); 4317 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
4574 objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); 4318 update.ClickAction = (byte)data.clickAction;
4575 objdata.PathCurve = 16; 4319 update.CRC = 0;
4576 objdata.ProfileCurve = 1; 4320 update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes;
4577 objdata.PathScaleX = 100; 4321 update.FullID = data.objectID;
4578 objdata.PathScaleY = 100; 4322 update.ID = data.localID;
4579 objdata.ParentID = 0; 4323 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
4580 objdata.OwnerID = UUID.Zero; 4324 //update.JointPivot = Vector3.Zero;
4581 objdata.Scale = new Vector3(1, 1, 1); 4325 //update.JointType = 0;
4582 objdata.PCode = (byte)PCode.Avatar; 4326 update.Material = data.material;
4583 if (textureEntry != null) 4327 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
4328 if (data.attachment)
4584 { 4329 {
4585 objdata.TextureEntry = textureEntry; 4330 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId);
4331 update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16));
4332 }
4333 else
4334 {
4335 update.NameValue = Utils.EmptyBytes;
4336 update.State = data.primShape.State;
4337 }
4338 update.ObjectData = objectData;
4339 update.ParentID = data.parentID;
4340 update.PathBegin = data.primShape.PathBegin;
4341 update.PathCurve = data.primShape.PathCurve;
4342 update.PathEnd = data.primShape.PathEnd;
4343 update.PathRadiusOffset = data.primShape.PathRadiusOffset;
4344 update.PathRevolutions = data.primShape.PathRevolutions;
4345 update.PathScaleX = data.primShape.PathScaleX;
4346 update.PathScaleY = data.primShape.PathScaleY;
4347 update.PathShearX = data.primShape.PathShearX;
4348 update.PathShearY = data.primShape.PathShearY;
4349 update.PathSkew = data.primShape.PathSkew;
4350 update.PathTaperX = data.primShape.PathTaperX;
4351 update.PathTaperY = data.primShape.PathTaperY;
4352 update.PathTwist = data.primShape.PathTwist;
4353 update.PathTwistBegin = data.primShape.PathTwistBegin;
4354 update.PCode = data.primShape.PCode;
4355 update.ProfileBegin = data.primShape.ProfileBegin;
4356 update.ProfileCurve = data.primShape.ProfileCurve;
4357 update.ProfileEnd = data.primShape.ProfileEnd;
4358 update.ProfileHollow = data.primShape.ProfileHollow;
4359 update.PSBlock = data.particleSystem ?? Utils.EmptyBytes;
4360 update.TextColor = data.color ?? Color4.Black.GetBytes(true);
4361 update.TextureAnim = data.textureanim ?? Utils.EmptyBytes;
4362 update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes;
4363 update.Scale = data.primShape.Scale;
4364 update.Text = Util.StringToBytes256(data.text);
4365 update.UpdateFlags = (uint)data.flags;
4366
4367 if (data.SoundId != UUID.Zero)
4368 {
4369 update.Sound = data.SoundId;
4370 update.OwnerID = data.ownerID;
4371 update.Gain = (float)data.SoundVolume;
4372 update.Radius = (float)data.SoundRadius;
4373 update.Flags = data.SoundFlags;
4374 }
4375
4376 switch ((PCode)data.primShape.PCode)
4377 {
4378 case PCode.Grass:
4379 case PCode.Tree:
4380 case PCode.NewTree:
4381 update.Data = new byte[] { data.primShape.State };
4382 break;
4383 default:
4384 // TODO: Support ScratchPad
4385 //if (prim.ScratchPad != null)
4386 //{
4387 // update.Data = new byte[prim.ScratchPad.Length];
4388 // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length);
4389 //}
4390 //else
4391 //{
4392 // update.Data = Utils.EmptyBytes;
4393 //}
4394 update.Data = Utils.EmptyBytes;
4395 break;
4586 } 4396 }
4587 Vector3 pos = new Vector3(objdata.ObjectData, 16);
4588 pos.X = 100f;
4589 objdata.ID = 8880000;
4590 objdata.NameValue = Utils.StringToBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User ");
4591 //Vector3 pos2 = new Vector3(100f, 100f, 23f);
4592 //objdata.FullID=user.AgentId;
4593 byte[] pb = pos.GetBytes();
4594 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
4595
4596 return objdata;
4597 }
4598 4397
4599 /// <summary> 4398 return update;
4600 ///
4601 /// </summary>
4602 /// <param name="objdata"></param>
4603 protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata)
4604 {
4605 objdata.PSBlock = new byte[0];
4606 objdata.ExtraParams = new byte[1];
4607 objdata.MediaURL = new byte[0];
4608 objdata.NameValue = new byte[0];
4609 objdata.Text = new byte[0];
4610 objdata.TextColor = new byte[4];
4611 objdata.JointAxisOrAnchor = new Vector3(0, 0, 0);
4612 objdata.JointPivot = new Vector3(0, 0, 0);
4613 objdata.Material = 4;
4614 objdata.TextureAnim = new byte[0];
4615 objdata.Sound = UUID.Zero;
4616 Primitive.TextureEntry ntex = new Primitive.TextureEntry(new UUID("00000000-0000-0000-5005-000000000005"));
4617 objdata.TextureEntry = ntex.GetBytes();
4618
4619 objdata.State = 0;
4620 objdata.Data = new byte[0];
4621
4622 objdata.ObjectData = new byte[76];
4623 objdata.ObjectData[15] = 128;
4624 objdata.ObjectData[16] = 63;
4625 objdata.ObjectData[56] = 128;
4626 objdata.ObjectData[61] = 102;
4627 objdata.ObjectData[62] = 40;
4628 objdata.ObjectData[63] = 61;
4629 objdata.ObjectData[64] = 189;
4630 } 4399 }
4631 4400
4632 public void SendNameReply(UUID profileId, string firstname, string lastname) 4401 public void SendNameReply(UUID profileId, string firstname, string lastname)
@@ -4636,8 +4405,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4636 packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1]; 4405 packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1];
4637 packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock(); 4406 packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock();
4638 packet.UUIDNameBlock[0].ID = profileId; 4407 packet.UUIDNameBlock[0].ID = profileId;
4639 packet.UUIDNameBlock[0].FirstName = Utils.StringToBytes(firstname); 4408 packet.UUIDNameBlock[0].FirstName = Util.StringToBytes256(firstname);
4640 packet.UUIDNameBlock[0].LastName = Utils.StringToBytes(lastname); 4409 packet.UUIDNameBlock[0].LastName = Util.StringToBytes256(lastname);
4641 4410
4642 OutPacket(packet, ThrottleOutPacketType.Task); 4411 OutPacket(packet, ThrottleOutPacketType.Task);
4643 } 4412 }
@@ -4833,8 +4602,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4833 scriptQuestion.Data.TaskID = taskID; 4602 scriptQuestion.Data.TaskID = taskID;
4834 scriptQuestion.Data.ItemID = itemID; 4603 scriptQuestion.Data.ItemID = itemID;
4835 scriptQuestion.Data.Questions = question; 4604 scriptQuestion.Data.Questions = question;
4836 scriptQuestion.Data.ObjectName = Utils.StringToBytes(taskName); 4605 scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName);
4837 scriptQuestion.Data.ObjectOwner = Utils.StringToBytes(ownerName); 4606 scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName);
4838 4607
4839 OutPacket(scriptQuestion, ThrottleOutPacketType.Task); 4608 OutPacket(scriptQuestion, ThrottleOutPacketType.Task);
4840 } 4609 }
@@ -5228,7 +4997,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5228 if (m_moneyBalance + debit >= 0) 4997 if (m_moneyBalance + debit >= 0)
5229 { 4998 {
5230 m_moneyBalance += debit; 4999 m_moneyBalance += debit;
5231 SendMoneyBalance(UUID.Zero, true, Utils.StringToBytes("Poof Poof!"), m_moneyBalance); 5000 SendMoneyBalance(UUID.Zero, true, Util.StringToBytes256("Poof Poof!"), m_moneyBalance);
5232 return true; 5001 return true;
5233 } 5002 }
5234 return false; 5003 return false;
@@ -8826,19 +8595,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8826 8595
8827 #endregion 8596 #endregion
8828 8597
8598 case PacketType.AgentFOV:
8599 AgentFOVPacket fovPacket = (AgentFOVPacket)Pack;
8829 8600
8830 #region unimplemented handlers 8601 if (fovPacket.FOVBlock.GenCounter > m_agentFOVCounter)
8831 8602 {
8832 case PacketType.StartPingCheck: 8603 m_agentFOVCounter = fovPacket.FOVBlock.GenCounter;
8833 StartPingCheckPacket pingStart = (StartPingCheckPacket)Pack; 8604 AgentFOV handlerAgentFOV = OnAgentFOV;
8834 CompletePingCheckPacket pingComplete = new CompletePingCheckPacket(); 8605 if (handlerAgentFOV != null)
8835 pingComplete.PingID.PingID = pingStart.PingID.PingID; 8606 {
8836 m_udpServer.SendPacket(m_udpClient, pingComplete, ThrottleOutPacketType.Unknown, false); 8607 handlerAgentFOV(this, fovPacket.FOVBlock.VerticalAngle);
8608 }
8609 }
8837 break; 8610 break;
8838 8611
8839 case PacketType.CompletePingCheck: 8612 #region unimplemented handlers
8840 // TODO: Do stats tracking or something with these?
8841 break;
8842 8613
8843 case PacketType.ViewerStats: 8614 case PacketType.ViewerStats:
8844 // TODO: handle this packet 8615 // TODO: handle this packet
@@ -9170,7 +8941,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9170 new GroupTitlesReplyPacket.GroupDataBlock(); 8941 new GroupTitlesReplyPacket.GroupDataBlock();
9171 8942
9172 groupTitlesReply.GroupData[i].Title = 8943 groupTitlesReply.GroupData[i].Title =
9173 Utils.StringToBytes(d.Name); 8944 Util.StringToBytes256(d.Name);
9174 groupTitlesReply.GroupData[i].RoleID = 8945 groupTitlesReply.GroupData[i].RoleID =
9175 d.UUID; 8946 d.UUID;
9176 groupTitlesReply.GroupData[i].Selected = 8947 groupTitlesReply.GroupData[i].Selected =
@@ -9207,10 +8978,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9207 groupProfileRequest.GroupData.GroupID); 8978 groupProfileRequest.GroupData.GroupID);
9208 8979
9209 groupProfileReply.GroupData.GroupID = d.GroupID; 8980 groupProfileReply.GroupData.GroupID = d.GroupID;
9210 groupProfileReply.GroupData.Name = Utils.StringToBytes(d.Name); 8981 groupProfileReply.GroupData.Name = Util.StringToBytes256(d.Name);
9211 groupProfileReply.GroupData.Charter = Utils.StringToBytes(d.Charter); 8982 groupProfileReply.GroupData.Charter = Util.StringToBytes1024(d.Charter);
9212 groupProfileReply.GroupData.ShowInList = d.ShowInList; 8983 groupProfileReply.GroupData.ShowInList = d.ShowInList;
9213 groupProfileReply.GroupData.MemberTitle = Utils.StringToBytes(d.MemberTitle); 8984 groupProfileReply.GroupData.MemberTitle = Util.StringToBytes256(d.MemberTitle);
9214 groupProfileReply.GroupData.PowersMask = d.PowersMask; 8985 groupProfileReply.GroupData.PowersMask = d.PowersMask;
9215 groupProfileReply.GroupData.InsigniaID = d.InsigniaID; 8986 groupProfileReply.GroupData.InsigniaID = d.InsigniaID;
9216 groupProfileReply.GroupData.FounderID = d.FounderID; 8987 groupProfileReply.GroupData.FounderID = d.FounderID;
@@ -9282,11 +9053,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9282 groupMembersReply.MemberData[i].Contribution = 9053 groupMembersReply.MemberData[i].Contribution =
9283 m.Contribution; 9054 m.Contribution;
9284 groupMembersReply.MemberData[i].OnlineStatus = 9055 groupMembersReply.MemberData[i].OnlineStatus =
9285 Utils.StringToBytes(m.OnlineStatus); 9056 Util.StringToBytes256(m.OnlineStatus);
9286 groupMembersReply.MemberData[i].AgentPowers = 9057 groupMembersReply.MemberData[i].AgentPowers =
9287 m.AgentPowers; 9058 m.AgentPowers;
9288 groupMembersReply.MemberData[i].Title = 9059 groupMembersReply.MemberData[i].Title =
9289 Utils.StringToBytes(m.Title); 9060 Util.StringToBytes256(m.Title);
9290 groupMembersReply.MemberData[i].IsOwner = 9061 groupMembersReply.MemberData[i].IsOwner =
9291 m.IsOwner; 9062 m.IsOwner;
9292 } 9063 }
@@ -9347,11 +9118,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9347 groupRolesReply.RoleData[i].RoleID = 9118 groupRolesReply.RoleData[i].RoleID =
9348 d.RoleID; 9119 d.RoleID;
9349 groupRolesReply.RoleData[i].Name = 9120 groupRolesReply.RoleData[i].Name =
9350 Utils.StringToBytes(d.Name); 9121 Util.StringToBytes256(d.Name);
9351 groupRolesReply.RoleData[i].Title = 9122 groupRolesReply.RoleData[i].Title =
9352 Utils.StringToBytes(d.Title); 9123 Util.StringToBytes256(d.Title);
9353 groupRolesReply.RoleData[i].Description = 9124 groupRolesReply.RoleData[i].Description =
9354 Utils.StringToBytes(d.Description); 9125 Util.StringToBytes1024(d.Description);
9355 groupRolesReply.RoleData[i].Powers = 9126 groupRolesReply.RoleData[i].Powers =
9356 d.Powers; 9127 d.Powers;
9357 groupRolesReply.RoleData[i].Members = 9128 groupRolesReply.RoleData[i].Members =
@@ -9578,9 +9349,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9578 groupNoticesListReply.Data[i].Timestamp = 9349 groupNoticesListReply.Data[i].Timestamp =
9579 g.Timestamp; 9350 g.Timestamp;
9580 groupNoticesListReply.Data[i].FromName = 9351 groupNoticesListReply.Data[i].FromName =
9581 Utils.StringToBytes(g.FromName); 9352 Util.StringToBytes256(g.FromName);
9582 groupNoticesListReply.Data[i].Subject = 9353 groupNoticesListReply.Data[i].Subject =
9583 Utils.StringToBytes(g.Subject); 9354 Util.StringToBytes256(g.Subject);
9584 groupNoticesListReply.Data[i].HasAttachment = 9355 groupNoticesListReply.Data[i].HasAttachment =
9585 g.HasAttachment; 9356 g.HasAttachment;
9586 groupNoticesListReply.Data[i].AssetType = 9357 groupNoticesListReply.Data[i].AssetType =
@@ -10179,12 +9950,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10179 byte mediaLoop) 9950 byte mediaLoop)
10180 { 9951 {
10181 ParcelMediaUpdatePacket updatePacket = new ParcelMediaUpdatePacket(); 9952 ParcelMediaUpdatePacket updatePacket = new ParcelMediaUpdatePacket();
10182 updatePacket.DataBlock.MediaURL = Utils.StringToBytes(mediaUrl); 9953 updatePacket.DataBlock.MediaURL = Util.StringToBytes256(mediaUrl);
10183 updatePacket.DataBlock.MediaID = mediaTextureID; 9954 updatePacket.DataBlock.MediaID = mediaTextureID;
10184 updatePacket.DataBlock.MediaAutoScale = autoScale; 9955 updatePacket.DataBlock.MediaAutoScale = autoScale;
10185 9956
10186 updatePacket.DataBlockExtended.MediaType = Utils.StringToBytes(mediaType); 9957 updatePacket.DataBlockExtended.MediaType = Util.StringToBytes256(mediaType);
10187 updatePacket.DataBlockExtended.MediaDesc = Utils.StringToBytes(mediaDesc); 9958 updatePacket.DataBlockExtended.MediaDesc = Util.StringToBytes256(mediaDesc);
10188 updatePacket.DataBlockExtended.MediaWidth = mediaWidth; 9959 updatePacket.DataBlockExtended.MediaWidth = mediaWidth;
10189 updatePacket.DataBlockExtended.MediaHeight = mediaHeight; 9960 updatePacket.DataBlockExtended.MediaHeight = mediaHeight;
10190 updatePacket.DataBlockExtended.MediaLoop = mediaLoop; 9961 updatePacket.DataBlockExtended.MediaLoop = mediaLoop;
@@ -10465,6 +10236,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10465 #region PriorityQueue 10236 #region PriorityQueue
10466 private class PriorityQueue<TPriority, TValue> 10237 private class PriorityQueue<TPriority, TValue>
10467 { 10238 {
10239 internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id);
10240
10468 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1]; 10241 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1];
10469 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>(); 10242 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>();
10470 private Comparison<TPriority> comparison; 10243 private Comparison<TPriority> comparison;
@@ -10539,6 +10312,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10539 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 10312 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
10540 } 10313 }
10541 10314
10315 internal void Reprioritize(UpdatePriorityHandler handler)
10316 {
10317 MinHeapItem item;
10318 TPriority priority;
10319
10320 foreach (LookupItem lookup in new List<LookupItem>(this.lookup_table.Values))
10321 {
10322 if (lookup.Heap.TryGetValue(lookup.Handle, out item))
10323 {
10324 priority = item.Priority;
10325 if (handler(ref priority, item.LocalID))
10326 {
10327 if (lookup.Heap.ContainsHandle(lookup.Handle))
10328 lookup.Heap[lookup.Handle] =
10329 new MinHeapItem(priority, item.Value, item.LocalID);
10330 }
10331 else
10332 {
10333 m_log.Warn("[LLCLIENTVIEW]: UpdatePriorityHandler returned false, dropping update");
10334 lookup.Heap.Remove(lookup.Handle);
10335 this.lookup_table.Remove(item.LocalID);
10336 }
10337 }
10338 }
10339 }
10340
10542 #region MinHeapItem 10341 #region MinHeapItem
10543 private struct MinHeapItem : IComparable<MinHeapItem> 10342 private struct MinHeapItem : IComparable<MinHeapItem>
10544 { 10343 {
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 7a403aa..66e1468 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -572,6 +572,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
572 for (int i = 0; i < ackPacket.Packets.Length; i++) 572 for (int i = 0; i < ackPacket.Packets.Length; i++)
573 AcknowledgePacket(udpClient, ackPacket.Packets[i].ID, now, packet.Header.Resent); 573 AcknowledgePacket(udpClient, ackPacket.Packets[i].ID, now, packet.Header.Resent);
574 } 574 }
575
576 // We don't need to do anything else with PacketAck packets
577 return;
575 } 578 }
576 579
577 #endregion ACK Receiving 580 #endregion ACK Receiving
@@ -579,20 +582,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
579 #region ACK Sending 582 #region ACK Sending
580 583
581 if (packet.Header.Reliable) 584 if (packet.Header.Reliable)
585 {
582 udpClient.PendingAcks.Enqueue(packet.Header.Sequence); 586 udpClient.PendingAcks.Enqueue(packet.Header.Sequence);
583 587
584 // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out, 588 // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out,
585 // add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove 589 // add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove
586 // 2*MTU bytes from the value and send ACKs, and finally add the local value back to 590 // 2*MTU bytes from the value and send ACKs, and finally add the local value back to
587 // client.BytesSinceLastACK. Lockless thread safety 591 // client.BytesSinceLastACK. Lockless thread safety
588 int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0); 592 int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0);
589 bytesSinceLastACK += buffer.DataLength; 593 bytesSinceLastACK += buffer.DataLength;
590 if (bytesSinceLastACK > LLUDPServer.MTU * 2) 594 if (bytesSinceLastACK > LLUDPServer.MTU * 2)
591 { 595 {
592 bytesSinceLastACK -= LLUDPServer.MTU * 2; 596 bytesSinceLastACK -= LLUDPServer.MTU * 2;
593 SendAcks(udpClient); 597 SendAcks(udpClient);
598 }
599 Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK);
594 } 600 }
595 Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK);
596 601
597 #endregion ACK Sending 602 #endregion ACK Sending
598 603
@@ -612,12 +617,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
612 617
613 #endregion Incoming Packet Accounting 618 #endregion Incoming Packet Accounting
614 619
615 // Don't bother clogging up the queue with PacketAck packets that are already handled here 620 #region Ping Check Handling
616 if (packet.Type != PacketType.PacketAck) 621
622 if (packet.Type == PacketType.StartPingCheck)
623 {
624 // We don't need to do anything else with ping checks
625 StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
626
627 CompletePingCheckPacket completePing = new CompletePingCheckPacket();
628 completePing.PingID.PingID = startPing.PingID.PingID;
629 SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false);
630 return;
631 }
632 else if (packet.Type == PacketType.CompletePingCheck)
617 { 633 {
618 // Inbox insertion 634 // We don't currently track client ping times
619 packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); 635 return;
620 } 636 }
637
638 #endregion Ping Check Handling
639
640 // Inbox insertion
641 packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
621 } 642 }
622 643
623 protected override void PacketSent(UDPPacketBuffer buffer, int bytesSent) 644 protected override void PacketSent(UDPPacketBuffer buffer, int bytesSent)
@@ -712,10 +733,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
712 // on to en-US to avoid number parsing issues 733 // on to en-US to avoid number parsing issues
713 Culture.SetCurrentCulture(); 734 Culture.SetCurrentCulture();
714 735
715 IncomingPacket incomingPacket = null;
716
717 while (base.IsRunning) 736 while (base.IsRunning)
718 { 737 {
738 IncomingPacket incomingPacket = null;
739
719 try 740 try
720 { 741 {
721 if (packetInbox.Dequeue(100, ref incomingPacket)) 742 if (packetInbox.Dequeue(100, ref incomingPacket))
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 3799a02..5a5fcfe 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -527,6 +527,10 @@ namespace OpenSim.Region.Examples.SimpleModule
527 { 527 {
528 } 528 }
529 529
530 public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
531 {
532 }
533
530 public void FlushPrimUpdates() 534 public void FlushPrimUpdates()
531 { 535 {
532 } 536 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 49c1ebf..70b11c3 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -278,6 +278,10 @@ namespace OpenSim.Region.Framework.Scenes
278 private bool m_firstHeartbeat = true; 278 private bool m_firstHeartbeat = true;
279 279
280 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; 280 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
281 private bool m_reprioritization_enabled = true;
282 private double m_reprioritization_interval = 2000.0;
283 private double m_root_reprioritization_distance = 5.0;
284 private double m_child_reprioritization_distance = 10.0;
281 285
282 private object m_deleting_scene_object = new object(); 286 private object m_deleting_scene_object = new object();
283 287
@@ -291,6 +295,10 @@ namespace OpenSim.Region.Framework.Scenes
291 #region Properties 295 #region Properties
292 296
293 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } 297 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } }
298 public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } }
299 public double ReprioritizationInterval { get { return m_reprioritization_interval; } }
300 public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } }
301 public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } }
294 302
295 public AgentCircuitManager AuthenticateHandler 303 public AgentCircuitManager AuthenticateHandler
296 { 304 {
@@ -349,13 +357,6 @@ namespace OpenSim.Region.Framework.Scenes
349 get { return m_defaultScriptEngine; } 357 get { return m_defaultScriptEngine; }
350 } 358 }
351 359
352 // Reference to all of the agents in the scene (root and child)
353 protected Dictionary<UUID, ScenePresence> m_scenePresences
354 {
355 get { return m_sceneGraph.ScenePresences; }
356 set { m_sceneGraph.ScenePresences = value; }
357 }
358
359 public EntityManager Entities 360 public EntityManager Entities
360 { 361 {
361 get { return m_sceneGraph.Entities; } 362 get { return m_sceneGraph.Entities; }
@@ -542,6 +543,11 @@ namespace OpenSim.Region.Framework.Scenes
542 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; 543 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
543 break; 544 break;
544 } 545 }
546
547 m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true);
548 m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0);
549 m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0);
550 m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0);
545 } 551 }
546 552
547 m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); 553 m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme");
@@ -1170,14 +1176,13 @@ namespace OpenSim.Region.Framework.Scenes
1170 /// <param name="stats">Stats on the Simulator's performance</param> 1176 /// <param name="stats">Stats on the Simulator's performance</param>
1171 private void SendSimStatsPackets(SimStats stats) 1177 private void SendSimStatsPackets(SimStats stats)
1172 { 1178 {
1173 List<ScenePresence> StatSendAgents = GetScenePresences(); 1179 ForEachScenePresence(
1174 foreach (ScenePresence agent in StatSendAgents) 1180 delegate(ScenePresence agent)
1175 {
1176 if (!agent.IsChildAgent)
1177 { 1181 {
1178 agent.ControllingClient.SendSimStats(stats); 1182 if (!agent.IsChildAgent)
1183 agent.ControllingClient.SendSimStats(stats);
1179 } 1184 }
1180 } 1185 );
1181 } 1186 }
1182 1187
1183 /// <summary> 1188 /// <summary>
@@ -3488,10 +3493,8 @@ namespace OpenSim.Region.Framework.Scenes
3488 { 3493 {
3489 ScenePresence presence; 3494 ScenePresence presence;
3490 3495
3491 lock (m_scenePresences) 3496 lock (m_sceneGraph.ScenePresences)
3492 { 3497 m_sceneGraph.ScenePresences.TryGetValue(agentID, out presence);
3493 m_scenePresences.TryGetValue(agentID, out presence);
3494 }
3495 3498
3496 if (presence != null) 3499 if (presence != null)
3497 { 3500 {
@@ -3701,12 +3704,9 @@ namespace OpenSim.Region.Framework.Scenes
3701 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, 3704 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
3702 Vector3 lookAt, uint teleportFlags) 3705 Vector3 lookAt, uint teleportFlags)
3703 { 3706 {
3704 ScenePresence sp = null; 3707 ScenePresence sp;
3705 lock (m_scenePresences) 3708 lock (m_sceneGraph.ScenePresences)
3706 { 3709 m_sceneGraph.ScenePresences.TryGetValue(remoteClient.AgentId, out sp);
3707 if (m_scenePresences.ContainsKey(remoteClient.AgentId))
3708 sp = m_scenePresences[remoteClient.AgentId];
3709 }
3710 3710
3711 if (sp != null) 3711 if (sp != null)
3712 { 3712 {
@@ -4155,7 +4155,7 @@ namespace OpenSim.Region.Framework.Scenes
4155 public void ForEachScenePresence(Action<ScenePresence> action) 4155 public void ForEachScenePresence(Action<ScenePresence> action)
4156 { 4156 {
4157 // We don't want to try to send messages if there are no avatars. 4157 // We don't want to try to send messages if there are no avatars.
4158 if (m_scenePresences != null) 4158 if (m_sceneGraph != null && m_sceneGraph.ScenePresences != null)
4159 { 4159 {
4160 try 4160 try
4161 { 4161 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index b9872ca..8ee26c3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -846,7 +846,7 @@ namespace OpenSim.Region.Framework.Scenes
846 /// </summary> 846 /// </summary>
847 /// <param name="localID"></param> 847 /// <param name="localID"></param>
848 /// <returns>null if no scene object group containing that prim is found</returns> 848 /// <returns>null if no scene object group containing that prim is found</returns>
849 private SceneObjectGroup GetGroupByPrim(uint localID) 849 public SceneObjectGroup GetGroupByPrim(uint localID)
850 { 850 {
851 if (Entities.ContainsKey(localID)) 851 if (Entities.ContainsKey(localID))
852 return Entities[localID] as SceneObjectGroup; 852 return Entities[localID] as SceneObjectGroup;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 79f6366..a078b3d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -3791,15 +3791,15 @@ if (m_shape != null) {
3791 if (ParentGroup.RootPart == this) 3791 if (ParentGroup.RootPart == this)
3792 lPos = AbsolutePosition; 3792 lPos = AbsolutePosition;
3793 } 3793 }
3794 3794
3795 // Causes this thread to dig into the Client Thread Data. 3795 // Causes this thread to dig into the Client Thread Data.
3796 // Remember your locking here! 3796 // Remember your locking here!
3797 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, 3797 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle,
3798 (ushort)(m_parentGroup.GetTimeDilation() * 3798 (ushort)(m_parentGroup.GetTimeDilation() *
3799 (float)ushort.MaxValue), LocalId, lPos, 3799 (float)ushort.MaxValue), LocalId, lPos,
3800 RotationOffset, Velocity, 3800 RotationOffset, Velocity, Acceleration,
3801 RotationalVelocity, state, FromItemID, 3801 RotationalVelocity, state, FromItemID,
3802 OwnerID, (int)AttachmentPoint, ParentGroup.GetUpdatePriority(remoteClient))); 3802 OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient)));
3803 } 3803 }
3804 3804
3805 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 9d13ad4..bdd80c6 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Timers;
31using OpenMetaverse; 32using OpenMetaverse;
32using log4net; 33using log4net;
33using OpenSim.Framework; 34using OpenSim.Framework;
@@ -172,6 +173,11 @@ namespace OpenSim.Region.Framework.Scenes
172 173
173 // Position of agent's camera in world (region cordinates) 174 // Position of agent's camera in world (region cordinates)
174 protected Vector3 m_CameraCenter = Vector3.Zero; 175 protected Vector3 m_CameraCenter = Vector3.Zero;
176 protected Vector3 m_lastCameraCenter = Vector3.Zero;
177
178 protected Timer m_reprioritization_timer;
179 protected bool m_reprioritizing = false;
180 protected bool m_reprioritization_called = false;
175 181
176 // Use these three vectors to figure out what the agent is looking at 182 // Use these three vectors to figure out what the agent is looking at
177 // Convert it to a Matrix and/or Quaternion 183 // Convert it to a Matrix and/or Quaternion
@@ -639,7 +645,14 @@ namespace OpenSim.Region.Framework.Scenes
639 645
640 m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); 646 m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>();
641 647
642 AbsolutePosition = m_controllingClient.StartPos; 648 AbsolutePosition = posLastSignificantMove = m_CameraCenter =
649 m_lastCameraCenter = m_controllingClient.StartPos;
650
651 m_reprioritization_timer = new Timer(world.ReprioritizationInterval);
652 m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize);
653 m_reprioritization_timer.AutoReset = false;
654
655
643 AdjustKnownSeeds(); 656 AdjustKnownSeeds();
644 657
645 TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here... 658 TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here...
@@ -1147,15 +1160,21 @@ namespace OpenSim.Region.Framework.Scenes
1147 /// </summary> 1160 /// </summary>
1148 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1161 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1149 { 1162 {
1150 lock (m_agentUpdates) 1163 const int AGENT_UPDATE_TIMEOUT_MS = 1000 * 3;
1164
1165 if (System.Threading.Monitor.TryEnter(m_agentUpdates, AGENT_UPDATE_TIMEOUT_MS))
1151 { 1166 {
1152 if (m_updatesAllowed) 1167 try
1153 { 1168 {
1154 RealHandleAgentUpdate(remoteClient, agentData); 1169 if (m_updatesAllowed)
1155 return; 1170 {
1171 RealHandleAgentUpdate(remoteClient, agentData);
1172 return;
1173 }
1174
1175 m_agentUpdates.Add(agentData);
1156 } 1176 }
1157 1177 finally { System.Threading.Monitor.Exit(m_agentUpdates); }
1158 m_agentUpdates.Add(agentData);
1159 } 1178 }
1160 } 1179 }
1161 1180
@@ -1219,6 +1238,11 @@ namespace OpenSim.Region.Framework.Scenes
1219 // Camera location in world. We'll need to raytrace 1238 // Camera location in world. We'll need to raytrace
1220 // from this location from time to time. 1239 // from this location from time to time.
1221 m_CameraCenter = agentData.CameraCenter; 1240 m_CameraCenter = agentData.CameraCenter;
1241 if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance)
1242 {
1243 ReprioritizeUpdates();
1244 m_lastCameraCenter = m_CameraCenter;
1245 }
1222 1246
1223 // Use these three vectors to figure out what the agent is looking at 1247 // Use these three vectors to figure out what the agent is looking at
1224 // Convert it to a Matrix and/or Quaternion 1248 // Convert it to a Matrix and/or Quaternion
@@ -2453,7 +2477,7 @@ namespace OpenSim.Region.Framework.Scenes
2453 pos.Z -= m_appearance.HipOffset; 2477 pos.Z -= m_appearance.HipOffset;
2454 2478
2455 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 2479 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
2456 pos, m_velocity, m_rotation, m_uuid, GetUpdatePriority(remoteClient))); 2480 pos, m_velocity, Vector3.Zero, m_rotation, Vector4.Zero, m_uuid, null, GetUpdatePriority(remoteClient)));
2457 2481
2458 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2482 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
2459 m_scene.StatsReporter.AddAgentUpdates(1); 2483 m_scene.StatsReporter.AddAgentUpdates(1);
@@ -2823,7 +2847,7 @@ namespace OpenSim.Region.Framework.Scenes
2823 } 2847 }
2824 2848
2825 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 2849 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
2826 if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32) 2850 if (Util.GetDistanceTo(AbsolutePosition, m_LastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance)
2827 { 2851 {
2828 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); 2852 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate();
2829 cadu.ActiveGroupID = UUID.Zero.Guid; 2853 cadu.ActiveGroupID = UUID.Zero.Guid;
@@ -3118,6 +3142,12 @@ namespace OpenSim.Region.Framework.Scenes
3118 if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! 3142 if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!!
3119 m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z); 3143 m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z);
3120 3144
3145 if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance)
3146 {
3147 posLastSignificantMove = AbsolutePosition;
3148 ReprioritizeUpdates();
3149 }
3150
3121 // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region 3151 // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region
3122 m_CameraCenter = cAgentData.Center; 3152 m_CameraCenter = cAgentData.Center;
3123 3153
@@ -3480,7 +3510,6 @@ namespace OpenSim.Region.Framework.Scenes
3480 3510
3481 public void Close() 3511 public void Close()
3482 { 3512 {
3483
3484 lock (m_attachments) 3513 lock (m_attachments)
3485 { 3514 {
3486 // Delete attachments from scene 3515 // Delete attachments from scene
@@ -3498,10 +3527,19 @@ namespace OpenSim.Region.Framework.Scenes
3498 { 3527 {
3499 m_knownChildRegions.Clear(); 3528 m_knownChildRegions.Clear();
3500 } 3529 }
3530
3531 lock (m_reprioritization_timer)
3532 {
3533 m_reprioritization_timer.Enabled = false;
3534 m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize);
3535 }
3536 // I don't get it but mono crashes when you try to dispose of this timer,
3537 // unsetting the elapsed callback should be enough to allow for cleanup however.
3538 //m_reprioritizationTimer.Dispose();
3539
3501 m_sceneViewer.Close(); 3540 m_sceneViewer.Close();
3502 3541
3503 RemoveFromPhysicalScene(); 3542 RemoveFromPhysicalScene();
3504 GC.Collect();
3505 } 3543 }
3506 3544
3507 public ScenePresence() 3545 public ScenePresence()
@@ -3913,5 +3951,79 @@ namespace OpenSim.Region.Framework.Scenes
3913 { 3951 {
3914 return Vector3.Distance(AbsolutePosition, position); 3952 return Vector3.Distance(AbsolutePosition, position);
3915 } 3953 }
3954
3955 private double GetSOGUpdatePriority(SceneObjectGroup sog)
3956 {
3957 switch (Scene.UpdatePrioritizationScheme)
3958 {
3959 case Scene.UpdatePrioritizationSchemes.Time:
3960 throw new InvalidOperationException("UpdatePrioritizationScheme for time not supported for reprioritization");
3961 case Scene.UpdatePrioritizationSchemes.Distance:
3962 return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3963 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3964 return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3965 default:
3966 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3967 }
3968 }
3969
3970 private double UpdatePriority(UpdatePriorityData data)
3971 {
3972 EntityBase entity;
3973 SceneObjectGroup group;
3974
3975 if (Scene.Entities.TryGetValue(data.localID, out entity))
3976 {
3977 group = entity as SceneObjectGroup;
3978 if (group != null)
3979 return GetSOGUpdatePriority(group);
3980
3981 ScenePresence presence = entity as ScenePresence;
3982 if (presence == null)
3983 throw new InvalidOperationException("entity found is neither SceneObjectGroup nor ScenePresence");
3984 switch (Scene.UpdatePrioritizationScheme)
3985 {
3986 case Scene.UpdatePrioritizationSchemes.Time:
3987 throw new InvalidOperationException("UpdatePrioritization for time not supported for reprioritization");
3988 case Scene.UpdatePrioritizationSchemes.Distance:
3989 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3990 return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3991 default:
3992 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3993 }
3994 }
3995 else
3996 {
3997 group = Scene.SceneGraph.GetGroupByPrim(data.localID);
3998 if (group != null)
3999 return GetSOGUpdatePriority(group);
4000 }
4001 return double.NaN;
4002 }
4003
4004 private void ReprioritizeUpdates()
4005 {
4006 if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != Scene.UpdatePrioritizationSchemes.Time)
4007 {
4008 lock (m_reprioritization_timer)
4009 {
4010 if (!m_reprioritizing)
4011 m_reprioritization_timer.Enabled = m_reprioritizing = true;
4012 else
4013 m_reprioritization_called = true;
4014 }
4015 }
4016 }
4017
4018 private void Reprioritize(object sender, ElapsedEventArgs e)
4019 {
4020 m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority);
4021
4022 lock (m_reprioritization_timer)
4023 {
4024 m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called;
4025 m_reprioritization_called = false;
4026 }
4027 }
3916 } 4028 }
3917} 4029}
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 1a24dec..df03b8d 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -1048,6 +1048,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1048 1048
1049 } 1049 }
1050 1050
1051 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
1052 {
1053
1054 }
1055
1051 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, bool fetchFolders, bool fetchItems) 1056 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, bool fetchFolders, bool fetchItems)
1052 { 1057 {
1053 1058
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 6c58f2d..f7cadaa 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -616,6 +616,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC
616 { 616 {
617 } 617 }
618 618
619 public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
620 {
621 }
622
619 public void FlushPrimUpdates() 623 public void FlushPrimUpdates()
620 { 624 {
621 } 625 }
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 1ea08e2..f609e73 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -289,6 +289,9 @@ namespace OpenSim.Region.Physics.Meshing
289 ManagedImage managedImage; // we never use this 289 ManagedImage managedImage; // we never use this
290 OpenJPEG.DecodeToImage(primShape.SculptData, out managedImage, out idata); 290 OpenJPEG.DecodeToImage(primShape.SculptData, out managedImage, out idata);
291 291
292 // Remove the reference to the encoded JPEG2000 data so it can be GCed
293 primShape.SculptData = Utils.EmptyBytes;
294
292 if (cacheSculptMaps) 295 if (cacheSculptMaps)
293 { 296 {
294 try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } 297 try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 21606e2..0f642b9 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -620,6 +620,10 @@ namespace OpenSim.Tests.Common.Mock
620 { 620 {
621 } 621 }
622 622
623 public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
624 {
625 }
626
623 public void FlushPrimUpdates() 627 public void FlushPrimUpdates()
624 { 628 {
625 } 629 }