aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs24
-rw-r--r--OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs54
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScenePresence.cs8
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISceneViewer.cs13
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModule.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs65
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs54
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs13
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs133
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs87
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs58
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs11
14 files changed, 373 insertions, 181 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index 59c26e7..d1b7dc1 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -89,18 +89,13 @@ namespace OpenSim.Region.Framework.Interfaces
89 ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); 89 ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
90 90
91 /// <summary> 91 /// <summary>
92 /// Rez an attachment from user inventory 92 /// Rez an attachment from user inventory and change inventory status to match.
93 /// </summary> 93 /// </summary>
94 /// <param name="remoteClient"></param> 94 /// <param name="sp"></param>
95 /// <param name="itemID"></param> 95 /// <param name="itemID"></param>
96 /// <param name="AttachmentPt"></param> 96 /// <param name="AttachmentPt"></param>
97 /// <param name="updateinventoryStatus"> 97 /// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
98 /// If true, we also update the user's inventory to show that the attachment is set. If false, we do not. 98 ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt);
99 /// False is required so that we don't attempt to update information when a user enters a scene with the
100 /// attachment already correctly set up in inventory.
101 /// <returns>The uuid of the scene object that was attached. Null if the scene object could not be found</returns>
102 ISceneEntity RezSingleAttachmentFromInventory(
103 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus);
104 99
105 // Same as above, but also load script states from a separate doc 100 // Same as above, but also load script states from a separate doc
106 ISceneEntity RezSingleAttachmentFromInventory( 101 ISceneEntity RezSingleAttachmentFromInventory(
@@ -146,13 +141,10 @@ namespace OpenSim.Region.Framework.Interfaces
146 /// </param> 141 /// </param>
147 void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient); 142 void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient);
148 143
149 /// <summary> 144 /// Update the position of an attachment.
150 /// Update the user inventory with a changed attachment
151 /// </summary> 145 /// </summary>
152 /// <param name="remoteClient"></param> 146 /// <param name="sog"></param>
153 /// <param name="grp"></param> 147 /// <param name="pos"></param>
154 /// <param name="itemID"></param> 148 void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos);
155 /// <param name="agentID"></param>
156 void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID);
157 } 149 }
158} 150}
diff --git a/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs b/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs
new file mode 100644
index 0000000..1ed978b
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IPermissionsModule.cs
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29using OpenSim.Region.Framework.Scenes;
30
31namespace OpenSim.Region.Framework.Interfaces
32{
33 /// <value>
34 /// Which set of permissions a user has.
35 /// </value>
36 public enum PermissionClass
37 {
38 Owner,
39 Group,
40 Everyone
41 };
42
43 public interface IPermissionsModule
44 {
45
46 /// <summary>
47 /// Returns the type of permissions that the user has over an object.
48 /// </summary>
49 /// <param name="user">The user</param>
50 /// <param name="obj">The object</param>
51 /// <returns>The type of permissions the user has over the object</returns>
52 PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj);
53 }
54}
diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
index 8913133..ff39283 100644
--- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
@@ -61,6 +61,14 @@ namespace OpenSim.Region.Framework.Interfaces
61 AvatarAppearance Appearance { get; set; } 61 AvatarAppearance Appearance { get; set; }
62 62
63 /// <summary> 63 /// <summary>
64 /// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments.
65 /// </summary>
66 /// <remarks>
67 /// All add and remove attachment operations must synchronize on this for the lifetime of their operations.
68 /// </remarks>
69 Object AttachmentsSyncLock { get; }
70
71 /// <summary>
64 /// The scene objects attached to this avatar. 72 /// The scene objects attached to this avatar.
65 /// </summary> 73 /// </summary>
66 /// <returns> 74 /// <returns>
diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
index 2397f22..e715e70 100644
--- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
+++ b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs
@@ -30,12 +30,21 @@ using OpenSim.Region.Framework.Scenes;
30 30
31namespace OpenSim.Region.Framework.Interfaces 31namespace OpenSim.Region.Framework.Interfaces
32{ 32{
33 /// <summary>
34 /// Sends scheduled updates to it's associated ScenePresence.
35 /// </summary>
33 public interface ISceneViewer 36 public interface ISceneViewer
34 { 37 {
35 void Reset(); 38// void Reset();
36 void Close(); 39 void Close();
40
41 /// <summary>
42 /// Add the part to the queue of parts for which we need to send an update to the client
43 /// </summary>
44 /// <param name="part"></param>
37 void QueuePartForUpdate(SceneObjectPart part); 45 void QueuePartForUpdate(SceneObjectPart part);
46
38 void SendPrimUpdates(); 47 void SendPrimUpdates();
39 int GetPendingObjectsCount(); 48 int GetPendingObjectsCount();
40 } 49 }
41} 50} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
index 641e226..7dde586 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
@@ -54,5 +54,10 @@ namespace OpenSim.Region.Framework.Interfaces
54 bool HasScript(UUID itemID, out bool running); 54 bool HasScript(UUID itemID, out bool running);
55 55
56 void SaveAllState(); 56 void SaveAllState();
57
58 /// <summary>
59 /// Starts the processing threads.
60 /// </summary>
61 void StartProcessing();
57 } 62 }
58} 63}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 63dd550..c2ec5d0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -57,11 +57,11 @@ namespace OpenSim.Region.Framework.Scenes
57 protected AsyncInventorySender m_asyncInventorySender; 57 protected AsyncInventorySender m_asyncInventorySender;
58 58
59 /// <summary> 59 /// <summary>
60 /// Start all the scripts in the scene which should be started. 60 /// Creates all the scripts in the scene which should be started.
61 /// </summary> 61 /// </summary>
62 public void CreateScriptInstances() 62 public void CreateScriptInstances()
63 { 63 {
64 m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); 64 m_log.Info("[PRIM INVENTORY]: Creating scripts in scene");
65 65
66 EntityBase[] entities = Entities.GetEntities(); 66 EntityBase[] entities = Entities.GetEntities();
67 foreach (EntityBase group in entities) 67 foreach (EntityBase group in entities)
@@ -74,6 +74,26 @@ namespace OpenSim.Region.Framework.Scenes
74 } 74 }
75 } 75 }
76 76
77 /// <summary>
78 /// Lets the script engines start processing scripts.
79 /// </summary>
80 public void StartScripts()
81 {
82 m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
83
84 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
85 if (engines != null)
86 {
87 foreach (IScriptModule engine in engines)
88 {
89 if (engine != null)
90 {
91 engine.StartProcessing();
92 }
93 }
94 }
95 }
96
77 public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) 97 public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item)
78 { 98 {
79 IMoneyModule money = RequestModuleInterface<IMoneyModule>(); 99 IMoneyModule money = RequestModuleInterface<IMoneyModule>();
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index a661ab8..c5bb2b2 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -610,9 +610,42 @@ namespace OpenSim.Region.Framework.Scenes
610 #region Region Settings 610 #region Region Settings
611 611
612 // Load region settings 612 // Load region settings
613 m_regInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(m_regInfo.RegionID); 613 // LoadRegionSettings creates new region settings in persistence if they don't already exist for this region.
614 // However, in this case, the default textures are not set in memory properly, so we need to do it here and
615 // resave.
616 // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
617 // region is set up and avoid these gyrations.
618 RegionSettings rs = simDataService.LoadRegionSettings(m_regInfo.RegionID);
619 bool updatedTerrainTextures = false;
620 if (rs.TerrainTexture1 == UUID.Zero)
621 {
622 rs.TerrainTexture1 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_1;
623 updatedTerrainTextures = true;
624 }
625
626 if (rs.TerrainTexture2 == UUID.Zero)
627 {
628 rs.TerrainTexture2 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_2;
629 updatedTerrainTextures = true;
630 }
631
632 if (rs.TerrainTexture3 == UUID.Zero)
633 {
634 rs.TerrainTexture3 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_3;
635 updatedTerrainTextures = true;
636 }
637
638 if (rs.TerrainTexture4 == UUID.Zero)
639 {
640 rs.TerrainTexture4 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_4;
641 updatedTerrainTextures = true;
642 }
643
644 if (updatedTerrainTextures)
645 rs.Save();
646
647 m_regInfo.RegionSettings = rs;
614 648
615 m_regInfo.RegionSettings = simDataService.LoadRegionSettings(m_regInfo.RegionID);
616 if (estateDataService != null) 649 if (estateDataService != null)
617 m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false); 650 m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false);
618 651
@@ -645,7 +678,7 @@ namespace OpenSim.Region.Framework.Scenes
645 EventManager.OnLandObjectRemoved += 678 EventManager.OnLandObjectRemoved +=
646 new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); 679 new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
647 680
648 m_sceneGraph = new SceneGraph(this, m_regInfo); 681 m_sceneGraph = new SceneGraph(this);
649 682
650 // If the scene graph has an Unrecoverable error, restart this sim. 683 // If the scene graph has an Unrecoverable error, restart this sim.
651 // Currently the only thing that causes it to happen is two kinds of specific 684 // Currently the only thing that causes it to happen is two kinds of specific
@@ -1575,7 +1608,9 @@ namespace OpenSim.Region.Framework.Scenes
1575 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; 1608 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
1576 msg.Position = Vector3.Zero; 1609 msg.Position = Vector3.Zero;
1577 msg.RegionID = RegionInfo.RegionID.Guid; 1610 msg.RegionID = RegionInfo.RegionID.Guid;
1578 msg.binaryBucket = new byte[0]; 1611
1612 // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
1613 msg.binaryBucket = Util.StringToBytes256("\0");
1579 if (ret.Value.count > 1) 1614 if (ret.Value.count > 1)
1580 msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); 1615 msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
1581 else 1616 else
@@ -2492,14 +2527,16 @@ namespace OpenSim.Region.Framework.Scenes
2492 /// <returns>False</returns> 2527 /// <returns>False</returns>
2493 public virtual bool IncomingCreateObject(UUID userID, UUID itemID) 2528 public virtual bool IncomingCreateObject(UUID userID, UUID itemID)
2494 { 2529 {
2495 //m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID); 2530 m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
2496 2531
2497 ScenePresence sp = GetScenePresence(userID); 2532 // Commented out since this is as yet unused and is arguably not the appropriate place to do this, as
2498 if (sp != null && AttachmentsModule != null) 2533 // attachments are being rezzed elsewhere in AddNewClient()
2499 { 2534// ScenePresence sp = GetScenePresence(userID);
2500 uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID); 2535// if (sp != null && AttachmentsModule != null)
2501 AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt); 2536// {
2502 } 2537// uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
2538// AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
2539// }
2503 2540
2504 return false; 2541 return false;
2505 } 2542 }
@@ -3272,8 +3309,8 @@ namespace OpenSim.Region.Framework.Scenes
3272 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3309 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3273 AttachmentsModule.SaveChangedAttachments(avatar); 3310 AttachmentsModule.SaveChangedAttachments(avatar);
3274 3311
3275 if (avatar != null && (!avatar.IsChildAgent)) 3312 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3276 avatar.SaveChangedAttachments(); 3313 AttachmentsModule.SaveChangedAttachments(avatar);
3277 3314
3278 ForEachClient( 3315 ForEachClient(
3279 delegate(IClientAPI client) 3316 delegate(IClientAPI client)
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 42e2502..d1ee990 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -83,7 +83,6 @@ namespace OpenSim.Region.Framework.Scenes
83 83
84 protected internal EntityManager Entities = new EntityManager(); 84 protected internal EntityManager Entities = new EntityManager();
85 85
86 protected RegionInfo m_regInfo;
87 protected Scene m_parentScene; 86 protected Scene m_parentScene;
88 protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); 87 protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
89 protected int m_numRootAgents = 0; 88 protected int m_numRootAgents = 0;
@@ -117,10 +116,9 @@ namespace OpenSim.Region.Framework.Scenes
117 116
118 #endregion 117 #endregion
119 118
120 protected internal SceneGraph(Scene parent, RegionInfo regInfo) 119 protected internal SceneGraph(Scene parent)
121 { 120 {
122 m_parentScene = parent; 121 m_parentScene = parent;
123 m_regInfo = regInfo;
124 } 122 }
125 123
126 public PhysicsScene PhysicsScene 124 public PhysicsScene PhysicsScene
@@ -131,7 +129,6 @@ namespace OpenSim.Region.Framework.Scenes
131 // If we're not doing the initial set 129 // If we're not doing the initial set
132 // Then we've got to remove the previous 130 // Then we've got to remove the previous
133 // event handler 131 // event handler
134
135 if (_PhyScene != null) 132 if (_PhyScene != null)
136 _PhyScene.OnPhysicsCrash -= physicsBasedCrash; 133 _PhyScene.OnPhysicsCrash -= physicsBasedCrash;
137 134
@@ -413,12 +410,12 @@ namespace OpenSim.Region.Framework.Scenes
413// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", 410// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
414// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); 411// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);
415 412
416 SceneObjectPart[] children = sceneObject.Parts; 413 SceneObjectPart[] parts = sceneObject.Parts;
417 414
418 // Clamp child prim sizes and add child prims to the m_numPrim count 415 // Clamp child prim sizes and add child prims to the m_numPrim count
419 if (m_parentScene.m_clampPrimSize) 416 if (m_parentScene.m_clampPrimSize)
420 { 417 {
421 foreach (SceneObjectPart part in children) 418 foreach (SceneObjectPart part in parts)
422 { 419 {
423 Vector3 scale = part.Shape.Scale; 420 Vector3 scale = part.Shape.Scale;
424 421
@@ -432,7 +429,7 @@ namespace OpenSim.Region.Framework.Scenes
432 part.Shape.Scale = scale; 429 part.Shape.Scale = scale;
433 } 430 }
434 } 431 }
435 m_numPrim += children.Length; 432 m_numPrim += parts.Length;
436 433
437 sceneObject.AttachToScene(m_parentScene); 434 sceneObject.AttachToScene(m_parentScene);
438 435
@@ -452,15 +449,17 @@ namespace OpenSim.Region.Framework.Scenes
452 449
453 lock (SceneObjectGroupsByFullPartID) 450 lock (SceneObjectGroupsByFullPartID)
454 { 451 {
455 SceneObjectGroupsByFullPartID[sceneObject.UUID] = sceneObject; 452 foreach (SceneObjectPart part in parts)
456 foreach (SceneObjectPart part in children)
457 SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; 453 SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
458 } 454 }
459 455
460 lock (SceneObjectGroupsByLocalPartID) 456 lock (SceneObjectGroupsByLocalPartID)
461 { 457 {
462 SceneObjectGroupsByLocalPartID[sceneObject.LocalId] = sceneObject; 458// m_log.DebugFormat(
463 foreach (SceneObjectPart part in children) 459// "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}",
460// sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName);
461
462 foreach (SceneObjectPart part in parts)
464 SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; 463 SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
465 } 464 }
466 465
@@ -473,6 +472,10 @@ namespace OpenSim.Region.Framework.Scenes
473 /// <returns>true if the object was deleted, false if there was no object to delete</returns> 472 /// <returns>true if the object was deleted, false if there was no object to delete</returns>
474 public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked) 473 public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
475 { 474 {
475// m_log.DebugFormat(
476// "[SCENE GRAPH]: Deleting scene object with uuid {0}, resultOfObjectLinked = {1}",
477// uuid, resultOfObjectLinked);
478
476 EntityBase entity; 479 EntityBase entity;
477 if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup))) 480 if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup)))
478 return false; 481 return false;
@@ -501,7 +504,6 @@ namespace OpenSim.Region.Framework.Scenes
501 SceneObjectPart[] parts = grp.Parts; 504 SceneObjectPart[] parts = grp.Parts;
502 for (int i = 0; i < parts.Length; i++) 505 for (int i = 0; i < parts.Length; i++)
503 SceneObjectGroupsByFullPartID.Remove(parts[i].UUID); 506 SceneObjectGroupsByFullPartID.Remove(parts[i].UUID);
504 SceneObjectGroupsByFullPartID.Remove(grp.RootPart.UUID);
505 } 507 }
506 508
507 lock (SceneObjectGroupsByLocalPartID) 509 lock (SceneObjectGroupsByLocalPartID)
@@ -509,7 +511,6 @@ namespace OpenSim.Region.Framework.Scenes
509 SceneObjectPart[] parts = grp.Parts; 511 SceneObjectPart[] parts = grp.Parts;
510 for (int i = 0; i < parts.Length; i++) 512 for (int i = 0; i < parts.Length; i++)
511 SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId); 513 SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId);
512 SceneObjectGroupsByLocalPartID.Remove(grp.RootPart.LocalId);
513 } 514 }
514 515
515 return Entities.Remove(uuid); 516 return Entities.Remove(uuid);
@@ -654,7 +655,7 @@ namespace OpenSim.Region.Framework.Scenes
654 ScenePresence newAvatar = null; 655 ScenePresence newAvatar = null;
655 656
656 // ScenePresence always defaults to child agent 657 // ScenePresence always defaults to child agent
657 newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance, type); 658 newAvatar = new ScenePresence(client, m_parentScene, appearance, type);
658 659
659 AddScenePresence(newAvatar); 660 AddScenePresence(newAvatar);
660 661
@@ -721,7 +722,7 @@ namespace OpenSim.Region.Framework.Scenes
721 if (!Entities.Remove(agentID)) 722 if (!Entities.Remove(agentID))
722 { 723 {
723 m_log.WarnFormat( 724 m_log.WarnFormat(
724 "[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list", 725 "[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list",
725 agentID); 726 agentID);
726 } 727 }
727 728
@@ -745,7 +746,7 @@ namespace OpenSim.Region.Framework.Scenes
745 } 746 }
746 else 747 else
747 { 748 {
748 m_log.WarnFormat("[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 749 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
749 } 750 }
750 } 751 }
751 finally 752 finally
@@ -956,7 +957,8 @@ namespace OpenSim.Region.Framework.Scenes
956 if (Entities.TryGetValue(localID, out entity)) 957 if (Entities.TryGetValue(localID, out entity))
957 return entity as SceneObjectGroup; 958 return entity as SceneObjectGroup;
958 959
959 //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID); 960// m_log.DebugFormat("[SCENE GRAPH]: Entered GetGroupByPrim with localID {0}", localID);
961
960 SceneObjectGroup sog; 962 SceneObjectGroup sog;
961 lock (SceneObjectGroupsByLocalPartID) 963 lock (SceneObjectGroupsByLocalPartID)
962 SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog); 964 SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog);
@@ -964,8 +966,24 @@ namespace OpenSim.Region.Framework.Scenes
964 if (sog != null) 966 if (sog != null)
965 { 967 {
966 if (sog.HasChildPrim(localID)) 968 if (sog.HasChildPrim(localID))
969 {
970// m_log.DebugFormat(
971// "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.",
972// sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
973
967 return sog; 974 return sog;
968 SceneObjectGroupsByLocalPartID.Remove(localID); 975 }
976 else
977 {
978 lock (SceneObjectGroupsByLocalPartID)
979 {
980 m_log.WarnFormat(
981 "[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.",
982 sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
983
984 SceneObjectGroupsByLocalPartID.Remove(localID);
985 }
986 }
969 } 987 }
970 988
971 EntityBase[] entityList = GetEntities(); 989 EntityBase[] entityList = GetEntities();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 9f0ac4f..6bd9183 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -388,5 +388,18 @@ namespace OpenSim.Region.Framework.Scenes
388 for (int i = 0; i < parts.Length; i++) 388 for (int i = 0; i < parts.Length; i++)
389 parts[i].Inventory.ResumeScripts(); 389 parts[i].Inventory.ResumeScripts();
390 } 390 }
391
392 /// <summary>
393 /// Returns true if any part in the scene object contains scripts, false otherwise.
394 /// </summary>
395 /// <returns></returns>
396 public bool ContainsScripts()
397 {
398 foreach (SceneObjectPart part in Parts)
399 if (part.Inventory.ContainsScripts())
400 return true;
401
402 return false;
403 }
391 } 404 }
392} 405}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 1f0840d..f6b690c 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -1239,10 +1239,15 @@ namespace OpenSim.Region.Framework.Scenes
1239 item.CurrentPermissions = perms; 1239 item.CurrentPermissions = perms;
1240 item.BasePermissions = perms; 1240 item.BasePermissions = perms;
1241 } 1241 }
1242
1242 m_inventorySerial++; 1243 m_inventorySerial++;
1243 HasInventoryChanged = true; 1244 HasInventoryChanged = true;
1244 } 1245 }
1245 1246
1247 /// <summary>
1248 /// Returns true if this part inventory contains any scripts. False otherwise.
1249 /// </summary>
1250 /// <returns></returns>
1246 public bool ContainsScripts() 1251 public bool ContainsScripts()
1247 { 1252 {
1248 foreach (TaskInventoryItem item in m_items.Values) 1253 foreach (TaskInventoryItem item in m_items.Values)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 35a8df7..7a86f98 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -124,6 +124,8 @@ namespace OpenSim.Region.Framework.Scenes
124 124
125 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 125 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
126 126
127 public Object AttachmentsSyncLock { get; private set; }
128
127 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); 129 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
128 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; 130 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
129 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; 131 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
@@ -199,7 +201,6 @@ namespace OpenSim.Region.Framework.Scenes
199 201
200 private float m_health = 100f; 202 private float m_health = 100f;
201 203
202 protected RegionInfo m_regionInfo;
203 protected ulong crossingFromRegion; 204 protected ulong crossingFromRegion;
204 205
205 private readonly Vector3[] Dir_Vectors = new Vector3[11]; 206 private readonly Vector3[] Dir_Vectors = new Vector3[11];
@@ -770,23 +771,24 @@ namespace OpenSim.Region.Framework.Scenes
770 #endregion 771 #endregion
771 772
772 #region Constructor(s) 773 #region Constructor(s)
773 774
774 public ScenePresence( 775 public ScenePresence(
775 IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance, PresenceType type) 776 IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type)
776 { 777 {
778 AttachmentsSyncLock = new Object();
779
777 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 780 m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
778 m_sceneViewer = new SceneViewer(this); 781 m_sceneViewer = new SceneViewer(this);
779 m_animator = new ScenePresenceAnimator(this); 782 m_animator = new ScenePresenceAnimator(this);
780 PresenceType = type; 783 PresenceType = type;
781 m_DrawDistance = world.DefaultDrawDistance; 784 m_DrawDistance = world.DefaultDrawDistance;
782 m_rootRegionHandle = reginfo.RegionHandle; 785 m_rootRegionHandle = world.RegionInfo.RegionHandle;
783 m_controllingClient = client; 786 m_controllingClient = client;
784 m_firstname = m_controllingClient.FirstName; 787 m_firstname = m_controllingClient.FirstName;
785 m_lastname = m_controllingClient.LastName; 788 m_lastname = m_controllingClient.LastName;
786 m_name = String.Format("{0} {1}", m_firstname, m_lastname); 789 m_name = String.Format("{0} {1}", m_firstname, m_lastname);
787 m_scene = world; 790 m_scene = world;
788 m_uuid = client.AgentId; 791 m_uuid = client.AgentId;
789 m_regionInfo = reginfo;
790 m_localId = m_scene.AllocateLocalId(); 792 m_localId = m_scene.AllocateLocalId();
791 793
792 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 794 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
@@ -1302,7 +1304,7 @@ namespace OpenSim.Region.Framework.Scenes
1302 1304
1303 //m_log.DebugFormat("Completed movement"); 1305 //m_log.DebugFormat("Completed movement");
1304 1306
1305 m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); 1307 m_controllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1306 SendInitialData(); 1308 SendInitialData();
1307 1309
1308 // Create child agents in neighbouring regions 1310 // Create child agents in neighbouring regions
@@ -3226,8 +3228,8 @@ namespace OpenSim.Region.Framework.Scenes
3226 /// </returns> 3228 /// </returns>
3227 protected int HaveNeighbor(Cardinals car, ref int[] fix) 3229 protected int HaveNeighbor(Cardinals car, ref int[] fix)
3228 { 3230 {
3229 uint neighbourx = m_regionInfo.RegionLocX; 3231 uint neighbourx = m_scene.RegionInfo.RegionLocX;
3230 uint neighboury = m_regionInfo.RegionLocY; 3232 uint neighboury = m_scene.RegionInfo.RegionLocY;
3231 3233
3232 int dir = (int)car; 3234 int dir = (int)car;
3233 3235
@@ -3247,8 +3249,8 @@ namespace OpenSim.Region.Framework.Scenes
3247 3249
3248 if (neighbourRegion == null) 3250 if (neighbourRegion == null)
3249 { 3251 {
3250 fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx); 3252 fix[0] = (int)(m_scene.RegionInfo.RegionLocX - neighbourx);
3251 fix[1] = (int)(m_regionInfo.RegionLocY - neighboury); 3253 fix[1] = (int)(m_scene.RegionInfo.RegionLocY - neighboury);
3252 return dir * (-1); 3254 return dir * (-1);
3253 } 3255 }
3254 else 3256 else
@@ -3494,26 +3496,30 @@ namespace OpenSim.Region.Framework.Scenes
3494 catch { } 3496 catch { }
3495 3497
3496 // Attachment objects 3498 // Attachment objects
3497 if (m_attachments != null && m_attachments.Count > 0) 3499 lock (m_attachments)
3498 { 3500 {
3499 cAgent.AttachmentObjects = new List<ISceneObject>(); 3501 if (m_attachments.Count > 0)
3500 cAgent.AttachmentObjectStates = new List<string>();
3501// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
3502 m_InTransitScriptStates.Clear();
3503 foreach (SceneObjectGroup sog in m_attachments)
3504 { 3502 {
3505 // We need to make a copy and pass that copy 3503 cAgent.AttachmentObjects = new List<ISceneObject>();
3506 // because of transfers withn the same sim 3504 cAgent.AttachmentObjectStates = new List<string>();
3507 ISceneObject clone = sog.CloneForNewScene(); 3505 // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
3508 // Attachment module assumes that GroupPosition holds the offsets...! 3506 m_InTransitScriptStates.Clear();
3509 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; 3507
3510 ((SceneObjectGroup)clone).IsAttachment = false; 3508 foreach (SceneObjectGroup sog in m_attachments)
3511 cAgent.AttachmentObjects.Add(clone); 3509 {
3512 string state = sog.GetStateSnapshot(); 3510 // We need to make a copy and pass that copy
3513 cAgent.AttachmentObjectStates.Add(state); 3511 // because of transfers withn the same sim
3514 m_InTransitScriptStates.Add(state); 3512 ISceneObject clone = sog.CloneForNewScene();
3515 // Let's remove the scripts of the original object here 3513 // Attachment module assumes that GroupPosition holds the offsets...!
3516 sog.RemoveScriptInstances(true); 3514 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
3515 ((SceneObjectGroup)clone).IsAttachment = false;
3516 cAgent.AttachmentObjects.Add(clone);
3517 string state = sog.GetStateSnapshot();
3518 cAgent.AttachmentObjectStates.Add(state);
3519 m_InTransitScriptStates.Add(state);
3520 // Let's remove the scripts of the original object here
3521 sog.RemoveScriptInstances(true);
3522 }
3517 } 3523 }
3518 } 3524 }
3519 } 3525 }
@@ -3931,7 +3937,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
3931 3937
3932 public void Close() 3938 public void Close()
3933 { 3939 {
3934 m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); 3940 if (!IsChildAgent)
3941 m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
3935 3942
3936 lock (m_knownChildRegions) 3943 lock (m_knownChildRegions)
3937 { 3944 {
@@ -4035,8 +4042,13 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4035 m_attachments.Clear(); 4042 m_attachments.Clear();
4036 } 4043 }
4037 4044
4045 /// <summary>
4046 /// This is currently just being done for information.
4047 /// </summary>
4038 public bool ValidateAttachments() 4048 public bool ValidateAttachments()
4039 { 4049 {
4050 bool validated = true;
4051
4040 lock (m_attachments) 4052 lock (m_attachments)
4041 { 4053 {
4042 // Validate 4054 // Validate
@@ -4045,21 +4057,22 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4045 if (gobj == null) 4057 if (gobj == null)
4046 { 4058 {
4047 m_log.WarnFormat( 4059 m_log.WarnFormat(
4048 "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null", Name); 4060 "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null. Continuing", Name);
4049 return false;
4050 }
4051 4061
4052 if (gobj.IsDeleted) 4062 validated = false;
4063 }
4064 else if (gobj.IsDeleted)
4053 { 4065 {
4054 m_log.WarnFormat( 4066 m_log.WarnFormat(
4055 "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted", 4067 "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted. Continuing",
4056 gobj.Name, gobj.UUID, Name); 4068 gobj.Name, gobj.UUID, Name);
4057 return false; 4069
4070 validated = false;
4058 } 4071 }
4059 } 4072 }
4060 } 4073 }
4061 4074
4062 return true; 4075 return validated;
4063 } 4076 }
4064 4077
4065 /// <summary> 4078 /// <summary>
@@ -4091,29 +4104,6 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4091 } 4104 }
4092 } 4105 }
4093 4106
4094
4095 public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene)
4096 {
4097 m_controllingClient = client;
4098 m_regionInfo = region;
4099 m_scene = scene;
4100
4101 RegisterToEvents();
4102
4103 /*
4104 AbsolutePosition = client.StartPos;
4105
4106 Animations = new AvatarAnimations();
4107 Animations.LoadAnims();
4108
4109 m_animations = new List<UUID>();
4110 m_animations.Add(Animations.AnimsUUID["STAND"]);
4111 m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber);
4112
4113 SetDirectionVectors();
4114 */
4115 }
4116
4117 internal void PushForce(Vector3 impulse) 4107 internal void PushForce(Vector3 impulse)
4118 { 4108 {
4119 if (PhysicsActor != null) 4109 if (PhysicsActor != null)
@@ -4141,6 +4131,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4141 obj.ignoreControls = (ScriptControlled)controls; 4131 obj.ignoreControls = (ScriptControlled)controls;
4142 obj.eventControls = (ScriptControlled)controls; 4132 obj.eventControls = (ScriptControlled)controls;
4143 } 4133 }
4134
4144 if (pass_on == 1 && accept == 1) 4135 if (pass_on == 1 && accept == 1)
4145 { 4136 {
4146 IgnoredControls = ScriptControlled.CONTROL_ZERO; 4137 IgnoredControls = ScriptControlled.CONTROL_ZERO;
@@ -4161,6 +4152,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4161 scriptedcontrols[Script_item_UUID] = obj; 4152 scriptedcontrols[Script_item_UUID] = obj;
4162 } 4153 }
4163 } 4154 }
4155
4164 ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); 4156 ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true);
4165 } 4157 }
4166 4158
@@ -4351,29 +4343,6 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4351 return(new Vector3(x,y,z)); 4343 return(new Vector3(x,y,z));
4352 } 4344 }
4353 4345
4354 public void SaveChangedAttachments()
4355 {
4356 // Need to copy this list because DetachToInventoryPrep mods it
4357 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(GetAttachments().ToArray());
4358
4359 IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule;
4360 if (attachmentsModule != null)
4361 {
4362 foreach (SceneObjectGroup grp in attachments)
4363 {
4364 if (grp.HasGroupChanged) // Resizer scripts?
4365 {
4366 grp.IsAttachment = false;
4367 grp.AbsolutePosition = grp.RootPart.AttachedPos;
4368// grp.DetachToInventoryPrep();
4369 attachmentsModule.UpdateKnownItem(ControllingClient,
4370 grp, grp.GetFromItemID(), grp.OwnerID);
4371 grp.IsAttachment = true;
4372 }
4373 }
4374 }
4375 }
4376
4377 private void CheckLandingPoint(ref Vector3 pos) 4346 private void CheckLandingPoint(ref Vector3 pos)
4378 { 4347 {
4379 // Never constrain lures 4348 // Never constrain lures
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index 501487a..8a0d288 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -38,27 +38,42 @@ namespace OpenSim.Region.Framework.Scenes
38{ 38{
39 public class SceneViewer : ISceneViewer 39 public class SceneViewer : ISceneViewer
40 { 40 {
41 /// <summary>
42 /// Is this scene viewer enabled?
43 /// </summary>
44 private bool IsEnabled { get; set; }
45
46 /// <summary>
47 /// The scene presence serviced by this viewer.
48 /// </summary>
41 protected ScenePresence m_presence; 49 protected ScenePresence m_presence;
50
51 /// <summary>
52 /// The queue of parts for which we need to send out updates.
53 /// </summary>
42 protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); 54 protected UpdateQueue m_partsUpdateQueue = new UpdateQueue();
55
56 /// <summary>
57 /// The queue of objects for which we need to send out updates.
58 /// </summary>
43 protected Queue<SceneObjectGroup> m_pendingObjects; 59 protected Queue<SceneObjectGroup> m_pendingObjects;
44 60
61 /// <summary>
62 /// The last update assocated with a given part update.
63 /// </summary>
45 protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); 64 protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>();
46 65
47 public SceneViewer()
48 {
49 }
50
51 public SceneViewer(ScenePresence presence) 66 public SceneViewer(ScenePresence presence)
52 { 67 {
53 m_presence = presence; 68 m_presence = presence;
69 IsEnabled = true;
54 } 70 }
55 71
56 /// <summary>
57 /// Add the part to the queue of parts for which we need to send an update to the client
58 /// </summary>
59 /// <param name="part"></param>
60 public void QueuePartForUpdate(SceneObjectPart part) 72 public void QueuePartForUpdate(SceneObjectPart part)
61 { 73 {
74 if (!IsEnabled)
75 return;
76
62 lock (m_partsUpdateQueue) 77 lock (m_partsUpdateQueue)
63 { 78 {
64 m_partsUpdateQueue.Enqueue(part); 79 m_partsUpdateQueue.Enqueue(part);
@@ -87,6 +102,11 @@ namespace OpenSim.Region.Framework.Scenes
87 102
88 lock (m_pendingObjects) 103 lock (m_pendingObjects)
89 { 104 {
105 // We must do this under lock so that we don't suffer a race condition if another thread closes the
106 // viewer
107 if (!IsEnabled)
108 return;
109
90 while (m_pendingObjects != null && m_pendingObjects.Count > 0) 110 while (m_pendingObjects != null && m_pendingObjects.Count > 0)
91 { 111 {
92 SceneObjectGroup g = m_pendingObjects.Dequeue(); 112 SceneObjectGroup g = m_pendingObjects.Dequeue();
@@ -119,7 +139,6 @@ namespace OpenSim.Region.Framework.Scenes
119 139
120 // We deal with the possibility that two updates occur at 140 // We deal with the possibility that two updates occur at
121 // the same unix time at the update point itself. 141 // the same unix time at the update point itself.
122
123 if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment) 142 if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment)
124 { 143 {
125 // m_log.DebugFormat( 144 // m_log.DebugFormat(
@@ -135,9 +154,7 @@ namespace OpenSim.Region.Framework.Scenes
135 // this update. If this happened, then subsequent 154 // this update. If this happened, then subsequent
136 // updates which occurred on the same tick or the 155 // updates which occurred on the same tick or the
137 // next tick of the last update would be ignored. 156 // next tick of the last update would be ignored.
138
139 update.LastFullUpdateTime = part.TimeStampFull; 157 update.LastFullUpdateTime = part.TimeStampFull;
140
141 } 158 }
142 else if (update.LastTerseUpdateTime <= part.TimeStampTerse) 159 else if (update.LastTerseUpdateTime <= part.TimeStampTerse)
143 { 160 {
@@ -176,38 +193,46 @@ namespace OpenSim.Region.Framework.Scenes
176 } 193 }
177 } 194 }
178 195
179 public void Reset() 196// public void Reset()
180 { 197// {
181 if (m_pendingObjects == null) 198// if (m_pendingObjects == null)
182 return; 199// return;
200//
201// lock (m_pendingObjects)
202// {
203// if (m_pendingObjects != null)
204// {
205// m_pendingObjects.Clear();
206// m_pendingObjects = null;
207// }
208// }
209// }
183 210
211 public void Close()
212 {
184 lock (m_pendingObjects) 213 lock (m_pendingObjects)
185 { 214 {
186 if (m_pendingObjects != null) 215 // We perform this under the m_pendingObjects lock in order to avoid a race condition with another
216 // thread on SendPrimUpdates()
217 IsEnabled = false;
218
219 lock (m_updateTimes)
187 { 220 {
188 m_pendingObjects.Clear(); 221 m_updateTimes.Clear();
189 m_pendingObjects = null;
190 } 222 }
191 }
192 }
193 223
194 public void Close() 224 lock (m_partsUpdateQueue)
195 { 225 {
196 lock (m_updateTimes) 226 m_partsUpdateQueue.Clear();
197 { 227 }
198 m_updateTimes.Clear();
199 }
200 lock (m_partsUpdateQueue)
201 {
202 m_partsUpdateQueue.Clear();
203 } 228 }
204 Reset();
205 } 229 }
206 230
207 public int GetPendingObjectsCount() 231 public int GetPendingObjectsCount()
208 { 232 {
209 if (m_pendingObjects != null) 233 if (m_pendingObjects != null)
210 return m_pendingObjects.Count; 234 lock (m_pendingObjects)
235 return m_pendingObjects.Count;
211 236
212 return 0; 237 return 0;
213 } 238 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
index 1ea2329..80f198d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
@@ -52,22 +52,25 @@ namespace OpenSim.Region.Framework.Scenes.Tests
52 TestHelpers.InMethod(); 52 TestHelpers.InMethod();
53 53
54 Scene scene = SceneHelpers.SetupScene(); 54 Scene scene = SceneHelpers.SetupScene();
55 int partsToTestCount = 3;
55 56
56 string objName = "obj1"; 57 SceneObjectGroup so
57 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); 58 = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10);
58 59 SceneObjectPart[] parts = so.Parts;
59 SceneObjectPart part
60 = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
61 { Name = objName, UUID = objUuid };
62 60
63 Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part), false), Is.True); 61 Assert.That(scene.AddNewSceneObject(so, false), Is.True);
64 62 SceneObjectGroup retrievedSo = scene.GetSceneObjectGroup(so.UUID);
65 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid); 63 SceneObjectPart[] retrievedParts = retrievedSo.Parts;
66 64
67 //m_log.Debug("retrievedPart : {0}", retrievedPart); 65 //m_log.Debug("retrievedPart : {0}", retrievedPart);
68 // If the parts have the same UUID then we will consider them as one and the same 66 // If the parts have the same UUID then we will consider them as one and the same
69 Assert.That(retrievedPart.Name, Is.EqualTo(objName)); 67 Assert.That(retrievedSo.PrimCount, Is.EqualTo(partsToTestCount));
70 Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); 68
69 for (int i = 0; i < partsToTestCount; i++)
70 {
71 Assert.That(retrievedParts[i].Name, Is.EqualTo(parts[i].Name));
72 Assert.That(retrievedParts[i].UUID, Is.EqualTo(parts[i].UUID));
73 }
71 } 74 }
72 75
73 [Test] 76 [Test]
@@ -103,6 +106,39 @@ namespace OpenSim.Region.Framework.Scenes.Tests
103 Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name)); 106 Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name));
104 Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); 107 Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
105 } 108 }
109
110 /// <summary>
111 /// Test retrieving a scene object via the local id of one of its parts.
112 /// </summary>
113 [Test]
114 public void TestGetSceneObjectByPartLocalId()
115 {
116 TestHelpers.InMethod();
117
118 Scene scene = SceneHelpers.SetupScene();
119 int partsToTestCount = 3;
120
121 SceneObjectGroup so
122 = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10);
123 SceneObjectPart[] parts = so.Parts;
124
125 scene.AddNewSceneObject(so, false);
126
127 // Test getting via the root part's local id
128 Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Not.Null);
129
130 // Test getting via a non root part's local id
131 Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Not.Null);
132
133 // Test that we don't get back an object for a local id that doesn't exist
134 Assert.That(scene.GetGroupByPrim(999), Is.Null);
135
136 // Now delete the scene object and check again
137 scene.DeleteSceneObject(so, false);
138
139 Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Null);
140 Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Null);
141 }
106 142
107 /// <summary> 143 /// <summary>
108 /// Test deleting an object from a scene. 144 /// Test deleting an object from a scene.
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index fdfbc78..8d41f00 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -43,11 +43,12 @@ namespace OpenSim.Region.Framework.Scenes
43 /// <summary> 43 /// <summary>
44 /// Gather uuids for a given entity. 44 /// Gather uuids for a given entity.
45 /// </summary> 45 /// </summary>
46 /// 46 /// <remarks>
47 /// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts 47 /// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts
48 /// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets 48 /// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets
49 /// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be 49 /// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be
50 /// retrieved to work out which assets it references). 50 /// retrieved to work out which assets it references).
51 /// </remarks>
51 public class UuidGatherer 52 public class UuidGatherer
52 { 53 {
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -76,11 +77,11 @@ namespace OpenSim.Region.Framework.Scenes
76 /// <summary> 77 /// <summary>
77 /// Gather all the asset uuids associated with the asset referenced by a given uuid 78 /// Gather all the asset uuids associated with the asset referenced by a given uuid
78 /// </summary> 79 /// </summary>
79 /// 80 /// <remarks>
80 /// This includes both those directly associated with 81 /// This includes both those directly associated with
81 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained 82 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
82 /// within this object). 83 /// within this object).
83 /// 84 /// </remarks>
84 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> 85 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
85 /// <param name="assetType">The type of the asset for the uuid given</param> 86 /// <param name="assetType">The type of the asset for the uuid given</param>
86 /// <param name="assetUuids">The assets gathered</param> 87 /// <param name="assetUuids">The assets gathered</param>
@@ -119,11 +120,11 @@ namespace OpenSim.Region.Framework.Scenes
119 /// <summary> 120 /// <summary>
120 /// Gather all the asset uuids associated with a given object. 121 /// Gather all the asset uuids associated with a given object.
121 /// </summary> 122 /// </summary>
122 /// 123 /// <remarks>
123 /// This includes both those directly associated with 124 /// This includes both those directly associated with
124 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained 125 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
125 /// within this object). 126 /// within this object).
126 /// 127 /// </remarks>
127 /// <param name="sceneObject">The scene object for which to gather assets</param> 128 /// <param name="sceneObject">The scene object for which to gather assets</param>
128 /// <param name="assetUuids">The assets gathered</param> 129 /// <param name="assetUuids">The assets gathered</param>
129 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids) 130 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids)