diff options
Diffstat (limited to 'OpenSim/Region/Framework')
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; | |||
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Tests.Common; | 37 | using OpenSim.Tests.Common; |
38 | using OpenSim.Tests.Common.Mock; | ||
39 | 38 | ||
40 | namespace OpenSim.Region.Framework.Scenes.Tests | 39 | namespace 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; | |||
36 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
38 | using OpenSim.Tests.Common; | 38 | using OpenSim.Tests.Common; |
39 | using OpenSim.Tests.Common.Mock; | ||
40 | 39 | ||
41 | namespace OpenSim.Region.Framework.Scenes.Tests | 40 | namespace 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; | |||
37 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
38 | using OpenSim.Services.Interfaces; | 38 | using OpenSim.Services.Interfaces; |
39 | using OpenSim.Tests.Common; | 39 | using OpenSim.Tests.Common; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | 40 | ||
42 | namespace OpenSim.Region.Framework.Scenes.Tests | 41 | namespace 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; | |||
37 | using OpenSim.Region.CoreModules.World.Land; | 37 | using OpenSim.Region.CoreModules.World.Land; |
38 | using OpenSim.Region.OptionalModules; | 38 | using OpenSim.Region.OptionalModules; |
39 | using OpenSim.Tests.Common; | 39 | using OpenSim.Tests.Common; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | 40 | ||
42 | namespace OpenSim.Region.Framework.Scenes.Tests | 41 | namespace 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; | |||
40 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Services.Interfaces; | 41 | using OpenSim.Services.Interfaces; |
42 | using OpenSim.Tests.Common; | 42 | using OpenSim.Tests.Common; |
43 | using OpenSim.Tests.Common.Mock; | ||
44 | 43 | ||
45 | namespace OpenSim.Region.Framework.Scenes.Tests | 44 | namespace 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; | |||
34 | using OpenSim.Framework.Communications; | 34 | using OpenSim.Framework.Communications; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Tests.Common; | 36 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | using log4net; | 37 | using log4net; |
39 | 38 | ||
40 | namespace OpenSim.Region.Framework.Scenes.Tests | 39 | namespace 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; | |||
33 | using OpenSim.Framework.Communications; | 33 | using OpenSim.Framework.Communications; |
34 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
35 | using OpenSim.Tests.Common; | 35 | using OpenSim.Tests.Common; |
36 | using OpenSim.Tests.Common.Mock; | ||
37 | 36 | ||
38 | namespace OpenSim.Region.Framework.Scenes.Tests | 37 | namespace 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; | |||
35 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
36 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Tests.Common; | 37 | using OpenSim.Tests.Common; |
38 | using OpenSim.Tests.Common.Mock; | ||
39 | 38 | ||
40 | namespace OpenSim.Region.Framework.Scenes.Tests | 39 | namespace 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; | |||
34 | using OpenSim.Framework.Communications; | 34 | using OpenSim.Framework.Communications; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Tests.Common; | 36 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | 37 | ||
39 | namespace OpenSim.Region.Framework.Scenes.Tests | 38 | namespace 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; | |||
34 | using OpenSim.Framework.Communications; | 34 | using OpenSim.Framework.Communications; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Tests.Common; | 36 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | 37 | ||
39 | namespace OpenSim.Region.Framework.Scenes.Tests | 38 | namespace 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; | |||
33 | using OpenSim.Framework.Communications; | 33 | using OpenSim.Framework.Communications; |
34 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
35 | using OpenSim.Tests.Common; | 35 | using OpenSim.Tests.Common; |
36 | using OpenSim.Tests.Common.Mock; | ||
37 | 36 | ||
38 | namespace OpenSim.Region.Framework.Scenes.Tests | 37 | namespace 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; | |||
39 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; | 40 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; |
41 | using OpenSim.Tests.Common; | 41 | using OpenSim.Tests.Common; |
42 | using OpenSim.Tests.Common.Mock; | ||
43 | 42 | ||
44 | namespace OpenSim.Region.Framework.Scenes.Tests | 43 | namespace 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; | |||
44 | using OpenSim.Region.CoreModules.World.Serialiser; | 44 | using OpenSim.Region.CoreModules.World.Serialiser; |
45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
46 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
47 | using OpenSim.Tests.Common.Mock; | ||
48 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 47 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
49 | 48 | ||
50 | namespace OpenSim.Region.Framework.Scenes.Tests | 49 | namespace 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; | |||
43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
44 | using OpenSim.Region.Physics.Manager; | 44 | using OpenSim.Region.Physics.Manager; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.Framework.Scenes.Tests | 47 | namespace 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; | |||
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
39 | using OpenSim.Tests.Common; | 39 | using OpenSim.Tests.Common; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | 40 | ||
42 | namespace OpenSim.Region.Framework.Scenes.Tests | 41 | namespace 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; | |||
47 | using OpenSim.Region.Framework.Scenes; | 47 | using OpenSim.Region.Framework.Scenes; |
48 | using OpenSim.Region.Framework.Interfaces; | 48 | using OpenSim.Region.Framework.Interfaces; |
49 | using OpenSim.Tests.Common; | 49 | using OpenSim.Tests.Common; |
50 | using OpenSim.Tests.Common.Mock; | ||
51 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 50 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
52 | 51 | ||
53 | namespace OpenSim.Region.Framework.Scenes.Tests | 52 | namespace 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; | |||
40 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 40 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
41 | using OpenSim.Region.CoreModules.World.Permissions; | 41 | using OpenSim.Region.CoreModules.World.Permissions; |
42 | using OpenSim.Tests.Common; | 42 | using OpenSim.Tests.Common; |
43 | using OpenSim.Tests.Common.Mock; | ||
44 | 43 | ||
45 | namespace OpenSim.Region.Framework.Scenes.Tests | 44 | namespace 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; | |||
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 38 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
39 | using OpenSim.Tests.Common; | 39 | using OpenSim.Tests.Common; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | using System.Threading; | 40 | using System.Threading; |
42 | 41 | ||
43 | namespace OpenSim.Region.Framework.Scenes.Tests | 42 | namespace 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; | |||
43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
44 | using OpenSim.Region.CoreModules.World.Permissions; | 44 | using OpenSim.Region.CoreModules.World.Permissions; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.Framework.Scenes.Tests | 47 | namespace 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; | |||
34 | using OpenSim.Framework.Communications; | 34 | using OpenSim.Framework.Communications; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Tests.Common; | 36 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | 37 | ||
39 | namespace OpenSim.Region.Framework.Scenes.Tests | 38 | namespace 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; | |||
32 | using OpenSim.Region.Framework.Interfaces; | 32 | using OpenSim.Region.Framework.Interfaces; |
33 | using OpenSim.Services.Interfaces; | 33 | using OpenSim.Services.Interfaces; |
34 | using OpenSim.Tests.Common; | 34 | using OpenSim.Tests.Common; |
35 | using OpenSim.Tests.Common.Mock; | ||
36 | 35 | ||
37 | namespace OpenSim.Region.Framework.Scenes.Tests | 36 | namespace 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; | |||
42 | using OpenSim.Region.CoreModules.World.Serialiser; | 42 | using OpenSim.Region.CoreModules.World.Serialiser; |
43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
44 | using OpenSim.Tests.Common; | 44 | using OpenSim.Tests.Common; |
45 | using OpenSim.Tests.Common.Mock; | ||
46 | 45 | ||
47 | namespace OpenSim.Region.Framework.Scenes.Tests | 46 | namespace 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; | |||
45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
46 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
47 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
48 | using OpenSim.Tests.Common.Mock; | ||
49 | 48 | ||
50 | namespace OpenSim.Region.Framework.Tests | 49 | namespace 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; | |||
45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
46 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
47 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
48 | using OpenSim.Tests.Common.Mock; | ||
49 | 48 | ||
50 | namespace OpenSim.Region.Framework.Tests | 49 | namespace 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; | |||
33 | using OpenSim.Region.Framework.Scenes; | 33 | using OpenSim.Region.Framework.Scenes; |
34 | using OpenSim.Services.Interfaces; | 34 | using OpenSim.Services.Interfaces; |
35 | using OpenSim.Tests.Common; | 35 | using OpenSim.Tests.Common; |
36 | using OpenSim.Tests.Common.Mock; | ||
37 | 36 | ||
38 | namespace OpenSim.Region.Framework.Scenes.Tests | 37 | namespace 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) |