aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs181
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs100
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs844
31 files changed, 895 insertions, 266 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 5d07a5f..1ebef90 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -98,6 +98,8 @@ namespace OpenSim.Region.Framework.Interfaces
98 void Cross(SceneObjectGroup sog, Vector3 position, bool silent); 98 void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
99 99
100 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); 100 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
101
102 bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition);
101 } 103 }
102 104
103 public interface IUserAgentVerificationModule 105 public interface IUserAgentVerificationModule
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0399a52..f7c12d6 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -6,7 +6,7 @@
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
@@ -360,19 +360,41 @@ namespace OpenSim.Region.Framework.Scenes
360 public uint MaintenanceRun { get; private set; } 360 public uint MaintenanceRun { get; private set; }
361 361
362 /// <summary> 362 /// <summary>
363 /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we 363 /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we
364 /// will sleep for the remaining period. 364 /// will sleep for the remaining period.
365 /// </summary> 365 /// </summary>
366 /// <remarks> 366 /// <remarks>
367 /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations 367 /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations
368 /// occur too quickly (viewer 1) or with even more slide (viewer 2). 368 /// occur too quickly (viewer 1) or with even more slide (viewer 2).
369 /// </remarks> 369 /// </remarks>
370 public float MinFrameTime { get; private set; } 370 public int MinFrameTicks
371 {
372 get { return m_minFrameTicks; }
373 private set
374 {
375 m_minFrameTicks = value;
376 MinFrameSeconds = (float)m_minFrameTicks / 1000;
377 }
378 }
379 private int m_minFrameTicks;
371 380
372 /// <summary> 381 /// <summary>
373 /// The minimum length of time in seconds that will be taken for a maintenance run. 382 /// The minimum length of time in seconds that will be taken for a scene frame.
374 /// </summary> 383 /// </summary>
375 public float MinMaintenanceTime { get; private set; } 384 /// <remarks>
385 /// Always derived from MinFrameTicks.
386 /// </remarks>
387 public float MinFrameSeconds { get; private set; }
388
389 /// <summary>
390 /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we
391 /// will sleep for the remaining period.
392 /// </summary>
393 /// <remarks>
394 /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations
395 /// occur too quickly (viewer 1) or with even more slide (viewer 2).
396 /// </remarks>
397 public int MinMaintenanceTicks { get; set; }
376 398
377 private int m_update_physics = 1; 399 private int m_update_physics = 1;
378 private int m_update_entitymovement = 1; 400 private int m_update_entitymovement = 1;
@@ -412,8 +434,16 @@ namespace OpenSim.Region.Framework.Scenes
412 /// asynchronously from the update loop. 434 /// asynchronously from the update loop.
413 /// </summary> 435 /// </summary>
414 private bool m_cleaningTemps = false; 436 private bool m_cleaningTemps = false;
437
438 /// <summary>
439 /// Used to control main scene thread looping time when not updating via timer.
440 /// </summary>
441 private ManualResetEvent m_updateWaitEvent = new ManualResetEvent(false);
415 442
416// private Object m_heartbeatLock = new Object(); 443 /// <summary>
444 /// Used to control maintenance thread runs.
445 /// </summary>
446 private ManualResetEvent m_maintenanceWaitEvent = new ManualResetEvent(false);
417 447
418 // TODO: Possibly stop other classes being able to manipulate this directly. 448 // TODO: Possibly stop other classes being able to manipulate this directly.
419 private SceneGraph m_sceneGraph; 449 private SceneGraph m_sceneGraph;
@@ -782,8 +812,8 @@ namespace OpenSim.Region.Framework.Scenes
782 : this(regInfo, physicsScene) 812 : this(regInfo, physicsScene)
783 { 813 {
784 m_config = config; 814 m_config = config;
785 MinFrameTime = 0.089f; 815 MinFrameTicks = 89;
786 MinMaintenanceTime = 1; 816 MinMaintenanceTicks = 1000;
787 SeeIntoRegion = true; 817 SeeIntoRegion = true;
788 818
789 Random random = new Random(); 819 Random random = new Random();
@@ -1005,7 +1035,9 @@ namespace OpenSim.Region.Framework.Scenes
1005 } 1035 }
1006 } 1036 }
1007 1037
1008 MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime); 1038 if (startupConfig.Contains("MinFrameTime"))
1039 MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000);
1040
1009 m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup); 1041 m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup);
1010 m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); 1042 m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations);
1011 m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement); 1043 m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement);
@@ -1396,7 +1428,7 @@ namespace OpenSim.Region.Framework.Scenes
1396 } 1428 }
1397 1429
1398 m_heartbeatThread 1430 m_heartbeatThread
1399 = Watchdog.StartThread( 1431 = WorkManager.StartThread(
1400 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); 1432 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false);
1401 1433
1402 StartScripts(); 1434 StartScripts();
@@ -1437,7 +1469,7 @@ namespace OpenSim.Region.Framework.Scenes
1437 // alarms for scenes with many objects. 1469 // alarms for scenes with many objects.
1438 Update(1); 1470 Update(1);
1439 1471
1440 Watchdog.StartThread( 1472 WorkManager.StartThread(
1441 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); 1473 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
1442 1474
1443 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; 1475 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
@@ -1445,13 +1477,14 @@ namespace OpenSim.Region.Framework.Scenes
1445 1477
1446 if (UpdateOnTimer) 1478 if (UpdateOnTimer)
1447 { 1479 {
1448 m_sceneUpdateTimer = new Timer(MinFrameTime * 1000); 1480 m_sceneUpdateTimer = new Timer(MinFrameTicks);
1449 m_sceneUpdateTimer.AutoReset = true; 1481 m_sceneUpdateTimer.AutoReset = true;
1450 m_sceneUpdateTimer.Elapsed += Update; 1482 m_sceneUpdateTimer.Elapsed += Update;
1451 m_sceneUpdateTimer.Start(); 1483 m_sceneUpdateTimer.Start();
1452 } 1484 }
1453 else 1485 else
1454 { 1486 {
1487 Thread.CurrentThread.Priority = ThreadPriority.Highest;
1455 Update(-1); 1488 Update(-1);
1456 Watchdog.RemoveThread(); 1489 Watchdog.RemoveThread();
1457 m_isRunning = false; 1490 m_isRunning = false;
@@ -1535,10 +1568,10 @@ namespace OpenSim.Region.Framework.Scenes
1535 tmpMS = Util.EnvironmentTickCount(); 1568 tmpMS = Util.EnvironmentTickCount();
1536 m_cleaningTemps = true; 1569 m_cleaningTemps = true;
1537 1570
1538 Watchdog.RunInThread( 1571 WorkManager.RunInThread(
1539 delegate { CleanTempObjects(); m_cleaningTemps = false; }, 1572 delegate { CleanTempObjects(); m_cleaningTemps = false; },
1540 string.Format("CleanTempObjects ({0})", Name), 1573 null,
1541 null); 1574 string.Format("CleanTempObjects ({0})", Name));
1542 1575
1543 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS); 1576 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS);
1544 } 1577 }
@@ -1548,19 +1581,19 @@ namespace OpenSim.Region.Framework.Scenes
1548 previousMaintenanceTick = m_lastMaintenanceTick; 1581 previousMaintenanceTick = m_lastMaintenanceTick;
1549 m_lastMaintenanceTick = Util.EnvironmentTickCount(); 1582 m_lastMaintenanceTick = Util.EnvironmentTickCount();
1550 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); 1583 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc);
1551 runtc = (int)(MinMaintenanceTime * 1000) - runtc; 1584 runtc = MinMaintenanceTicks - runtc;
1552 1585
1553 if (runtc > 0) 1586 if (runtc > 0)
1554 Thread.Sleep(runtc); 1587 m_maintenanceWaitEvent.WaitOne(runtc);
1555 1588
1556 // Optionally warn if a frame takes double the amount of time that it should. 1589 // Optionally warn if a frame takes double the amount of time that it should.
1557 if (DebugUpdates 1590 if (DebugUpdates
1558 && Util.EnvironmentTickCountSubtract( 1591 && Util.EnvironmentTickCountSubtract(
1559 m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2)) 1592 m_lastMaintenanceTick, previousMaintenanceTick) > MinMaintenanceTicks * 2)
1560 m_log.WarnFormat( 1593 m_log.WarnFormat(
1561 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", 1594 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}",
1562 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), 1595 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick),
1563 MinMaintenanceTime * 1000, 1596 MinMaintenanceTicks,
1564 RegionInfo.RegionName); 1597 RegionInfo.RegionName);
1565 } 1598 }
1566 } 1599 }
@@ -1612,7 +1645,7 @@ namespace OpenSim.Region.Framework.Scenes
1612 if (Frame % m_update_physics == 0) 1645 if (Frame % m_update_physics == 0)
1613 { 1646 {
1614 if (PhysicsEnabled) 1647 if (PhysicsEnabled)
1615 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime); 1648 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds);
1616 1649
1617 if (SynchronizeScene != null) 1650 if (SynchronizeScene != null)
1618 SynchronizeScene(this); 1651 SynchronizeScene(this);
@@ -1710,18 +1743,16 @@ namespace OpenSim.Region.Framework.Scenes
1710 { 1743 {
1711 Watchdog.UpdateThread(); 1744 Watchdog.UpdateThread();
1712 1745
1713 tmpMS = Util.EnvironmentTickCountSubtract(Util.EnvironmentTickCount(), m_lastFrameTick); 1746 spareMS = MinFrameTicks - Util.EnvironmentTickCountSubtract(m_lastFrameTick);
1714 tmpMS = (int)(MinFrameTime * 1000) - tmpMS;
1715 1747
1716 if (tmpMS > 0) 1748 if (spareMS > 0)
1717 { 1749 m_updateWaitEvent.WaitOne(spareMS);
1718 spareMS = tmpMS; 1750 else
1719 Thread.Sleep(tmpMS); 1751 spareMS = 0;
1720 }
1721 } 1752 }
1722 else 1753 else
1723 { 1754 {
1724 spareMS = Math.Max(0, (int)(MinFrameTime * 1000) - physicsMS2 - agentMS - physicsMS -otherMS); 1755 spareMS = Math.Max(0, MinFrameTicks - physicsMS2 - agentMS - physicsMS - otherMS);
1725 } 1756 }
1726 1757
1727 previousFrameTick = m_lastFrameTick; 1758 previousFrameTick = m_lastFrameTick;
@@ -1744,11 +1775,11 @@ namespace OpenSim.Region.Framework.Scenes
1744 // Optionally warn if a frame takes double the amount of time that it should. 1775 // Optionally warn if a frame takes double the amount of time that it should.
1745 if (DebugUpdates 1776 if (DebugUpdates
1746 && Util.EnvironmentTickCountSubtract( 1777 && Util.EnvironmentTickCountSubtract(
1747 m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2)) 1778 m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2)
1748 m_log.WarnFormat( 1779 m_log.WarnFormat(
1749 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", 1780 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1750 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), 1781 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
1751 MinFrameTime * 1000, 1782 MinFrameTicks,
1752 RegionInfo.RegionName); 1783 RegionInfo.RegionName);
1753 } 1784 }
1754 1785
@@ -1812,7 +1843,7 @@ namespace OpenSim.Region.Framework.Scenes
1812 if (!m_backingup) 1843 if (!m_backingup)
1813 { 1844 {
1814 m_backingup = true; 1845 m_backingup = true;
1815 Watchdog.RunInThread(o => Backup(false), string.Format("BackupWaitCallback ({0})", Name), null); 1846 WorkManager.RunInThread(o => Backup(false), null, string.Format("BackupWaitCallback ({0})", Name));
1816 } 1847 }
1817 } 1848 }
1818 1849
@@ -2592,48 +2623,8 @@ namespace OpenSim.Region.Framework.Scenes
2592 return false; 2623 return false;
2593 } 2624 }
2594 2625
2595 // If the user is banned, we won't let any of their objects 2626 if (!EntityTransferModule.HandleIncomingSceneObject(newObject, newPosition))
2596 // enter. Period. 2627 return false;
2597 //
2598 if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID))
2599 {
2600 m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID);
2601 return false;
2602 }
2603
2604 if (newPosition != Vector3.Zero)
2605 newObject.RootPart.GroupPosition = newPosition;
2606
2607 if (!AddSceneObject(newObject))
2608 {
2609 m_log.DebugFormat(
2610 "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName);
2611 return false;
2612 }
2613
2614 if (!newObject.IsAttachment)
2615 {
2616 // FIXME: It would be better to never add the scene object at all rather than add it and then delete
2617 // it
2618 if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition))
2619 {
2620 // Deny non attachments based on parcel settings
2621 //
2622 m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings");
2623
2624 DeleteSceneObject(newObject, false);
2625
2626 return false;
2627 }
2628
2629 // For attachments, we need to wait until the agent is root
2630 // before we restart the scripts, or else some functions won't work.
2631 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
2632 newObject.ResumeScripts();
2633
2634 if (newObject.RootPart.KeyframeMotion != null)
2635 newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
2636 }
2637 2628
2638 // Do this as late as possible so that listeners have full access to the incoming object 2629 // Do this as late as possible so that listeners have full access to the incoming object
2639 EventManager.TriggerOnIncomingSceneObject(newObject); 2630 EventManager.TriggerOnIncomingSceneObject(newObject);
@@ -2702,16 +2693,6 @@ namespace OpenSim.Region.Framework.Scenes
2702 return true; 2693 return true;
2703 } 2694 }
2704 2695
2705 private int GetStateSource(SceneObjectGroup sog)
2706 {
2707 ScenePresence sp = GetScenePresence(sog.OwnerID);
2708
2709 if (sp != null)
2710 return sp.GetStateSource();
2711
2712 return 2; // StateSource.PrimCrossing
2713 }
2714
2715 #endregion 2696 #endregion
2716 2697
2717 #region Add/Remove Avatar Methods 2698 #region Add/Remove Avatar Methods
@@ -2758,29 +2739,41 @@ namespace OpenSim.Region.Framework.Scenes
2758 m_log.DebugFormat( 2739 m_log.DebugFormat(
2759 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 2740 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2760 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); 2741 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2761 2742
2743 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2744
2745 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2746 // client is for a root or child agent.
2747 // We must also set this before adding the client to the client manager so that an exception later on
2748 // does not leave a client manager entry without the scene agent set, which will cause other code
2749 // to fail since any entry in the client manager should have a ScenePresence
2750 //
2751 // XXX: This may be better set for a new client before that client is added to the client manager.
2752 // But need to know what happens in the case where a ScenePresence is already present (and if this
2753 // actually occurs).
2754 client.SceneAgent = sp;
2755
2762 m_clientManager.Add(client); 2756 m_clientManager.Add(client);
2763 SubscribeToClientEvents(client); 2757 SubscribeToClientEvents(client);
2764
2765 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2766 m_eventManager.TriggerOnNewPresence(sp); 2758 m_eventManager.TriggerOnNewPresence(sp);
2767 2759
2768 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; 2760 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2769 } 2761 }
2770 else 2762 else
2771 { 2763 {
2764 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2765 // client is for a root or child agent.
2766 // XXX: This may be better set for a new client before that client is added to the client manager.
2767 // But need to know what happens in the case where a ScenePresence is already present (and if this
2768 // actually occurs).
2769 client.SceneAgent = sp;
2770
2772 m_log.WarnFormat( 2771 m_log.WarnFormat(
2773 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 2772 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2774 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2773 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2774
2775 reallyNew = false; 2775 reallyNew = false;
2776 } 2776 }
2777
2778 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2779 // client is for a root or child agent.
2780 // XXX: This may be better set for a new client before that client is added to the client manager.
2781 // But need to know what happens in the case where a ScenePresence is already present (and if this
2782 // actually occurs).
2783 client.SceneAgent = sp;
2784 2777
2785 // This is currently also being done earlier in NewUserConnection for real users to see if this 2778 // This is currently also being done earlier in NewUserConnection for real users to see if this
2786 // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other 2779 // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index bfa3b9a..9db5309 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -226,7 +226,10 @@ namespace OpenSim.Region.Framework.Scenes
226 // We must take a copy here since handle is acts like a reference when used in an iterator. 226 // We must take a copy here since handle is acts like a reference when used in an iterator.
227 // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region. 227 // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region.
228 ulong handleCopy = handle; 228 ulong handleCopy = handle;
229 Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy, auth_code); }); 229 Util.FireAndForget(
230 o => SendCloseChildAgent(agentID, handleCopy, auth_code),
231 null,
232 "SceneCommunicationService.SendCloseChildAgentConnections");
230 } 233 }
231 } 234 }
232 235
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 87063c6..5a35aff 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1228,10 +1228,11 @@ namespace OpenSim.Region.Framework.Scenes
1228 // viewers without (e.g. v1 viewers) will not, so we still need to make this call. 1228 // viewers without (e.g. v1 viewers) will not, so we still need to make this call.
1229 if (Scene.AttachmentsModule != null) 1229 if (Scene.AttachmentsModule != null)
1230 { 1230 {
1231 Util.FireAndForget(o => 1231 WorkManager.RunJob(
1232 { 1232 "RezAttachments",
1233 Scene.AttachmentsModule.RezAttachments(this); 1233 o => Scene.AttachmentsModule.RezAttachments(this),
1234 }); 1234 null,
1235 string.Format("Rez attachments for {0} in {1}", Name, Scene.Name));
1235 } 1236 }
1236 } 1237 }
1237 else 1238 else
@@ -1241,11 +1242,6 @@ namespace OpenSim.Region.Framework.Scenes
1241 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1242 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1242 // not transporting the required data. 1243 // not transporting the required data.
1243 // 1244 //
1244 // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
1245 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1246 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1247 // not transporting the required data.
1248 //
1249 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of 1245 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1250 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here 1246 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1251 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. 1247 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
@@ -1254,23 +1250,16 @@ namespace OpenSim.Region.Framework.Scenes
1254 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing 1250 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1255 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the 1251 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1256 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. 1252 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1257 //
1258 // One cannot simply iterate over attachments in a fire and forget thread because this would no longer
1259 // be locked, allowing race conditions if other code changes the attachments list.
1260 List<SceneObjectGroup> attachments = GetAttachments(); 1253 List<SceneObjectGroup> attachments = GetAttachments();
1261 1254
1262 if (attachments.Count > 0) 1255 if (attachments.Count > 0)
1263 { 1256 {
1264 m_log.DebugFormat( 1257 WorkManager.RunJob(
1265 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); 1258 "StartAttachmentScripts",
1266 1259 o => RestartAttachmentScripts(attachments),
1267 // Resume scripts 1260 null,
1268 foreach (SceneObjectGroup sog in attachments) 1261 string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name),
1269 { 1262 true);
1270 sog.ScheduleGroupForFullUpdate();
1271 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1272 sog.ResumeScripts();
1273 }
1274 } 1263 }
1275 } 1264 }
1276 1265
@@ -1294,6 +1283,20 @@ namespace OpenSim.Region.Framework.Scenes
1294 return true; 1283 return true;
1295 } 1284 }
1296 1285
1286 private void RestartAttachmentScripts(List<SceneObjectGroup> attachments)
1287 {
1288 m_log.DebugFormat(
1289 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1290
1291 // Resume scripts
1292 foreach (SceneObjectGroup sog in attachments)
1293 {
1294 sog.ScheduleGroupForFullUpdate();
1295 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1296 sog.ResumeScripts();
1297 }
1298 }
1299
1297 private static bool IsRealLogin(TeleportFlags teleportFlags) 1300 private static bool IsRealLogin(TeleportFlags teleportFlags)
1298 { 1301 {
1299 return ((teleportFlags & TeleportFlags.ViaLogin) != 0) && ((teleportFlags & TeleportFlags.ViaHGLogin) == 0); 1302 return ((teleportFlags & TeleportFlags.ViaLogin) != 0) && ((teleportFlags & TeleportFlags.ViaHGLogin) == 0);
@@ -1326,7 +1329,7 @@ namespace OpenSim.Region.Framework.Scenes
1326 1329
1327 UseFakeGroupTitle = false; 1330 UseFakeGroupTitle = false;
1328 SendAvatarDataToAllClients(false); 1331 SendAvatarDataToAllClients(false);
1329 }); 1332 }, null, "Scenepresence.ForceViewersUpdateName");
1330 } 1333 }
1331 1334
1332 public int GetStateSource() 1335 public int GetStateSource()
@@ -1809,14 +1812,15 @@ namespace OpenSim.Region.Framework.Scenes
1809 1812
1810 } 1813 }
1811 1814
1812 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1815 // XXX: If we force an update after activity has completed, then multiple attachments do appear correctly on a destination region
1813 // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. 1816 // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work.
1814 // This may be due to viewer code or it may be something we're not doing properly simulator side. 1817 // This may be due to viewer code or it may be something we're not doing properly simulator side.
1815 lock (m_attachments) 1818 WorkManager.RunJob(
1816 { 1819 "ScheduleAttachmentsForFullUpdate",
1817 foreach (SceneObjectGroup sog in m_attachments) 1820 o => ScheduleAttachmentsForFullUpdate(),
1818 sog.ScheduleGroupForFullUpdate(); 1821 null,
1819 } 1822 string.Format("Schedule attachments for full update for {0} in {1}", Name, Scene.Name),
1823 true);
1820 1824
1821 // m_log.DebugFormat( 1825 // m_log.DebugFormat(
1822 // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1826 // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
@@ -1828,6 +1832,15 @@ namespace OpenSim.Region.Framework.Scenes
1828 } 1832 }
1829 } 1833 }
1830 1834
1835 private void ScheduleAttachmentsForFullUpdate()
1836 {
1837 lock (m_attachments)
1838 {
1839 foreach (SceneObjectGroup sog in m_attachments)
1840 sog.ScheduleGroupForFullUpdate();
1841 }
1842 }
1843
1831 /// <summary> 1844 /// <summary>
1832 /// Callback for the Camera view block check. Gets called with the results of the camera view block test 1845 /// Callback for the Camera view block check. Gets called with the results of the camera view block test
1833 /// hitYN is true when there's something in the way. 1846 /// hitYN is true when there's something in the way.
@@ -3362,7 +3375,7 @@ namespace OpenSim.Region.Framework.Scenes
3362 SentInitialDataToClient = true; 3375 SentInitialDataToClient = true;
3363 3376
3364 // Send all scene object to the new client 3377 // Send all scene object to the new client
3365 Watchdog.RunInThread(delegate 3378 WorkManager.RunJob("SendInitialDataToClient", delegate
3366 { 3379 {
3367// m_log.DebugFormat( 3380// m_log.DebugFormat(
3368// "[SCENE PRESENCE]: Sending initial data to {0} agent {1} in {2}, tp flags {3}", 3381// "[SCENE PRESENCE]: Sending initial data to {0} agent {1} in {2}, tp flags {3}",
@@ -3380,7 +3393,7 @@ namespace OpenSim.Region.Framework.Scenes
3380 if (e != null && e is SceneObjectGroup) 3393 if (e != null && e is SceneObjectGroup)
3381 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); 3394 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
3382 } 3395 }
3383 }, string.Format("SendInitialDataToClient ({0} in {1})", Name, Scene.Name), null); 3396 }, null, string.Format("SendInitialDataToClient ({0} in {1})", Name, Scene.Name), false, true);
3384 } 3397 }
3385 3398
3386 /// <summary> 3399 /// <summary>
@@ -3617,7 +3630,8 @@ namespace OpenSim.Region.Framework.Scenes
3617 agentpos.CopyFrom(cadu, ControllingClient.SessionId); 3630 agentpos.CopyFrom(cadu, ControllingClient.SessionId);
3618 3631
3619 // Let's get this out of the update loop 3632 // Let's get this out of the update loop
3620 Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); 3633 Util.FireAndForget(
3634 o => m_scene.SendOutChildAgentUpdates(agentpos, this), null, "ScenePresence.SendOutChildAgentUpdates");
3621 } 3635 }
3622 } 3636 }
3623 3637
@@ -4035,9 +4049,23 @@ namespace OpenSim.Region.Framework.Scenes
4035 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); 4049 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
4036 4050
4037 if (Scene.AttachmentsModule != null) 4051 if (Scene.AttachmentsModule != null)
4038 Scene.AttachmentsModule.CopyAttachments(cAgent, this); 4052 {
4039 4053 // If the JobEngine is running we can schedule this job now and continue rather than waiting for all
4040 // This must occur after attachments are copied, as it releases the CompleteMovement() calling thread 4054 // attachments to copy, which might take a long time in the Hypergrid case as the entire inventory
4055 // graph is inspected for each attachments and assets possibly fetched.
4056 //
4057 // We don't need to worry about a race condition as the job to later start the scripts is also
4058 // JobEngine scheduled and so will always occur after this task.
4059 // XXX: This will not be true if JobEngine ever gets more than one thread.
4060 WorkManager.RunJob(
4061 "CopyAttachments",
4062 o => Scene.AttachmentsModule.CopyAttachments(cAgent, this),
4063 null,
4064 string.Format("Copy attachments for {0} entering {1}", Name, Scene.Name),
4065 true);
4066 }
4067
4068 // This must occur after attachments are copied or scheduled to be copied, as it releases the CompleteMovement() calling thread
4041 // originating from the client completing a teleport. Otherwise, CompleteMovement() code to restart 4069 // originating from the client completing a teleport. Otherwise, CompleteMovement() code to restart
4042 // script attachments can outrace this thread. 4070 // script attachments can outrace this thread.
4043 lock (m_originRegionIDAccessLock) 4071 lock (m_originRegionIDAccessLock)
@@ -4471,7 +4499,7 @@ namespace OpenSim.Region.Framework.Scenes
4471 } 4499 }
4472 } 4500 }
4473 } 4501 }
4474 }); 4502 }, null, "ScenePresence.SendScriptEventToAttachments");
4475 } 4503 }
4476 4504
4477 /// <summary> 4505 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 95f9caf..8f1e345 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -224,7 +224,7 @@ namespace OpenSim.Region.Framework.Scenes
224 public SimStatsReporter(Scene scene) 224 public SimStatsReporter(Scene scene)
225 { 225 {
226 m_scene = scene; 226 m_scene = scene;
227 m_reportedFpsCorrectionFactor = scene.MinFrameTime * m_nominalReportedFps; 227 m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps;
228 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000); 228 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
229 ReportingRegion = scene.RegionInfo; 229 ReportingRegion = scene.RegionInfo;
230 230
@@ -239,7 +239,7 @@ namespace OpenSim.Region.Framework.Scenes
239 239
240 /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit 240 /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
241 /// longer than ideal (which in itself is a concern). 241 /// longer than ideal (which in itself is a concern).
242 SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.MinFrameTime * 1000 * 1.2); 242 SlowFramesStatReportThreshold = (int)Math.Ceiling(scene.MinFrameTicks * 1.2);
243 243
244 SlowFramesStat 244 SlowFramesStat
245 = new Stat( 245 = new Stat(
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
index 575a081..b6b3344 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
@@ -35,7 +35,6 @@ using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35using OpenSim.Framework.Communications;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Tests.Common; 37using OpenSim.Tests.Common;
38using OpenSim.Tests.Common.Mock;
39 38
40namespace OpenSim.Region.Framework.Scenes.Tests 39namespace OpenSim.Region.Framework.Scenes.Tests
41{ 40{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs
index 2d831fa..6118004 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs
@@ -36,7 +36,6 @@ using OpenSim.Framework.Communications;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
38using OpenSim.Tests.Common; 38using OpenSim.Tests.Common;
39using OpenSim.Tests.Common.Mock;
40 39
41namespace OpenSim.Region.Framework.Scenes.Tests 40namespace OpenSim.Region.Framework.Scenes.Tests
42{ 41{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
index a07d64c..bdf0700 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Framework.Communications;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41 40
42namespace OpenSim.Region.Framework.Scenes.Tests 41namespace OpenSim.Region.Framework.Scenes.Tests
43{ 42{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs
index 969f73d..5635c20 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
37using OpenSim.Region.CoreModules.World.Land; 37using OpenSim.Region.CoreModules.World.Land;
38using OpenSim.Region.OptionalModules; 38using OpenSim.Region.OptionalModules;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41 40
42namespace OpenSim.Region.Framework.Scenes.Tests 41namespace OpenSim.Region.Framework.Scenes.Tests
43{ 42{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
index 5b5fb92..558ba2c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
@@ -40,7 +40,6 @@ using OpenSim.Region.CoreModules.World.Permissions;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
42using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock;
44 43
45namespace OpenSim.Region.Framework.Scenes.Tests 44namespace OpenSim.Region.Framework.Scenes.Tests
46{ 45{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index 0aefcbd..c2e0ae3 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -34,7 +34,6 @@ using OpenSim.Framework;
34using OpenSim.Framework.Communications; 34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38using log4net; 37using log4net;
39 38
40namespace OpenSim.Region.Framework.Scenes.Tests 39namespace OpenSim.Region.Framework.Scenes.Tests
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
index c264433..11e9084 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
@@ -33,7 +33,6 @@ using OpenSim.Framework;
33using OpenSim.Framework.Communications; 33using OpenSim.Framework.Communications;
34using OpenSim.Region.Framework.Scenes; 34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Tests.Common; 35using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock;
37 36
38namespace OpenSim.Region.Framework.Scenes.Tests 37namespace OpenSim.Region.Framework.Scenes.Tests
39{ 38{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
index a58e735..fdbe7ae 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
@@ -35,7 +35,6 @@ using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Tests.Common; 37using OpenSim.Tests.Common;
38using OpenSim.Tests.Common.Mock;
39 38
40namespace OpenSim.Region.Framework.Scenes.Tests 39namespace OpenSim.Region.Framework.Scenes.Tests
41{ 40{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
index abaa1d1..974529a 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
@@ -34,7 +34,6 @@ using OpenSim.Framework;
34using OpenSim.Framework.Communications; 34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38 37
39namespace OpenSim.Region.Framework.Scenes.Tests 38namespace OpenSim.Region.Framework.Scenes.Tests
40{ 39{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
index 6985766..5ba754c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
@@ -34,7 +34,6 @@ using OpenSim.Framework;
34using OpenSim.Framework.Communications; 34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38 37
39namespace OpenSim.Region.Framework.Scenes.Tests 38namespace OpenSim.Region.Framework.Scenes.Tests
40{ 39{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs
index 4883ae7..cdebe25 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs
@@ -33,7 +33,6 @@ using OpenSim.Framework;
33using OpenSim.Framework.Communications; 33using OpenSim.Framework.Communications;
34using OpenSim.Region.Framework.Scenes; 34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Tests.Common; 35using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock;
37 36
38namespace OpenSim.Region.Framework.Scenes.Tests 37namespace OpenSim.Region.Framework.Scenes.Tests
39{ 38{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
index 2b79271..fd49c88 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
@@ -39,7 +39,6 @@ using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; 40using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
41using OpenSim.Tests.Common; 41using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock;
43 42
44namespace OpenSim.Region.Framework.Scenes.Tests 43namespace OpenSim.Region.Framework.Scenes.Tests
45{ 44{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index e2ed9c8..06e6423 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -44,7 +44,6 @@ using OpenSim.Region.CoreModules.Framework.EntityTransfer;
44using OpenSim.Region.CoreModules.World.Serialiser; 44using OpenSim.Region.CoreModules.World.Serialiser;
45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
46using OpenSim.Tests.Common; 46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48using GridRegion = OpenSim.Services.Interfaces.GridRegion; 47using GridRegion = OpenSim.Services.Interfaces.GridRegion;
49 48
50namespace OpenSim.Region.Framework.Scenes.Tests 49namespace OpenSim.Region.Framework.Scenes.Tests
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
index 1cd8ae9..42cfa1b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.World.Serialiser;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Region.Physics.Manager; 44using OpenSim.Region.Physics.Manager;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.Framework.Scenes.Tests 47namespace OpenSim.Region.Framework.Scenes.Tests
49{ 48{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
index d80afd3..c6e3b8b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Framework.Communications;
37using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41 40
42namespace OpenSim.Region.Framework.Scenes.Tests 41namespace OpenSim.Region.Framework.Scenes.Tests
43{ 42{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
index 4fdfc74..cca30db 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
@@ -47,7 +47,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
47using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Framework.Interfaces; 48using OpenSim.Region.Framework.Interfaces;
49using OpenSim.Tests.Common; 49using OpenSim.Tests.Common;
50using OpenSim.Tests.Common.Mock;
51using GridRegion = OpenSim.Services.Interfaces.GridRegion; 50using GridRegion = OpenSim.Services.Interfaces.GridRegion;
52 51
53namespace OpenSim.Region.Framework.Scenes.Tests 52namespace OpenSim.Region.Framework.Scenes.Tests
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
index cf211a1..e14da8b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
@@ -40,7 +40,6 @@ using OpenSim.Region.CoreModules.Framework.EntityTransfer;
40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
41using OpenSim.Region.CoreModules.World.Permissions; 41using OpenSim.Region.CoreModules.World.Permissions;
42using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock;
44 43
45namespace OpenSim.Region.Framework.Scenes.Tests 44namespace OpenSim.Region.Framework.Scenes.Tests
46{ 45{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
index 2b84364..b775178 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Framework.Servers;
37using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 38using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41using System.Threading; 40using System.Threading;
42 41
43namespace OpenSim.Region.Framework.Scenes.Tests 42namespace OpenSim.Region.Framework.Scenes.Tests
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index 8c25dbc..da93d44 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.Framework.EntityTransfer;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Region.CoreModules.World.Permissions; 44using OpenSim.Region.CoreModules.World.Permissions;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.Framework.Scenes.Tests 47namespace OpenSim.Region.Framework.Scenes.Tests
49{ 48{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs
index 1667002..2d36214 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs
@@ -34,7 +34,6 @@ using OpenSim.Framework;
34using OpenSim.Framework.Communications; 34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38 37
39namespace OpenSim.Region.Framework.Scenes.Tests 38namespace OpenSim.Region.Framework.Scenes.Tests
40{ 39{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs
index 9a97acc..584a03c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs
@@ -32,7 +32,6 @@ using OpenSim.Region.Framework.Scenes;
32using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Services.Interfaces; 33using OpenSim.Services.Interfaces;
34using OpenSim.Tests.Common; 34using OpenSim.Tests.Common;
35using OpenSim.Tests.Common.Mock;
36 35
37namespace OpenSim.Region.Framework.Scenes.Tests 36namespace OpenSim.Region.Framework.Scenes.Tests
38{ 37{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 52e4362..33ef83b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -42,7 +42,6 @@ using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.CoreModules.World.Serialiser; 42using OpenSim.Region.CoreModules.World.Serialiser;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Tests.Common; 44using OpenSim.Tests.Common;
45using OpenSim.Tests.Common.Mock;
46 45
47namespace OpenSim.Region.Framework.Scenes.Tests 46namespace OpenSim.Region.Framework.Scenes.Tests
48{ 47{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
index f809267..9655d19 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.CoreModules.World.Serialiser;
45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
46using OpenSim.Services.Interfaces; 46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49 48
50namespace OpenSim.Region.Framework.Tests 49namespace OpenSim.Region.Framework.Tests
51{ 50{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index 0736278..edc0a52 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.CoreModules.World.Serialiser;
45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
46using OpenSim.Services.Interfaces; 46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49 48
50namespace OpenSim.Region.Framework.Tests 49namespace OpenSim.Region.Framework.Tests
51{ 50{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
index 1e59e3f..a12b170 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
@@ -33,7 +33,6 @@ using OpenSim.Framework;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34using OpenSim.Services.Interfaces; 34using OpenSim.Services.Interfaces;
35using OpenSim.Tests.Common; 35using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock;
37 36
38namespace OpenSim.Region.Framework.Scenes.Tests 37namespace OpenSim.Region.Framework.Scenes.Tests
39{ 38{
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index d07cc6a..2450cdb 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -57,22 +57,83 @@ namespace OpenSim.Region.Framework.Scenes
57 57
58 protected IAssetService m_assetService; 58 protected IAssetService m_assetService;
59 59
60// /// <summary> 60 // /// <summary>
61// /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate 61 // /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate
62// /// asset was found by the asset service. 62 // /// asset was found by the asset service.
63// /// </summary> 63 // /// </summary>
64// private AssetBase m_requestedObjectAsset; 64 // private AssetBase m_requestedObjectAsset;
65// 65 //
66// /// <summary> 66 // /// <summary>
67// /// Signal whether we are currently waiting for the asset service to deliver an asset. 67 // /// Signal whether we are currently waiting for the asset service to deliver an asset.
68// /// </summary> 68 // /// </summary>
69// private bool m_waitingForObjectAsset; 69 // private bool m_waitingForObjectAsset;
70 70
71 public UuidGatherer(IAssetService assetService) 71 public UuidGatherer(IAssetService assetService)
72 { 72 {
73 m_assetService = assetService; 73 m_assetService = assetService;
74 } 74 }
75 75
76 /// <summary>
77 /// Gather all the asset uuids associated with the asset referenced by a given uuid
78 /// </summary>
79 /// <remarks>
80 /// 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 /// within this object).
83 /// This method assumes that the asset type associated with this asset in persistent storage is correct (which
84 /// should always be the case). So with this method we always need to retrieve asset data even if the asset
85 /// is of a type which is known not to reference any other assets
86 /// </remarks>
87 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
88 /// <param name="assetUuids">The assets gathered</param>
89 public void GatherAssetUuids(UUID assetUuid, IDictionary<UUID, sbyte> assetUuids)
90 {
91 // avoid infinite loops
92 if (assetUuids.ContainsKey(assetUuid))
93 return;
94
95 try
96 {
97 AssetBase assetBase = GetAsset(assetUuid);
98
99 if (null != assetBase)
100 {
101 sbyte assetType = assetBase.Type;
102 assetUuids[assetUuid] = assetType;
103
104 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
105 {
106 GetWearableAssetUuids(assetBase, assetUuids);
107 }
108 else if ((sbyte)AssetType.Gesture == assetType)
109 {
110 GetGestureAssetUuids(assetBase, assetUuids);
111 }
112 else if ((sbyte)AssetType.Notecard == assetType)
113 {
114 GetTextEmbeddedAssetUuids(assetBase, assetUuids);
115 }
116 else if ((sbyte)AssetType.LSLText == assetType)
117 {
118 GetTextEmbeddedAssetUuids(assetBase, assetUuids);
119 }
120 else if ((sbyte)OpenSimAssetType.Material == assetType)
121 {
122 GetMaterialAssetUuids(assetBase, assetUuids);
123 }
124 else if ((sbyte)AssetType.Object == assetType)
125 {
126 GetSceneObjectAssetUuids(assetBase, assetUuids);
127 }
128 }
129 }
130 catch (Exception)
131 {
132 m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid);
133 throw;
134 }
135 }
136
76 /// <summary> 137 /// <summary>
77 /// Gather all the asset uuids associated with the asset referenced by a given uuid 138 /// Gather all the asset uuids associated with the asset referenced by a given uuid
78 /// </summary> 139 /// </summary>
@@ -93,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes
93 try 154 try
94 { 155 {
95 assetUuids[assetUuid] = assetType; 156 assetUuids[assetUuid] = assetType;
96 157
97 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) 158 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
98 { 159 {
99 GetWearableAssetUuids(assetUuid, assetUuids); 160 GetWearableAssetUuids(assetUuid, assetUuids);
@@ -143,16 +204,16 @@ namespace OpenSim.Region.Framework.Scenes
143 /// </param> 204 /// </param>
144 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, sbyte> assetUuids) 205 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, sbyte> assetUuids)
145 { 206 {
146// m_log.DebugFormat( 207 // m_log.DebugFormat(
147// "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); 208 // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
148 209
149 SceneObjectPart[] parts = sceneObject.Parts; 210 SceneObjectPart[] parts = sceneObject.Parts;
150 for (int i = 0; i < parts.Length; i++) 211 for (int i = 0; i < parts.Length; i++)
151 { 212 {
152 SceneObjectPart part = parts[i]; 213 SceneObjectPart part = parts[i];
153 214
154// m_log.DebugFormat( 215 // m_log.DebugFormat(
155// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); 216 // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
156 217
157 try 218 try
158 { 219 {
@@ -173,7 +234,7 @@ namespace OpenSim.Region.Framework.Scenes
173 } 234 }
174 } 235 }
175 } 236 }
176 237
177 // If the prim is a sculpt then preserve this information too 238 // If the prim is a sculpt then preserve this information too
178 if (part.Shape.SculptTexture != UUID.Zero) 239 if (part.Shape.SculptTexture != UUID.Zero)
179 assetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture; 240 assetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
@@ -201,13 +262,13 @@ namespace OpenSim.Region.Framework.Scenes
201 } 262 }
202 263
203 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 264 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
204 265
205 // Now analyze this prim's inventory items to preserve all the uuids that they reference 266 // Now analyze this prim's inventory items to preserve all the uuids that they reference
206 foreach (TaskInventoryItem tii in taskDictionary.Values) 267 foreach (TaskInventoryItem tii in taskDictionary.Values)
207 { 268 {
208// m_log.DebugFormat( 269 // m_log.DebugFormat(
209// "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", 270 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
210// tii.Name, tii.Type, part.Name, part.UUID); 271 // tii.Name, tii.Type, part.Name, part.UUID);
211 272
212 if (!assetUuids.ContainsKey(tii.AssetID)) 273 if (!assetUuids.ContainsKey(tii.AssetID))
213 GatherAssetUuids(tii.AssetID, (sbyte)tii.Type, assetUuids); 274 GatherAssetUuids(tii.AssetID, (sbyte)tii.Type, assetUuids);
@@ -217,7 +278,7 @@ namespace OpenSim.Region.Framework.Scenes
217 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and 278 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
218 // inventory transfer. There needs to be a way for a module to register a method without assuming a 279 // inventory transfer. There needs to be a way for a module to register a method without assuming a
219 // Scene.EventManager is present. 280 // Scene.EventManager is present.
220// part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids); 281 // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
221 282
222 283
223 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs 284 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
@@ -246,19 +307,6 @@ namespace OpenSim.Region.Framework.Scenes
246 } 307 }
247 } 308 }
248 309
249// /// <summary>
250// /// The callback made when we request the asset for an object from the asset service.
251// /// </summary>
252// private void AssetReceived(string id, Object sender, AssetBase asset)
253// {
254// lock (this)
255// {
256// m_requestedObjectAsset = asset;
257// m_waitingForObjectAsset = false;
258// Monitor.Pulse(this);
259// }
260// }
261
262 /// <summary> 310 /// <summary>
263 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps 311 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps
264 /// stored in legacy format in part.DynAttrs 312 /// stored in legacy format in part.DynAttrs
@@ -327,7 +375,7 @@ namespace OpenSim.Region.Framework.Scenes
327 } 375 }
328 } 376 }
329 } 377 }
330 378
331 /// <summary> 379 /// <summary>
332 /// Get an asset synchronously, potentially using an asynchronous callback. If the 380 /// Get an asset synchronously, potentially using an asynchronous callback. If the
333 /// asynchronous callback is used, we will wait for it to complete. 381 /// asynchronous callback is used, we will wait for it to complete.
@@ -340,54 +388,64 @@ namespace OpenSim.Region.Framework.Scenes
340 388
341 // XXX: Switching to do this synchronously where the call was async before but we always waited for it 389 // XXX: Switching to do this synchronously where the call was async before but we always waited for it
342 // to complete anyway! 390 // to complete anyway!
343// m_waitingForObjectAsset = true; 391 // m_waitingForObjectAsset = true;
344// m_assetCache.Get(uuid.ToString(), this, AssetReceived); 392 // m_assetCache.Get(uuid.ToString(), this, AssetReceived);
345// 393 //
346// // The asset cache callback can either 394 // // The asset cache callback can either
347// // 395 // //
348// // 1. Complete on the same thread (if the asset is already in the cache) or 396 // // 1. Complete on the same thread (if the asset is already in the cache) or
349// // 2. Come in via a different thread (if we need to go fetch it). 397 // // 2. Come in via a different thread (if we need to go fetch it).
350// // 398 // //
351// // The code below handles both these alternatives. 399 // // The code below handles both these alternatives.
352// lock (this) 400 // lock (this)
353// { 401 // {
354// if (m_waitingForObjectAsset) 402 // if (m_waitingForObjectAsset)
355// { 403 // {
356// Monitor.Wait(this); 404 // Monitor.Wait(this);
357// m_waitingForObjectAsset = false; 405 // m_waitingForObjectAsset = false;
358// } 406 // }
359// } 407 // }
360// 408 //
361// return m_requestedObjectAsset; 409 // return m_requestedObjectAsset;
362 } 410 }
363 411
364 /// <summary> 412 /// <summary>
365 /// Record the asset uuids embedded within the given script. 413 /// Record the asset uuids embedded within the given text (e.g. a script).
366 /// </summary> 414 /// </summary>
367 /// <param name="scriptUuid"></param> 415 /// <param name="textAssetUuid"></param>
368 /// <param name="assetUuids">Dictionary in which to record the references</param> 416 /// <param name="assetUuids">Dictionary in which to record the references</param>
369 private void GetTextEmbeddedAssetUuids(UUID embeddingAssetId, IDictionary<UUID, sbyte> assetUuids) 417 private void GetTextEmbeddedAssetUuids(UUID textAssetUuid, IDictionary<UUID, sbyte> assetUuids)
370 { 418 {
371// m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); 419 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
372 420
373 AssetBase embeddingAsset = GetAsset(embeddingAssetId); 421 AssetBase textAsset = GetAsset(textAssetUuid);
374 422
375 if (null != embeddingAsset) 423 if (null != textAsset)
376 { 424 GetTextEmbeddedAssetUuids(textAsset, assetUuids);
377 string script = Utils.BytesToString(embeddingAsset.Data); 425 }
378// m_log.DebugFormat("[ARCHIVER]: Script {0}", script);
379 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script);
380// m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count);
381 426
382 foreach (Match uuidMatch in uuidMatches) 427 /// <summary>
383 { 428 /// Record the asset uuids embedded within the given text (e.g. a script).
384 UUID uuid = new UUID(uuidMatch.Value); 429 /// </summary>
385// m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); 430 /// <param name="textAsset"></param>
431 /// <param name="assetUuids">Dictionary in which to record the references</param>
432 private void GetTextEmbeddedAssetUuids(AssetBase textAsset, IDictionary<UUID, sbyte> assetUuids)
433 {
434 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
386 435
387 // Embedded asset references (if not false positives) could be for many types of asset, so we will 436 string script = Utils.BytesToString(textAsset.Data);
388 // label these as unknown. 437 // m_log.DebugFormat("[ARCHIVER]: Script {0}", script);
389 assetUuids[uuid] = (sbyte)AssetType.Unknown; 438 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script);
390 } 439 // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count);
440
441 foreach (Match uuidMatch in uuidMatches)
442 {
443 UUID uuid = new UUID(uuidMatch.Value);
444 // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid);
445
446 // Embedded asset references (if not false positives) could be for many types of asset, so we will
447 // label these as unknown.
448 assetUuids[uuid] = (sbyte)AssetType.Unknown;
391 } 449 }
392 } 450 }
393 451
@@ -401,18 +459,26 @@ namespace OpenSim.Region.Framework.Scenes
401 AssetBase assetBase = GetAsset(wearableAssetUuid); 459 AssetBase assetBase = GetAsset(wearableAssetUuid);
402 460
403 if (null != assetBase) 461 if (null != assetBase)
462 GetWearableAssetUuids(assetBase, assetUuids);
463 }
464
465 /// <summary>
466 /// Record the uuids referenced by the given wearable asset
467 /// </summary>
468 /// <param name="assetBase"></param>
469 /// <param name="assetUuids">Dictionary in which to record the references</param>
470 private void GetWearableAssetUuids(AssetBase assetBase, IDictionary<UUID, sbyte> assetUuids)
471 {
472 //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data));
473 AssetWearable wearableAsset = new AssetBodypart(assetBase.FullID, assetBase.Data);
474 wearableAsset.Decode();
475
476 //m_log.DebugFormat(
477 // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count);
478
479 foreach (UUID uuid in wearableAsset.Textures.Values)
404 { 480 {
405 //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data)); 481 assetUuids[uuid] = (sbyte)AssetType.Texture;
406 AssetWearable wearableAsset = new AssetBodypart(wearableAssetUuid, assetBase.Data);
407 wearableAsset.Decode();
408
409 //m_log.DebugFormat(
410 // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count);
411
412 foreach (UUID uuid in wearableAsset.Textures.Values)
413 {
414 assetUuids[uuid] = (sbyte)AssetType.Texture;
415 }
416 } 482 }
417 } 483 }
418 484
@@ -425,25 +491,35 @@ namespace OpenSim.Region.Framework.Scenes
425 /// <param name="assetUuids"></param> 491 /// <param name="assetUuids"></param>
426 private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids) 492 private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids)
427 { 493 {
428 AssetBase objectAsset = GetAsset(sceneObjectUuid); 494 AssetBase sceneObjectAsset = GetAsset(sceneObjectUuid);
495
496 if (null != sceneObjectAsset)
497 GetSceneObjectAssetUuids(sceneObjectAsset, assetUuids);
498 }
499
500 /// <summary>
501 /// Get all the asset uuids associated with a given object. This includes both those directly associated with
502 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
503 /// within this object).
504 /// </summary>
505 /// <param name="sceneObjectAsset"></param>
506 /// <param name="assetUuids"></param>
507 private void GetSceneObjectAssetUuids(AssetBase sceneObjectAsset, IDictionary<UUID, sbyte> assetUuids)
508 {
509 string xml = Utils.BytesToString(sceneObjectAsset.Data);
429 510
430 if (null != objectAsset) 511 CoalescedSceneObjects coa;
512 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa))
431 { 513 {
432 string xml = Utils.BytesToString(objectAsset.Data); 514 foreach (SceneObjectGroup sog in coa.Objects)
433 515 GatherAssetUuids(sog, assetUuids);
434 CoalescedSceneObjects coa; 516 }
435 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) 517 else
436 { 518 {
437 foreach (SceneObjectGroup sog in coa.Objects) 519 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
438 GatherAssetUuids(sog, assetUuids); 520
439 } 521 if (null != sog)
440 else 522 GatherAssetUuids(sog, assetUuids);
441 {
442 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
443
444 if (null != sog)
445 GatherAssetUuids(sog, assetUuids);
446 }
447 } 523 }
448 } 524 }
449 525
@@ -454,12 +530,22 @@ namespace OpenSim.Region.Framework.Scenes
454 /// <param name="assetUuids"></param> 530 /// <param name="assetUuids"></param>
455 private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids) 531 private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids)
456 { 532 {
457 AssetBase assetBase = GetAsset(gestureUuid); 533 AssetBase gestureAsset = GetAsset(gestureUuid);
458 if (null == assetBase) 534 if (null == gestureAsset)
459 return; 535 return;
460 536
461 using (MemoryStream ms = new MemoryStream(assetBase.Data)) 537 GetGestureAssetUuids(gestureAsset, assetUuids);
462 using (StreamReader sr = new StreamReader(ms)) 538 }
539
540 /// <summary>
541 /// Get the asset uuid associated with a gesture
542 /// </summary>
543 /// <param name="gestureAsset"></param>
544 /// <param name="assetUuids"></param>
545 private void GetGestureAssetUuids(AssetBase gestureAsset, IDictionary<UUID, sbyte> assetUuids)
546 {
547 using (MemoryStream ms = new MemoryStream(gestureAsset.Data))
548 using (StreamReader sr = new StreamReader(ms))
463 { 549 {
464 sr.ReadLine(); // Unknown (Version?) 550 sr.ReadLine(); // Unknown (Version?)
465 sr.ReadLine(); // Unknown 551 sr.ReadLine(); // Unknown
@@ -500,7 +586,15 @@ namespace OpenSim.Region.Framework.Scenes
500 if (null == assetBase) 586 if (null == assetBase)
501 return; 587 return;
502 588
503 OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(assetBase.Data); 589 GetMaterialAssetUuids(assetBase, assetUuids);
590 }
591
592 /// <summary>
593 /// Get the asset uuid's referenced in a material.
594 /// </summary>
595 private void GetMaterialAssetUuids(AssetBase materialAsset, IDictionary<UUID, sbyte> assetUuids)
596 {
597 OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data);
504 598
505 UUID normMap = mat["NormMap"].AsUUID(); 599 UUID normMap = mat["NormMap"].AsUUID();
506 if (normMap != UUID.Zero) 600 if (normMap != UUID.Zero)
@@ -536,7 +630,541 @@ namespace OpenSim.Region.Framework.Scenes
536 630
537 public AssetBase FetchAsset(UUID assetID) 631 public AssetBase FetchAsset(UUID assetID)
538 { 632 {
633 // Test if it's already here
634 AssetBase asset = m_assetService.Get(assetID.ToString());
635 if (asset == null)
636 {
637 // It's not, so fetch it from abroad
638 asset = m_assetService.Get(m_assetServerURL + assetID.ToString());
639 if (asset != null)
640 m_log.DebugFormat("[HGUUIDGatherer]: Copied asset {0} from {1} to local asset server", assetID, m_assetServerURL);
641 else
642 m_log.DebugFormat("[HGUUIDGatherer]: Failed to fetch asset {0} from {1}", assetID, m_assetServerURL);
643 }
644 //else
645 // m_log.DebugFormat("[HGUUIDGatherer]: Asset {0} from {1} was already here", assetID, m_assetServerURL);
646
647 return asset;
648 }
649 }
650
651 public class IteratingUuidGatherer
652 {
653 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
654
655 /// <summary>
656 /// Is gathering complete?
657 /// </summary>
658 public bool Complete { get { return m_assetUuidsToInspect.Count <= 0; } }
659
660 /// <summary>
661 /// Gets the next UUID to inspect.
662 /// </summary>
663 /// <value>If there is no next UUID then returns null</value>
664 public UUID? NextUuidToInspect
665 {
666 get
667 {
668 if (Complete)
669 return null;
670 else
671 return m_assetUuidsToInspect.Peek();
672 }
673 }
674
675 protected IAssetService m_assetService;
676
677 protected IDictionary<UUID, sbyte> m_gatheredAssetUuids;
678
679 protected Queue<UUID> m_assetUuidsToInspect;
680
681 public IteratingUuidGatherer(IAssetService assetService)
682 {
683 m_assetService = assetService;
684 m_gatheredAssetUuids = new Dictionary<UUID, sbyte>();
685
686 // FIXME: Not efficient for searching, can improve.
687 m_assetUuidsToInspect = new Queue<UUID>();
688 }
689
690 public IDictionary<UUID, sbyte> GetGatheredUuids()
691 {
692 return new Dictionary<UUID, sbyte>(m_gatheredAssetUuids);
693 }
694
695 public bool AddAssetUuidToInspect(UUID uuid)
696 {
697 if (m_assetUuidsToInspect.Contains(uuid))
698 return false;
699
700 m_assetUuidsToInspect.Enqueue(uuid);
701
702 return true;
703 }
704
705 /// <summary>
706 /// Gathers the next set of assets returned by the next uuid to get from the asset service.
707 /// </summary>
708 /// <returns>false if gathering is already complete, true otherwise</returns>
709 public bool GatherNext()
710 {
711 if (Complete)
712 return false;
713
714 GetAssetUuids(m_assetUuidsToInspect.Dequeue());
715
716 return true;
717 }
718
719 /// <summary>
720 /// Gathers all remaining asset UUIDS no matter how many calls are required to the asset service.
721 /// </summary>
722 /// <returns>false if gathering is already complete, true otherwise</returns>
723 public bool GatherAll()
724 {
725 if (Complete)
726 return false;
727
728 while (GatherNext());
729
730 return true;
731 }
732
733 /// <summary>
734 /// Gather all the asset uuids associated with the asset referenced by a given uuid
735 /// </summary>
736 /// <remarks>
737 /// This includes both those directly associated with
738 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
739 /// within this object).
740 /// This method assumes that the asset type associated with this asset in persistent storage is correct (which
741 /// should always be the case). So with this method we always need to retrieve asset data even if the asset
742 /// is of a type which is known not to reference any other assets
743 /// </remarks>
744 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
745 private void GetAssetUuids(UUID assetUuid)
746 {
747 // avoid infinite loops
748 if (m_gatheredAssetUuids.ContainsKey(assetUuid))
749 return;
750
751 try
752 {
753 AssetBase assetBase = GetAsset(assetUuid);
754
755 if (null != assetBase)
756 {
757 sbyte assetType = assetBase.Type;
758 m_gatheredAssetUuids[assetUuid] = assetType;
759
760 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
761 {
762 RecordWearableAssetUuids(assetBase);
763 }
764 else if ((sbyte)AssetType.Gesture == assetType)
765 {
766 RecordGestureAssetUuids(assetBase);
767 }
768 else if ((sbyte)AssetType.Notecard == assetType)
769 {
770 RecordTextEmbeddedAssetUuids(assetBase);
771 }
772 else if ((sbyte)AssetType.LSLText == assetType)
773 {
774 RecordTextEmbeddedAssetUuids(assetBase);
775 }
776 else if ((sbyte)OpenSimAssetType.Material == assetType)
777 {
778 RecordMaterialAssetUuids(assetBase);
779 }
780 else if ((sbyte)AssetType.Object == assetType)
781 {
782 RecordSceneObjectAssetUuids(assetBase);
783 }
784 }
785 }
786 catch (Exception)
787 {
788 m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid);
789 throw;
790 }
791 }
792
793 private void RecordAssetUuids(UUID assetUuid, sbyte assetType)
794 {
795 // Here, we want to collect uuids which require further asset fetches but mark the others as gathered
796 try
797 {
798 m_gatheredAssetUuids[assetUuid] = assetType;
799
800 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
801 {
802 AddAssetUuidToInspect(assetUuid);
803 }
804 else if ((sbyte)AssetType.Gesture == assetType)
805 {
806 AddAssetUuidToInspect(assetUuid);
807 }
808 else if ((sbyte)AssetType.Notecard == assetType)
809 {
810 AddAssetUuidToInspect(assetUuid);
811 }
812 else if ((sbyte)AssetType.LSLText == assetType)
813 {
814 AddAssetUuidToInspect(assetUuid);
815 }
816 else if ((sbyte)OpenSimAssetType.Material == assetType)
817 {
818 AddAssetUuidToInspect(assetUuid);
819 }
820 else if ((sbyte)AssetType.Object == assetType)
821 {
822 AddAssetUuidToInspect(assetUuid);
823 }
824 }
825 catch (Exception)
826 {
827 m_log.ErrorFormat(
828 "[ITERATABLE UUID GATHERER]: Failed to gather uuids for asset id {0}, type {1}",
829 assetUuid, assetType);
830 throw;
831 }
832 }
833
834 /// <summary>
835 /// Gather all the asset uuids associated with a given object.
836 /// </summary>
837 /// <remarks>
838 /// This includes both those directly associated with
839 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
840 /// within this object).
841 /// </remarks>
842 /// <param name="sceneObject">The scene object for which to gather assets</param>
843 public void RecordAssetUuids(SceneObjectGroup sceneObject)
844 {
845 // m_log.DebugFormat(
846 // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
539 847
848 SceneObjectPart[] parts = sceneObject.Parts;
849 for (int i = 0; i < parts.Length; i++)
850 {
851 SceneObjectPart part = parts[i];
852
853 // m_log.DebugFormat(
854 // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
855
856 try
857 {
858 Primitive.TextureEntry textureEntry = part.Shape.Textures;
859 if (textureEntry != null)
860 {
861 // Get the prim's default texture. This will be used for faces which don't have their own texture
862 if (textureEntry.DefaultTexture != null)
863 RecordTextureEntryAssetUuids(textureEntry.DefaultTexture);
864
865 if (textureEntry.FaceTextures != null)
866 {
867 // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture)
868 foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures)
869 {
870 if (texture != null)
871 RecordTextureEntryAssetUuids(texture);
872 }
873 }
874 }
875
876 // If the prim is a sculpt then preserve this information too
877 if (part.Shape.SculptTexture != UUID.Zero)
878 m_gatheredAssetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
879
880 if (part.Shape.ProjectionTextureUUID != UUID.Zero)
881 m_gatheredAssetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
882
883 if (part.CollisionSound != UUID.Zero)
884 m_gatheredAssetUuids[part.CollisionSound] = (sbyte)AssetType.Sound;
885
886 if (part.ParticleSystem.Length > 0)
887 {
888 try
889 {
890 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
891 if (ps.Texture != UUID.Zero)
892 m_gatheredAssetUuids[ps.Texture] = (sbyte)AssetType.Texture;
893 }
894 catch (Exception)
895 {
896 m_log.WarnFormat(
897 "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.",
898 part.Name, part.UUID, sceneObject.Name, sceneObject.UUID);
899 }
900 }
901
902 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
903
904 // Now analyze this prim's inventory items to preserve all the uuids that they reference
905 foreach (TaskInventoryItem tii in taskDictionary.Values)
906 {
907 // m_log.DebugFormat(
908 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
909 // tii.Name, tii.Type, part.Name, part.UUID);
910
911 if (!m_gatheredAssetUuids.ContainsKey(tii.AssetID))
912 RecordAssetUuids(tii.AssetID, (sbyte)tii.Type);
913 }
914
915 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
916 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
917 // inventory transfer. There needs to be a way for a module to register a method without assuming a
918 // Scene.EventManager is present.
919 // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
920
921
922 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
923 RecordMaterialsUuids(part);
924 }
925 catch (Exception e)
926 {
927 m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e);
928 m_log.DebugFormat(
929 "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)",
930 part.Shape.TextureEntry.Length);
931 }
932 }
933 }
934
935 /// <summary>
936 /// Collect all the asset uuids found in one face of a Texture Entry.
937 /// </summary>
938 private void RecordTextureEntryAssetUuids(Primitive.TextureEntryFace texture)
939 {
940 m_gatheredAssetUuids[texture.TextureID] = (sbyte)AssetType.Texture;
941
942 if (texture.MaterialID != UUID.Zero)
943 AddAssetUuidToInspect(texture.MaterialID);
944 }
945
946 /// <summary>
947 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps
948 /// stored in legacy format in part.DynAttrs
949 /// </summary>
950 /// <param name="part"></param>
951 public void RecordMaterialsUuids(SceneObjectPart part)
952 {
953 // scan thru the dynAttrs map of this part for any textures used as materials
954 OSD osdMaterials = null;
955
956 lock (part.DynAttrs)
957 {
958 if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
959 {
960 OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
961
962 if (materialsStore == null)
963 return;
964
965 materialsStore.TryGetValue("Materials", out osdMaterials);
966 }
967
968 if (osdMaterials != null)
969 {
970 //m_log.Info("[UUID Gatherer]: found Materials: " + OSDParser.SerializeJsonString(osd));
971
972 if (osdMaterials is OSDArray)
973 {
974 OSDArray matsArr = osdMaterials as OSDArray;
975 foreach (OSDMap matMap in matsArr)
976 {
977 try
978 {
979 if (matMap.ContainsKey("Material"))
980 {
981 OSDMap mat = matMap["Material"] as OSDMap;
982 if (mat.ContainsKey("NormMap"))
983 {
984 UUID normalMapId = mat["NormMap"].AsUUID();
985 if (normalMapId != UUID.Zero)
986 {
987 m_gatheredAssetUuids[normalMapId] = (sbyte)AssetType.Texture;
988 //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString());
989 }
990 }
991 if (mat.ContainsKey("SpecMap"))
992 {
993 UUID specularMapId = mat["SpecMap"].AsUUID();
994 if (specularMapId != UUID.Zero)
995 {
996 m_gatheredAssetUuids[specularMapId] = (sbyte)AssetType.Texture;
997 //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString());
998 }
999 }
1000 }
1001
1002 }
1003 catch (Exception e)
1004 {
1005 m_log.Warn("[UUID Gatherer]: exception getting materials: " + e.Message);
1006 }
1007 }
1008 }
1009 }
1010 }
1011 }
1012
1013 /// <summary>
1014 /// Get an asset synchronously, potentially using an asynchronous callback. If the
1015 /// asynchronous callback is used, we will wait for it to complete.
1016 /// </summary>
1017 /// <param name="uuid"></param>
1018 /// <returns></returns>
1019 protected virtual AssetBase GetAsset(UUID uuid)
1020 {
1021 return m_assetService.Get(uuid.ToString());
1022 }
1023
1024 /// <summary>
1025 /// Record the asset uuids embedded within the given text (e.g. a script).
1026 /// </summary>
1027 /// <param name="textAsset"></param>
1028 private void RecordTextEmbeddedAssetUuids(AssetBase textAsset)
1029 {
1030 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
1031
1032 string script = Utils.BytesToString(textAsset.Data);
1033 // m_log.DebugFormat("[ARCHIVER]: Script {0}", script);
1034 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script);
1035 // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count);
1036
1037 foreach (Match uuidMatch in uuidMatches)
1038 {
1039 UUID uuid = new UUID(uuidMatch.Value);
1040 // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid);
1041
1042 AddAssetUuidToInspect(uuid);
1043 }
1044 }
1045
1046 /// <summary>
1047 /// Record the uuids referenced by the given wearable asset
1048 /// </summary>
1049 /// <param name="assetBase"></param>
1050 private void RecordWearableAssetUuids(AssetBase assetBase)
1051 {
1052 //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data));
1053 AssetWearable wearableAsset = new AssetBodypart(assetBase.FullID, assetBase.Data);
1054 wearableAsset.Decode();
1055
1056 //m_log.DebugFormat(
1057 // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count);
1058
1059 foreach (UUID uuid in wearableAsset.Textures.Values)
1060 m_gatheredAssetUuids[uuid] = (sbyte)AssetType.Texture;
1061 }
1062
1063 /// <summary>
1064 /// Get all the asset uuids associated with a given object. This includes both those directly associated with
1065 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
1066 /// within this object).
1067 /// </summary>
1068 /// <param name="sceneObjectAsset"></param>
1069 private void RecordSceneObjectAssetUuids(AssetBase sceneObjectAsset)
1070 {
1071 string xml = Utils.BytesToString(sceneObjectAsset.Data);
1072
1073 CoalescedSceneObjects coa;
1074 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa))
1075 {
1076 foreach (SceneObjectGroup sog in coa.Objects)
1077 RecordAssetUuids(sog);
1078 }
1079 else
1080 {
1081 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
1082
1083 if (null != sog)
1084 RecordAssetUuids(sog);
1085 }
1086 }
1087
1088 /// <summary>
1089 /// Get the asset uuid associated with a gesture
1090 /// </summary>
1091 /// <param name="gestureAsset"></param>
1092 private void RecordGestureAssetUuids(AssetBase gestureAsset)
1093 {
1094 using (MemoryStream ms = new MemoryStream(gestureAsset.Data))
1095 using (StreamReader sr = new StreamReader(ms))
1096 {
1097 sr.ReadLine(); // Unknown (Version?)
1098 sr.ReadLine(); // Unknown
1099 sr.ReadLine(); // Unknown
1100 sr.ReadLine(); // Name
1101 sr.ReadLine(); // Comment ?
1102 int count = Convert.ToInt32(sr.ReadLine()); // Item count
1103
1104 for (int i = 0 ; i < count ; i++)
1105 {
1106 string type = sr.ReadLine();
1107 if (type == null)
1108 break;
1109 string name = sr.ReadLine();
1110 if (name == null)
1111 break;
1112 string id = sr.ReadLine();
1113 if (id == null)
1114 break;
1115 string unknown = sr.ReadLine();
1116 if (unknown == null)
1117 break;
1118
1119 // If it can be parsed as a UUID, it is an asset ID
1120 UUID uuid;
1121 if (UUID.TryParse(id, out uuid))
1122 m_gatheredAssetUuids[uuid] = (sbyte)AssetType.Animation; // the asset is either an Animation or a Sound, but this distinction isn't important
1123 }
1124 }
1125 }
1126
1127 /// <summary>
1128 /// Get the asset uuid's referenced in a material.
1129 /// </summary>
1130 private void RecordMaterialAssetUuids(AssetBase materialAsset)
1131 {
1132 OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data);
1133
1134 UUID normMap = mat["NormMap"].AsUUID();
1135 if (normMap != UUID.Zero)
1136 m_gatheredAssetUuids[normMap] = (sbyte)AssetType.Texture;
1137
1138 UUID specMap = mat["SpecMap"].AsUUID();
1139 if (specMap != UUID.Zero)
1140 m_gatheredAssetUuids[specMap] = (sbyte)AssetType.Texture;
1141 }
1142 }
1143
1144 public class IteratingHGUuidGatherer : IteratingUuidGatherer
1145 {
1146 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1147
1148 protected string m_assetServerURL;
1149
1150 public IteratingHGUuidGatherer(IAssetService assetService, string assetServerURL)
1151 : base(assetService)
1152 {
1153 m_assetServerURL = assetServerURL;
1154 if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("="))
1155 m_assetServerURL = m_assetServerURL + "/";
1156 }
1157
1158 protected override AssetBase GetAsset(UUID uuid)
1159 {
1160 if (string.Empty == m_assetServerURL)
1161 return base.GetAsset(uuid);
1162 else
1163 return FetchAsset(uuid);
1164 }
1165
1166 public AssetBase FetchAsset(UUID assetID)
1167 {
540 // Test if it's already here 1168 // Test if it's already here
541 AssetBase asset = m_assetService.Get(assetID.ToString()); 1169 AssetBase asset = m_assetService.Get(assetID.ToString());
542 if (asset == null) 1170 if (asset == null)