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