aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs62
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs135
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs92
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs119
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs81
6 files changed, 340 insertions, 161 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 3fd7485..55766cf 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4121,32 +4121,52 @@ namespace OpenSim.Region.Framework.Scenes
4121 } 4121 }
4122 } 4122 }
4123 4123
4124// m_log.DebugFormat(
4125// "[SCENE]: Found telehub object {0} for new user connection {1} to {2}",
4126// RegionInfo.RegionSettings.TelehubObject, acd.Name, Name);
4127
4124 // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags 4128 // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags
4125 if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero && 4129 if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero &&
4126 RegionInfo.EstateSettings.AllowDirectTeleport == false && 4130 RegionInfo.EstateSettings.AllowDirectTeleport == false &&
4127 !viahome && !godlike) 4131 !viahome && !godlike)
4128 { 4132 {
4129 SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); 4133 SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject);
4130 // Can have multiple SpawnPoints 4134
4131 List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints(); 4135 if (telehub != null)
4132 if (spawnpoints.Count > 1)
4133 { 4136 {
4134 // We have multiple SpawnPoints, Route the agent to a random or sequential one 4137 // Can have multiple SpawnPoints
4135 if (SpawnPointRouting == "random") 4138 List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints();
4136 acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( 4139 if (spawnpoints.Count > 1)
4137 telehub.AbsolutePosition, 4140 {
4138 telehub.GroupRotation 4141 // We have multiple SpawnPoints, Route the agent to a random or sequential one
4139 ); 4142 if (SpawnPointRouting == "random")
4143 acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation(
4144 telehub.AbsolutePosition,
4145 telehub.GroupRotation
4146 );
4147 else
4148 acd.startpos = spawnpoints[SpawnPoint()].GetLocation(
4149 telehub.AbsolutePosition,
4150 telehub.GroupRotation
4151 );
4152 }
4153 else if (spawnpoints.Count == 1)
4154 {
4155 // We have a single SpawnPoint and will route the agent to it
4156 acd.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4157 }
4140 else 4158 else
4141 acd.startpos = spawnpoints[SpawnPoint()].GetLocation( 4159 {
4142 telehub.AbsolutePosition, 4160 m_log.DebugFormat(
4143 telehub.GroupRotation 4161 "[SCENE]: No spawnpoints defined for telehub {0} for {1} in {2}. Continuing.",
4144 ); 4162 RegionInfo.RegionSettings.TelehubObject, acd.Name, Name);
4163 }
4145 } 4164 }
4146 else 4165 else
4147 { 4166 {
4148 // We have a single SpawnPoint and will route the agent to it 4167 m_log.DebugFormat(
4149 acd.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4168 "[SCENE]: No telehub {0} found to direct {1} in {2}. Continuing.",
4169 RegionInfo.RegionSettings.TelehubObject, acd.Name, Name);
4150 } 4170 }
4151 4171
4152 return true; 4172 return true;
@@ -4593,18 +4613,6 @@ namespace OpenSim.Region.Framework.Scenes
4593 return sp; 4613 return sp;
4594 } 4614 }
4595 4615
4596 public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent)
4597 {
4598 agent = null;
4599 ScenePresence sp = GetScenePresence(id);
4600 if ((sp != null) && (!sp.IsChildAgent))
4601 {
4602 sp.IsChildAgent = true;
4603 return sp.CopyAgent(out agent);
4604 }
4605
4606 return false;
4607 }
4608 /// <summary> 4616 /// <summary>
4609 /// Authenticated close (via network) 4617 /// Authenticated close (via network)
4610 /// </summary> 4618 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 252c72f..f57d4fe 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -109,6 +109,16 @@ namespace OpenSim.Region.Framework.Scenes
109 } 109 }
110 } 110 }
111 111
112 /// <summary>
113 /// This exists to prevent race conditions between two CompleteMovement threads if the simulator is slow and
114 /// the viewer fires these in quick succession.
115 /// </summary>
116 /// <remarks>
117 /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement
118 /// regulation done there.
119 /// </remarks>
120 private object m_completeMovementLock = new object();
121
112// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 122// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
113 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); 123 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
114 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); 124 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
@@ -984,6 +994,7 @@ namespace OpenSim.Region.Framework.Scenes
984 /// <summary> 994 /// <summary>
985 /// Turns a child agent into a root agent. 995 /// Turns a child agent into a root agent.
986 /// </summary> 996 /// </summary>
997 /// <remarks>
987 /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the 998 /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the
988 /// avatar is actual in the sim. They can perform all actions. 999 /// avatar is actual in the sim. They can perform all actions.
989 /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, 1000 /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim,
@@ -991,49 +1002,52 @@ namespace OpenSim.Region.Framework.Scenes
991 /// 1002 ///
992 /// This method is on the critical path for transferring an avatar from one region to another. Delay here 1003 /// This method is on the critical path for transferring an avatar from one region to another. Delay here
993 /// delays that crossing. 1004 /// delays that crossing.
994 /// </summary> 1005 /// </remarks>
995 private void MakeRootAgent(Vector3 pos, bool isFlying) 1006 private bool MakeRootAgent(Vector3 pos, bool isFlying)
996 { 1007 {
997// m_log.InfoFormat( 1008 lock (m_completeMovementLock)
998// "[SCENE]: Upgrading child to root agent for {0} in {1}",
999// Name, m_scene.RegionInfo.RegionName);
1000
1001 if (ParentUUID != UUID.Zero)
1002 { 1009 {
1003 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); 1010 if (!IsChildAgent)
1004 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); 1011 return false;
1005 if (part == null) 1012
1013 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
1014
1015 // m_log.InfoFormat(
1016 // "[SCENE]: Upgrading child to root agent for {0} in {1}",
1017 // Name, m_scene.RegionInfo.RegionName);
1018
1019 if (ParentUUID != UUID.Zero)
1006 { 1020 {
1007 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); 1021 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1022 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1023 if (part == null)
1024 {
1025 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1026 }
1027 else
1028 {
1029 part.ParentGroup.AddAvatar(UUID);
1030 if (part.SitTargetPosition != Vector3.Zero)
1031 part.SitTargetAvatar = UUID;
1032 // ParentPosition = part.GetWorldPosition();
1033 ParentID = part.LocalId;
1034 ParentPart = part;
1035 m_pos = PrevSitOffset;
1036 // pos = ParentPosition;
1037 pos = part.GetWorldPosition();
1038 }
1039 ParentUUID = UUID.Zero;
1040
1041 // Animator.TrySetMovementAnimation("SIT");
1008 } 1042 }
1009 else 1043 else
1010 { 1044 {
1011 part.ParentGroup.AddAvatar(UUID); 1045 IsLoggingIn = false;
1012 if (part.SitTargetPosition != Vector3.Zero)
1013 part.SitTargetAvatar = UUID;
1014// ParentPosition = part.GetWorldPosition();
1015 ParentID = part.LocalId;
1016 ParentPart = part;
1017 m_pos = PrevSitOffset;
1018// pos = ParentPosition;
1019 pos = part.GetWorldPosition();
1020 } 1046 }
1021 ParentUUID = UUID.Zero;
1022
1023 IsChildAgent = false;
1024 1047
1025// Animator.TrySetMovementAnimation("SIT");
1026 }
1027 else
1028 {
1029 IsChildAgent = false; 1048 IsChildAgent = false;
1030 IsLoggingIn = false;
1031 } 1049 }
1032 1050
1033 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
1034
1035 IsChildAgent = false;
1036
1037 // Must reset this here so that a teleport to a region next to an existing region does not keep the flag 1051 // Must reset this here so that a teleport to a region next to an existing region does not keep the flag
1038 // set and prevent the close of the connection on a subsequent re-teleport. 1052 // set and prevent the close of the connection on a subsequent re-teleport.
1039 // Should not be needed if we are not trying to tell this region to close 1053 // Should not be needed if we are not trying to tell this region to close
@@ -1178,22 +1192,36 @@ namespace OpenSim.Region.Framework.Scenes
1178 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1192 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1179 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1193 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1180 // not transporting the required data. 1194 // not transporting the required data.
1181 lock (m_attachments) 1195 //
1196 // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
1197 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1198 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1199 // not transporting the required data.
1200 //
1201 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1202 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1203 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
1204 //
1205 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
1206 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1207 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1208 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1209 //
1210 // One cannot simply iterate over attachments in a fire and forget thread because this would no longer
1211 // be locked, allowing race conditions if other code changes the attachments list.
1212 List<SceneObjectGroup> attachments = GetAttachments();
1213
1214 if (attachments.Count > 0)
1182 { 1215 {
1183 if (HasAttachments()) 1216 m_log.DebugFormat(
1184 { 1217 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1185 m_log.DebugFormat(
1186 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1187 1218
1188 // Resume scripts 1219 // Resume scripts
1189 Util.FireAndForget(delegate(object x) { 1220 foreach (SceneObjectGroup sog in attachments)
1190 foreach (SceneObjectGroup sog in m_attachments) 1221 {
1191 { 1222 sog.ScheduleGroupForFullUpdate();
1192 sog.ScheduleGroupForFullUpdate(); 1223 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1193 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1224 sog.ResumeScripts();
1194 sog.ResumeScripts();
1195 }
1196 });
1197 } 1225 }
1198 } 1226 }
1199 } 1227 }
@@ -1215,6 +1243,7 @@ namespace OpenSim.Region.Framework.Scenes
1215 1243
1216 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1244 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1217 1245
1246 return true;
1218 } 1247 }
1219 1248
1220 public int GetStateSource() 1249 public int GetStateSource()
@@ -1637,7 +1666,14 @@ namespace OpenSim.Region.Framework.Scenes
1637 } 1666 }
1638 1667
1639 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1668 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1640 MakeRootAgent(AbsolutePosition, flying); 1669 if (!MakeRootAgent(AbsolutePosition, flying))
1670 {
1671 m_log.DebugFormat(
1672 "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root",
1673 Name, Scene.Name);
1674
1675 return;
1676 }
1641 1677
1642 // Tell the client that we're totally ready 1678 // Tell the client that we're totally ready
1643 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); 1679 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
@@ -2884,7 +2920,6 @@ namespace OpenSim.Region.Framework.Scenes
2884 Rotation = newRot; 2920 Rotation = newRot;
2885 2921
2886// ParentPosition = part.AbsolutePosition; 2922// ParentPosition = part.AbsolutePosition;
2887 part.ParentGroup.AddAvatar(UUID);
2888 } 2923 }
2889 else 2924 else
2890 { 2925 {
@@ -2893,13 +2928,13 @@ namespace OpenSim.Region.Framework.Scenes
2893 m_pos -= part.GroupPosition; 2928 m_pos -= part.GroupPosition;
2894 2929
2895// ParentPosition = part.AbsolutePosition; 2930// ParentPosition = part.AbsolutePosition;
2896 part.ParentGroup.AddAvatar(UUID);
2897 2931
2898// m_log.DebugFormat( 2932// m_log.DebugFormat(
2899// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2933// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
2900// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); 2934// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
2901 } 2935 }
2902 2936
2937 part.ParentGroup.AddAvatar(UUID);
2903 ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID); 2938 ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
2904 ParentID = m_requestedSitTargetID; 2939 ParentID = m_requestedSitTargetID;
2905 m_AngularVelocity = Vector3.Zero; 2940 m_AngularVelocity = Vector3.Zero;
@@ -3210,6 +3245,8 @@ namespace OpenSim.Region.Framework.Scenes
3210 // again here... this comes after the cached appearance check because the avatars 3245 // again here... this comes after the cached appearance check because the avatars
3211 // appearance goes into the avatar update packet 3246 // appearance goes into the avatar update packet
3212 SendAvatarDataToAllAgents(); 3247 SendAvatarDataToAllAgents();
3248
3249 // This invocation always shows up in the viewer logs as an error. Is it needed?
3213 SendAppearanceToAgent(this); 3250 SendAppearanceToAgent(this);
3214 3251
3215 // If we are using the the cached appearance then send it out to everyone 3252 // If we are using the the cached appearance then send it out to everyone
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index d1aeaee..1ff1329 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -111,6 +111,45 @@ namespace OpenSim.Region.Framework.Scenes.Tests
111 Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1)); 111 Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1));
112 } 112 }
113 113
114 /// <summary>
115 /// Test that duplicate complete movement calls are ignored.
116 /// </summary>
117 /// <remarks>
118 /// If duplicate calls are not ignored then there is a risk of race conditions or other unexpected effects.
119 /// </remarks>
120 [Test]
121 public void TestDupeCompleteMovementCalls()
122 {
123 TestHelpers.InMethod();
124// TestHelpers.EnableLogging();
125
126 UUID spUuid = TestHelpers.ParseTail(0x1);
127
128 TestScene scene = new SceneHelpers().SetupScene();
129
130 int makeRootAgentEvents = 0;
131 scene.EventManager.OnMakeRootAgent += spi => makeRootAgentEvents++;
132
133 ScenePresence sp = SceneHelpers.AddScenePresence(scene, spUuid);
134
135 Assert.That(makeRootAgentEvents, Is.EqualTo(1));
136
137 // Normally these would be invoked by a CompleteMovement message coming in to the UDP stack. But for
138 // convenience, here we will invoke it manually.
139 sp.CompleteMovement(sp.ControllingClient, true);
140
141 Assert.That(makeRootAgentEvents, Is.EqualTo(1));
142
143 // Check rest of exepcted parameters.
144 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(spUuid), Is.Not.Null);
145 Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1));
146
147 Assert.That(sp.IsChildAgent, Is.False);
148 Assert.That(sp.UUID, Is.EqualTo(spUuid));
149
150 Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1));
151 }
152
114 [Test] 153 [Test]
115 public void TestCreateDuplicateRootScenePresence() 154 public void TestCreateDuplicateRootScenePresence()
116 { 155 {
@@ -249,58 +288,5 @@ namespace OpenSim.Region.Framework.Scenes.Tests
249// Assert.That(childPresence, Is.Not.Null); 288// Assert.That(childPresence, Is.Not.Null);
250// Assert.That(childPresence.IsChildAgent, Is.True); 289// Assert.That(childPresence.IsChildAgent, Is.True);
251 } 290 }
252
253// /// <summary>
254// /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene.
255// /// </summary>
256// [Test]
257// public void T010_TestAddRootAgent()
258// {
259// TestHelpers.InMethod();
260//
261// string firstName = "testfirstname";
262//
263// AgentCircuitData agent = new AgentCircuitData();
264// agent.AgentID = agent1;
265// agent.firstname = firstName;
266// agent.lastname = "testlastname";
267// agent.SessionID = UUID.Random();
268// agent.SecureSessionID = UUID.Random();
269// agent.circuitcode = 123;
270// agent.BaseFolder = UUID.Zero;
271// agent.InventoryFolder = UUID.Zero;
272// agent.startpos = Vector3.Zero;
273// agent.CapsPath = GetRandomCapsObjectPath();
274// agent.ChildrenCapSeeds = new Dictionary<ulong, string>();
275// agent.child = true;
276//
277// scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID);
278//
279// string reason;
280// scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason);
281// testclient = new TestClient(agent, scene);
282// scene.AddNewAgent(testclient);
283//
284// ScenePresence presence = scene.GetScenePresence(agent1);
285//
286// Assert.That(presence, Is.Not.Null, "presence is null");
287// Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same");
288// acd1 = agent;
289// }
290//
291// /// <summary>
292// /// Test removing an uncrossed root agent from a scene.
293// /// </summary>
294// [Test]
295// public void T011_TestRemoveRootAgent()
296// {
297// TestHelpers.InMethod();
298//
299// scene.RemoveClient(agent1);
300//
301// ScenePresence presence = scene.GetScenePresence(agent1);
302//
303// Assert.That(presence, Is.Null, "presence is not null");
304// }
305 } 291 }
306} \ No newline at end of file 292} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs
new file mode 100644
index 0000000..9a97acc
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs
@@ -0,0 +1,119 @@
1/*
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that the following conditions are met:
4 * * Redistributions of source code must retain the above copyright
5 * notice, this list of conditions and the following disclaimer.
6 * * Redistributions in binary form must reproduce the above copyright
7 * notice, this list of conditions and the following disclaimer in the
8 * documentation and/or other materials provided with the distribution.
9 * * Neither the name of the OpenSimulator Project nor the
10 * names of its contributors may be used to endorse or promote products
11 * derived from this software without specific prior written permission.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25using System;
26using Nini.Config;
27using NUnit.Framework;
28using OpenMetaverse;
29using OpenSim.Framework;
30using OpenSim.Region.CoreModules.World.Estate;
31using OpenSim.Region.Framework.Scenes;
32using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Services.Interfaces;
34using OpenSim.Tests.Common;
35using OpenSim.Tests.Common.Mock;
36
37namespace OpenSim.Region.Framework.Scenes.Tests
38{
39 /// <summary>
40 /// Scene telehub tests
41 /// </summary>
42 /// <remarks>
43 /// TODO: Tests which run through normal functionality. Currently, the only test is one that checks behaviour
44 /// in the case of an error condition
45 /// </remarks>
46 [TestFixture]
47 public class SceneTelehubTests : OpenSimTestCase
48 {
49 /// <summary>
50 /// Test for desired behaviour when a telehub has no spawn points
51 /// </summary>
52 [Test]
53 public void TestNoTelehubSpawnPoints()
54 {
55 TestHelpers.InMethod();
56// TestHelpers.EnableLogging();
57
58 EstateManagementModule emm = new EstateManagementModule();
59
60 SceneHelpers sh = new SceneHelpers();
61 Scene scene = sh.SetupScene();
62 SceneHelpers.SetupSceneModules(scene, emm);
63
64 UUID telehubSceneObjectOwner = TestHelpers.ParseTail(0x1);
65
66 SceneObjectGroup telehubSo = SceneHelpers.AddSceneObject(scene, "telehubObject", telehubSceneObjectOwner);
67
68 emm.HandleOnEstateManageTelehub(null, UUID.Zero, UUID.Zero, "connect", telehubSo.LocalId);
69 scene.RegionInfo.EstateSettings.AllowDirectTeleport = false;
70
71 // Must still be possible to successfully log in
72 UUID loggingInUserId = TestHelpers.ParseTail(0x2);
73
74 UserAccount ua
75 = UserAccountHelpers.CreateUserWithInventory(scene, "Test", "User", loggingInUserId, "password");
76
77 SceneHelpers.AddScenePresence(scene, ua);
78
79 Assert.That(scene.GetScenePresence(loggingInUserId), Is.Not.Null);
80 }
81
82 /// <summary>
83 /// Test for desired behaviour when the scene object nominated as a telehub object does not exist.
84 /// </summary>
85 [Test]
86 public void TestNoTelehubSceneObject()
87 {
88 TestHelpers.InMethod();
89// TestHelpers.EnableLogging();
90
91 EstateManagementModule emm = new EstateManagementModule();
92
93 SceneHelpers sh = new SceneHelpers();
94 Scene scene = sh.SetupScene();
95 SceneHelpers.SetupSceneModules(scene, emm);
96
97 UUID telehubSceneObjectOwner = TestHelpers.ParseTail(0x1);
98
99 SceneObjectGroup telehubSo = SceneHelpers.AddSceneObject(scene, "telehubObject", telehubSceneObjectOwner);
100 SceneObjectGroup spawnPointSo = SceneHelpers.AddSceneObject(scene, "spawnpointObject", telehubSceneObjectOwner);
101
102 emm.HandleOnEstateManageTelehub(null, UUID.Zero, UUID.Zero, "connect", telehubSo.LocalId);
103 emm.HandleOnEstateManageTelehub(null, UUID.Zero, UUID.Zero, "spawnpoint add", spawnPointSo.LocalId);
104 scene.RegionInfo.EstateSettings.AllowDirectTeleport = false;
105
106 scene.DeleteSceneObject(telehubSo, false);
107
108 // Must still be possible to successfully log in
109 UUID loggingInUserId = TestHelpers.ParseTail(0x2);
110
111 UserAccount ua
112 = UserAccountHelpers.CreateUserWithInventory(scene, "Test", "User", loggingInUserId, "password");
113
114 SceneHelpers.AddScenePresence(scene, ua);
115
116 Assert.That(scene.GetScenePresence(loggingInUserId), Is.Not.Null);
117 }
118 }
119} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
index dd27294..1e59e3f 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
@@ -62,8 +62,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
62 = AssetHelpers.CreateAsset(corruptAssetUuid, AssetType.Notecard, "CORRUPT ASSET", UUID.Zero); 62 = AssetHelpers.CreateAsset(corruptAssetUuid, AssetType.Notecard, "CORRUPT ASSET", UUID.Zero);
63 m_assetService.Store(corruptAsset); 63 m_assetService.Store(corruptAsset);
64 64
65 IDictionary<UUID, AssetType> foundAssetUuids = new Dictionary<UUID, AssetType>(); 65 IDictionary<UUID, sbyte> foundAssetUuids = new Dictionary<UUID, sbyte>();
66 m_uuidGatherer.GatherAssetUuids(corruptAssetUuid, AssetType.Object, foundAssetUuids); 66 m_uuidGatherer.GatherAssetUuids(corruptAssetUuid, (sbyte)AssetType.Object, foundAssetUuids);
67 67
68 // We count the uuid as gathered even if the asset itself is corrupt. 68 // We count the uuid as gathered even if the asset itself is corrupt.
69 Assert.That(foundAssetUuids.Count, Is.EqualTo(1)); 69 Assert.That(foundAssetUuids.Count, Is.EqualTo(1));
@@ -78,9 +78,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
78 TestHelpers.InMethod(); 78 TestHelpers.InMethod();
79 79
80 UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); 80 UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
81 IDictionary<UUID, AssetType> foundAssetUuids = new Dictionary<UUID, AssetType>(); 81 IDictionary<UUID, sbyte> foundAssetUuids = new Dictionary<UUID, sbyte>();
82 82
83 m_uuidGatherer.GatherAssetUuids(missingAssetUuid, AssetType.Object, foundAssetUuids); 83 m_uuidGatherer.GatherAssetUuids(missingAssetUuid, (sbyte)AssetType.Object, foundAssetUuids);
84 84
85 // We count the uuid as gathered even if the asset itself is missing. 85 // We count the uuid as gathered even if the asset itself is missing.
86 Assert.That(foundAssetUuids.Count, Is.EqualTo(1)); 86 Assert.That(foundAssetUuids.Count, Is.EqualTo(1));
@@ -103,8 +103,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
103 AssetBase ncAsset = AssetHelpers.CreateNotecardAsset(ncAssetId, soAssetId.ToString()); 103 AssetBase ncAsset = AssetHelpers.CreateNotecardAsset(ncAssetId, soAssetId.ToString());
104 m_assetService.Store(ncAsset); 104 m_assetService.Store(ncAsset);
105 105
106 IDictionary<UUID, AssetType> foundAssetUuids = new Dictionary<UUID, AssetType>(); 106 IDictionary<UUID, sbyte> foundAssetUuids = new Dictionary<UUID, sbyte>();
107 m_uuidGatherer.GatherAssetUuids(ncAssetId, AssetType.Notecard, foundAssetUuids); 107 m_uuidGatherer.GatherAssetUuids(ncAssetId, (sbyte)AssetType.Notecard, foundAssetUuids);
108 108
109 // We count the uuid as gathered even if the asset itself is corrupt. 109 // We count the uuid as gathered even if the asset itself is corrupt.
110 Assert.That(foundAssetUuids.Count, Is.EqualTo(2)); 110 Assert.That(foundAssetUuids.Count, Is.EqualTo(2));
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index d8309d8..67655d6 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -38,6 +38,7 @@ using OpenMetaverse.StructuredData;
38using OpenSim.Framework; 38using OpenSim.Framework;
39using OpenSim.Region.Framework.Scenes.Serialization; 39using OpenSim.Region.Framework.Scenes.Serialization;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41using OpenSimAssetType = OpenSim.Framework.SLUtil.OpenSimAssetType;
41 42
42namespace OpenSim.Region.Framework.Scenes 43namespace OpenSim.Region.Framework.Scenes
43{ 44{
@@ -83,29 +84,33 @@ namespace OpenSim.Region.Framework.Scenes
83 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> 84 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
84 /// <param name="assetType">The type of the asset for the uuid given</param> 85 /// <param name="assetType">The type of the asset for the uuid given</param>
85 /// <param name="assetUuids">The assets gathered</param> 86 /// <param name="assetUuids">The assets gathered</param>
86 public void GatherAssetUuids(UUID assetUuid, AssetType assetType, IDictionary<UUID, AssetType> assetUuids) 87 public void GatherAssetUuids(UUID assetUuid, sbyte assetType, IDictionary<UUID, sbyte> assetUuids)
87 { 88 {
88 try 89 try
89 { 90 {
90 assetUuids[assetUuid] = assetType; 91 assetUuids[assetUuid] = assetType;
91 92
92 if (AssetType.Bodypart == assetType || AssetType.Clothing == assetType) 93 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
93 { 94 {
94 GetWearableAssetUuids(assetUuid, assetUuids); 95 GetWearableAssetUuids(assetUuid, assetUuids);
95 } 96 }
96 else if (AssetType.Gesture == assetType) 97 else if ((sbyte)AssetType.Gesture == assetType)
97 { 98 {
98 GetGestureAssetUuids(assetUuid, assetUuids); 99 GetGestureAssetUuids(assetUuid, assetUuids);
99 } 100 }
100 else if (AssetType.Notecard == assetType) 101 else if ((sbyte)AssetType.Notecard == assetType)
101 { 102 {
102 GetTextEmbeddedAssetUuids(assetUuid, assetUuids); 103 GetTextEmbeddedAssetUuids(assetUuid, assetUuids);
103 } 104 }
104 else if (AssetType.LSLText == assetType) 105 else if ((sbyte)AssetType.LSLText == assetType)
105 { 106 {
106 GetTextEmbeddedAssetUuids(assetUuid, assetUuids); 107 GetTextEmbeddedAssetUuids(assetUuid, assetUuids);
107 } 108 }
108 else if (AssetType.Object == assetType) 109 else if ((sbyte)OpenSimAssetType.Material == assetType)
110 {
111 GetMaterialAssetUuids(assetUuid, assetUuids);
112 }
113 else if ((sbyte)AssetType.Object == assetType)
109 { 114 {
110 GetSceneObjectAssetUuids(assetUuid, assetUuids); 115 GetSceneObjectAssetUuids(assetUuid, assetUuids);
111 } 116 }
@@ -132,7 +137,7 @@ namespace OpenSim.Region.Framework.Scenes
132 /// A dictionary which is populated with the asset UUIDs gathered and the type of that asset. 137 /// A dictionary which is populated with the asset UUIDs gathered and the type of that asset.
133 /// For assets where the type is not clear (e.g. UUIDs extracted from LSL and notecards), the type is Unknown. 138 /// For assets where the type is not clear (e.g. UUIDs extracted from LSL and notecards), the type is Unknown.
134 /// </param> 139 /// </param>
135 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids) 140 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, sbyte> assetUuids)
136 { 141 {
137// m_log.DebugFormat( 142// m_log.DebugFormat(
138// "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); 143// "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
@@ -152,7 +157,7 @@ namespace OpenSim.Region.Framework.Scenes
152 { 157 {
153 // Get the prim's default texture. This will be used for faces which don't have their own texture 158 // Get the prim's default texture. This will be used for faces which don't have their own texture
154 if (textureEntry.DefaultTexture != null) 159 if (textureEntry.DefaultTexture != null)
155 assetUuids[textureEntry.DefaultTexture.TextureID] = AssetType.Texture; 160 assetUuids[textureEntry.DefaultTexture.TextureID] = (sbyte)AssetType.Texture;
156 161
157 if (textureEntry.FaceTextures != null) 162 if (textureEntry.FaceTextures != null)
158 { 163 {
@@ -160,20 +165,20 @@ namespace OpenSim.Region.Framework.Scenes
160 foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures) 165 foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures)
161 { 166 {
162 if (texture != null) 167 if (texture != null)
163 assetUuids[texture.TextureID] = AssetType.Texture; 168 assetUuids[texture.TextureID] = (sbyte)AssetType.Texture;
164 } 169 }
165 } 170 }
166 } 171 }
167 172
168 // If the prim is a sculpt then preserve this information too 173 // If the prim is a sculpt then preserve this information too
169 if (part.Shape.SculptTexture != UUID.Zero) 174 if (part.Shape.SculptTexture != UUID.Zero)
170 assetUuids[part.Shape.SculptTexture] = AssetType.Texture; 175 assetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
171 176
172 if (part.Shape.ProjectionTextureUUID != UUID.Zero) 177 if (part.Shape.ProjectionTextureUUID != UUID.Zero)
173 assetUuids[part.Shape.ProjectionTextureUUID] = AssetType.Texture; 178 assetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
174 179
175 if (part.CollisionSound != UUID.Zero) 180 if (part.CollisionSound != UUID.Zero)
176 assetUuids[part.CollisionSound] = AssetType.Sound; 181 assetUuids[part.CollisionSound] = (sbyte)AssetType.Sound;
177 182
178 if (part.ParticleSystem.Length > 0) 183 if (part.ParticleSystem.Length > 0)
179 { 184 {
@@ -181,7 +186,7 @@ namespace OpenSim.Region.Framework.Scenes
181 { 186 {
182 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0); 187 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
183 if (ps.Texture != UUID.Zero) 188 if (ps.Texture != UUID.Zero)
184 assetUuids[ps.Texture] = AssetType.Texture; 189 assetUuids[ps.Texture] = (sbyte)AssetType.Texture;
185 } 190 }
186 catch (Exception e) 191 catch (Exception e)
187 { 192 {
@@ -201,7 +206,7 @@ namespace OpenSim.Region.Framework.Scenes
201// tii.Name, tii.Type, part.Name, part.UUID); 206// tii.Name, tii.Type, part.Name, part.UUID);
202 207
203 if (!assetUuids.ContainsKey(tii.AssetID)) 208 if (!assetUuids.ContainsKey(tii.AssetID))
204 GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids); 209 GatherAssetUuids(tii.AssetID, (sbyte)tii.Type, assetUuids);
205 } 210 }
206 211
207 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed 212 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
@@ -210,7 +215,9 @@ namespace OpenSim.Region.Framework.Scenes
210 // Scene.EventManager is present. 215 // Scene.EventManager is present.
211// part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids); 216// part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
212 217
213 GatherMaterialsUuids(part, assetUuids); 218
219 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
220 GatherMaterialsUuids(part, assetUuids);
214 } 221 }
215 catch (Exception e) 222 catch (Exception e)
216 { 223 {
@@ -221,7 +228,7 @@ namespace OpenSim.Region.Framework.Scenes
221 } 228 }
222 } 229 }
223 } 230 }
224 231
225// /// <summary> 232// /// <summary>
226// /// The callback made when we request the asset for an object from the asset service. 233// /// The callback made when we request the asset for an object from the asset service.
227// /// </summary> 234// /// </summary>
@@ -237,10 +244,12 @@ namespace OpenSim.Region.Framework.Scenes
237 244
238 /// <summary> 245 /// <summary>
239 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps 246 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps
247 /// stored in legacy format in part.DynAttrs
240 /// </summary> 248 /// </summary>
241 /// <param name="part"></param> 249 /// <param name="part"></param>
242 /// <param name="assetUuids"></param> 250 /// <param name="assetUuids"></param>
243 public void GatherMaterialsUuids(SceneObjectPart part, IDictionary<UUID, AssetType> assetUuids) 251 //public void GatherMaterialsUuids(SceneObjectPart part, IDictionary<UUID, AssetType> assetUuids)
252 public void GatherMaterialsUuids(SceneObjectPart part, IDictionary<UUID, sbyte> assetUuids)
244 { 253 {
245 // scan thru the dynAttrs map of this part for any textures used as materials 254 // scan thru the dynAttrs map of this part for any textures used as materials
246 OSD osdMaterials = null; 255 OSD osdMaterials = null;
@@ -276,7 +285,7 @@ namespace OpenSim.Region.Framework.Scenes
276 UUID normalMapId = mat["NormMap"].AsUUID(); 285 UUID normalMapId = mat["NormMap"].AsUUID();
277 if (normalMapId != UUID.Zero) 286 if (normalMapId != UUID.Zero)
278 { 287 {
279 assetUuids[normalMapId] = AssetType.Texture; 288 assetUuids[normalMapId] = (sbyte)AssetType.Texture;
280 //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString()); 289 //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString());
281 } 290 }
282 } 291 }
@@ -285,7 +294,7 @@ namespace OpenSim.Region.Framework.Scenes
285 UUID specularMapId = mat["SpecMap"].AsUUID(); 294 UUID specularMapId = mat["SpecMap"].AsUUID();
286 if (specularMapId != UUID.Zero) 295 if (specularMapId != UUID.Zero)
287 { 296 {
288 assetUuids[specularMapId] = AssetType.Texture; 297 assetUuids[specularMapId] = (sbyte)AssetType.Texture;
289 //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString()); 298 //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString());
290 } 299 }
291 } 300 }
@@ -340,7 +349,7 @@ namespace OpenSim.Region.Framework.Scenes
340 /// </summary> 349 /// </summary>
341 /// <param name="scriptUuid"></param> 350 /// <param name="scriptUuid"></param>
342 /// <param name="assetUuids">Dictionary in which to record the references</param> 351 /// <param name="assetUuids">Dictionary in which to record the references</param>
343 private void GetTextEmbeddedAssetUuids(UUID embeddingAssetId, IDictionary<UUID, AssetType> assetUuids) 352 private void GetTextEmbeddedAssetUuids(UUID embeddingAssetId, IDictionary<UUID, sbyte> assetUuids)
344 { 353 {
345// m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); 354// m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
346 355
@@ -360,7 +369,7 @@ namespace OpenSim.Region.Framework.Scenes
360 369
361 // Embedded asset references (if not false positives) could be for many types of asset, so we will 370 // Embedded asset references (if not false positives) could be for many types of asset, so we will
362 // label these as unknown. 371 // label these as unknown.
363 assetUuids[uuid] = AssetType.Unknown; 372 assetUuids[uuid] = (sbyte)AssetType.Unknown;
364 } 373 }
365 } 374 }
366 } 375 }
@@ -370,7 +379,7 @@ namespace OpenSim.Region.Framework.Scenes
370 /// </summary> 379 /// </summary>
371 /// <param name="wearableAssetUuid"></param> 380 /// <param name="wearableAssetUuid"></param>
372 /// <param name="assetUuids">Dictionary in which to record the references</param> 381 /// <param name="assetUuids">Dictionary in which to record the references</param>
373 private void GetWearableAssetUuids(UUID wearableAssetUuid, IDictionary<UUID, AssetType> assetUuids) 382 private void GetWearableAssetUuids(UUID wearableAssetUuid, IDictionary<UUID, sbyte> assetUuids)
374 { 383 {
375 AssetBase assetBase = GetAsset(wearableAssetUuid); 384 AssetBase assetBase = GetAsset(wearableAssetUuid);
376 385
@@ -385,7 +394,7 @@ namespace OpenSim.Region.Framework.Scenes
385 394
386 foreach (UUID uuid in wearableAsset.Textures.Values) 395 foreach (UUID uuid in wearableAsset.Textures.Values)
387 { 396 {
388 assetUuids[uuid] = AssetType.Texture; 397 assetUuids[uuid] = (sbyte)AssetType.Texture;
389 } 398 }
390 } 399 }
391 } 400 }
@@ -397,7 +406,7 @@ namespace OpenSim.Region.Framework.Scenes
397 /// </summary> 406 /// </summary>
398 /// <param name="sceneObject"></param> 407 /// <param name="sceneObject"></param>
399 /// <param name="assetUuids"></param> 408 /// <param name="assetUuids"></param>
400 private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, AssetType> assetUuids) 409 private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids)
401 { 410 {
402 AssetBase objectAsset = GetAsset(sceneObjectUuid); 411 AssetBase objectAsset = GetAsset(sceneObjectUuid);
403 412
@@ -426,7 +435,7 @@ namespace OpenSim.Region.Framework.Scenes
426 /// </summary> 435 /// </summary>
427 /// <param name="gestureUuid"></param> 436 /// <param name="gestureUuid"></param>
428 /// <param name="assetUuids"></param> 437 /// <param name="assetUuids"></param>
429 private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, AssetType> assetUuids) 438 private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids)
430 { 439 {
431 AssetBase assetBase = GetAsset(gestureUuid); 440 AssetBase assetBase = GetAsset(gestureUuid);
432 if (null == assetBase) 441 if (null == assetBase)
@@ -460,9 +469,29 @@ namespace OpenSim.Region.Framework.Scenes
460 // If it can be parsed as a UUID, it is an asset ID 469 // If it can be parsed as a UUID, it is an asset ID
461 UUID uuid; 470 UUID uuid;
462 if (UUID.TryParse(id, out uuid)) 471 if (UUID.TryParse(id, out uuid))
463 assetUuids[uuid] = AssetType.Animation; 472 assetUuids[uuid] = (sbyte)AssetType.Animation;
464 } 473 }
465 } 474 }
475
476 /// <summary>
477 /// Get the asset uuid's referenced in a material.
478 /// </summary>
479 private void GetMaterialAssetUuids(UUID materialUuid, IDictionary<UUID, sbyte> assetUuids)
480 {
481 AssetBase assetBase = GetAsset(materialUuid);
482 if (null == assetBase)
483 return;
484
485 OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(assetBase.Data);
486
487 UUID normMap = mat["NormMap"].AsUUID();
488 if (normMap != UUID.Zero)
489 assetUuids[normMap] = (sbyte)AssetType.Texture;
490
491 UUID specMap = mat["SpecMap"].AsUUID();
492 if (specMap != UUID.Zero)
493 assetUuids[specMap] = (sbyte)AssetType.Texture;
494 }
466 } 495 }
467 496
468 public class HGUuidGatherer : UuidGatherer 497 public class HGUuidGatherer : UuidGatherer