diff options
author | Justin Clark-Casey (justincc) | 2012-05-24 00:31:14 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-05-24 00:31:14 +0100 |
commit | 459c7635afdbc4002cacbf5780185645a4296f6a (patch) | |
tree | 9cf90fb39bc20e9283d6702d102475db08ca53d3 /OpenSim/Region/CoreModules/ServiceConnectorsOut | |
parent | Environment Module - allows Environment settings for Viewer3 warning: include... (diff) | |
download | opensim-SC-459c7635afdbc4002cacbf5780185645a4296f6a.zip opensim-SC-459c7635afdbc4002cacbf5780185645a4296f6a.tar.gz opensim-SC-459c7635afdbc4002cacbf5780185645a4296f6a.tar.bz2 opensim-SC-459c7635afdbc4002cacbf5780185645a4296f6a.tar.xz |
If an agent is still registered as 'in transit' by the source region, don't allow an immediate teleport back.
This is to help relieve a race condition when an agent teleports then immediately attempts to teleport back before the source region has properly cleaned up/demoted the old ScenePresence.
This is rare in viewers but much more possible via scripting or region module.
However, more needs to be done since virtually all clean up happens after the transit flag is cleared .
Possibly need to add a 'cleaning up' state to in transit.
This change required making the EntityTransferModule and HGEntityTransferModule per-region rather than shared, in order to allow separate transit lists.
Changes were also required in LocalSimulationConnector.
Tested in standalone, grid and with local and remote region crossings with attachments.
Diffstat (limited to 'OpenSim/Region/CoreModules/ServiceConnectorsOut')
-rw-r--r-- | OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs | 186 |
1 files changed, 95 insertions, 91 deletions
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 90f27c4..270daad 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | using System; | 27 | using System; |
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Linq; | ||
29 | using System.Reflection; | 30 | using System.Reflection; |
30 | using log4net; | 31 | using log4net; |
31 | using Nini.Config; | 32 | using Nini.Config; |
@@ -41,22 +42,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
41 | public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService | 42 | public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService |
42 | { | 43 | { |
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
44 | // Version of this service | ||
45 | private const string m_Version = "SIMULATION/0.1"; | ||
46 | 45 | ||
47 | private List<Scene> m_sceneList = new List<Scene>(); | 46 | /// <summary> |
47 | /// Version of this service | ||
48 | /// </summary> | ||
49 | private const string m_Version = "SIMULATION/0.1"; | ||
48 | 50 | ||
49 | private IEntityTransferModule m_AgentTransferModule; | 51 | /// <summary> |
50 | protected IEntityTransferModule AgentTransferModule | 52 | /// Map region ID to scene. |
51 | { | 53 | /// </summary> |
52 | get | 54 | private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); |
53 | { | ||
54 | if (m_AgentTransferModule == null) | ||
55 | m_AgentTransferModule = m_sceneList[0].RequestModuleInterface<IEntityTransferModule>(); | ||
56 | return m_AgentTransferModule; | ||
57 | } | ||
58 | } | ||
59 | 55 | ||
56 | /// <summary> | ||
57 | /// Is this module enabled? | ||
58 | /// </summary> | ||
60 | private bool m_ModuleEnabled = false; | 59 | private bool m_ModuleEnabled = false; |
61 | 60 | ||
62 | #region IRegionModule | 61 | #region IRegionModule |
@@ -129,12 +128,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
129 | /// <param name="scene"></param> | 128 | /// <param name="scene"></param> |
130 | public void RemoveScene(Scene scene) | 129 | public void RemoveScene(Scene scene) |
131 | { | 130 | { |
132 | lock (m_sceneList) | 131 | lock (m_scenes) |
133 | { | 132 | { |
134 | if (m_sceneList.Contains(scene)) | 133 | if (m_scenes.ContainsKey(scene.RegionInfo.RegionID)) |
135 | { | 134 | m_scenes.Remove(scene.RegionInfo.RegionID); |
136 | m_sceneList.Remove(scene); | 135 | else |
137 | } | 136 | m_log.WarnFormat( |
137 | "[LOCAL SIMULATION CONNECTOR]: Tried to remove region {0} but it was not present", | ||
138 | scene.RegionInfo.RegionName); | ||
138 | } | 139 | } |
139 | } | 140 | } |
140 | 141 | ||
@@ -144,13 +145,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
144 | /// <param name="scene"></param> | 145 | /// <param name="scene"></param> |
145 | public void Init(Scene scene) | 146 | public void Init(Scene scene) |
146 | { | 147 | { |
147 | if (!m_sceneList.Contains(scene)) | 148 | lock (m_scenes) |
148 | { | 149 | { |
149 | lock (m_sceneList) | 150 | if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID)) |
150 | { | 151 | m_scenes[scene.RegionInfo.RegionID] = scene; |
151 | m_sceneList.Add(scene); | 152 | else |
152 | } | 153 | m_log.WarnFormat( |
153 | 154 | "[LOCAL SIMULATION CONNECTOR]: Tried to add region {0} but it is already present", | |
155 | scene.RegionInfo.RegionName); | ||
154 | } | 156 | } |
155 | } | 157 | } |
156 | 158 | ||
@@ -160,13 +162,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
160 | 162 | ||
161 | public IScene GetScene(ulong regionhandle) | 163 | public IScene GetScene(ulong regionhandle) |
162 | { | 164 | { |
163 | foreach (Scene s in m_sceneList) | 165 | foreach (Scene s in m_scenes.Values) |
164 | { | 166 | { |
165 | if (s.RegionInfo.RegionHandle == regionhandle) | 167 | if (s.RegionInfo.RegionHandle == regionhandle) |
166 | return s; | 168 | return s; |
167 | } | 169 | } |
170 | |||
168 | // ? weird. should not happen | 171 | // ? weird. should not happen |
169 | return m_sceneList[0]; | 172 | return m_scenes.Values.ToArray()[0]; |
170 | } | 173 | } |
171 | 174 | ||
172 | public ISimulationService GetInnerService() | 175 | public ISimulationService GetInnerService() |
@@ -187,13 +190,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
187 | return false; | 190 | return false; |
188 | } | 191 | } |
189 | 192 | ||
190 | foreach (Scene s in m_sceneList) | 193 | if (m_scenes.ContainsKey(destination.RegionID)) |
191 | { | 194 | { |
192 | if (s.RegionInfo.RegionHandle == destination.RegionHandle) | ||
193 | { | ||
194 | // m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName); | 195 | // m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName); |
195 | return s.NewUserConnection(aCircuit, teleportFlags, out reason); | 196 | return m_scenes[destination.RegionID].NewUserConnection(aCircuit, teleportFlags, out reason); |
196 | } | ||
197 | } | 197 | } |
198 | 198 | ||
199 | reason = "Did not find region " + destination.RegionName; | 199 | reason = "Did not find region " + destination.RegionName; |
@@ -205,17 +205,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
205 | if (destination == null) | 205 | if (destination == null) |
206 | return false; | 206 | return false; |
207 | 207 | ||
208 | foreach (Scene s in m_sceneList) | 208 | if (m_scenes.ContainsKey(destination.RegionID)) |
209 | { | 209 | { |
210 | if (s.RegionInfo.RegionHandle == destination.RegionHandle) | ||
211 | { | ||
212 | // m_log.DebugFormat( | 210 | // m_log.DebugFormat( |
213 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | 211 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
214 | // s.RegionInfo.RegionName, destination.RegionHandle); | 212 | // s.RegionInfo.RegionName, destination.RegionHandle); |
215 | 213 | ||
216 | s.IncomingChildAgentDataUpdate(cAgentData); | 214 | return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData); |
217 | return true; | ||
218 | } | ||
219 | } | 215 | } |
220 | 216 | ||
221 | // m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); | 217 | // m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); |
@@ -231,11 +227,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
231 | // simulator so when we receive the update we need to hand it to each of the | 227 | // simulator so when we receive the update we need to hand it to each of the |
232 | // scenes; scenes each check to see if the is a scene presence for the avatar | 228 | // scenes; scenes each check to see if the is a scene presence for the avatar |
233 | // note that we really don't need the GridRegion for this call | 229 | // note that we really don't need the GridRegion for this call |
234 | foreach (Scene s in m_sceneList) | 230 | foreach (Scene s in m_scenes.Values) |
235 | { | 231 | { |
236 | //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); | 232 | //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); |
237 | s.IncomingChildAgentDataUpdate(cAgentData); | 233 | s.IncomingChildAgentDataUpdate(cAgentData); |
238 | } | 234 | } |
235 | |||
239 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); | 236 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); |
240 | return true; | 237 | return true; |
241 | } | 238 | } |
@@ -247,14 +244,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
247 | if (destination == null) | 244 | if (destination == null) |
248 | return false; | 245 | return false; |
249 | 246 | ||
250 | foreach (Scene s in m_sceneList) | 247 | if (m_scenes.ContainsKey(destination.RegionID)) |
251 | { | 248 | { |
252 | if (s.RegionInfo.RegionHandle == destination.RegionHandle) | 249 | // m_log.DebugFormat( |
253 | { | 250 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
254 | //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); | 251 | // s.RegionInfo.RegionName, destination.RegionHandle); |
255 | return s.IncomingRetrieveRootAgent(id, out agent); | 252 | |
256 | } | 253 | return m_scenes[destination.RegionID].IncomingRetrieveRootAgent(id, out agent); |
257 | } | 254 | } |
255 | |||
258 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); | 256 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); |
259 | return false; | 257 | return false; |
260 | } | 258 | } |
@@ -266,27 +264,31 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
266 | if (destination == null) | 264 | if (destination == null) |
267 | return false; | 265 | return false; |
268 | 266 | ||
269 | foreach (Scene s in m_sceneList) | 267 | if (m_scenes.ContainsKey(destination.RegionID)) |
270 | { | 268 | { |
271 | if (s.RegionInfo.RegionID == destination.RegionID) | 269 | // m_log.DebugFormat( |
272 | return s.QueryAccess(id, position, out reason); | 270 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
271 | // s.RegionInfo.RegionName, destination.RegionHandle); | ||
272 | |||
273 | return m_scenes[destination.RegionID].QueryAccess(id, position, out reason); | ||
273 | } | 274 | } |
275 | |||
274 | //m_log.Debug("[LOCAL COMMS]: region not found for QueryAccess"); | 276 | //m_log.Debug("[LOCAL COMMS]: region not found for QueryAccess"); |
275 | return false; | 277 | return false; |
276 | } | 278 | } |
277 | 279 | ||
278 | public bool ReleaseAgent(UUID origin, UUID id, string uri) | 280 | public bool ReleaseAgent(UUID originId, UUID agentId, string uri) |
279 | { | 281 | { |
280 | foreach (Scene s in m_sceneList) | 282 | if (m_scenes.ContainsKey(originId)) |
281 | { | 283 | { |
282 | if (s.RegionInfo.RegionID == origin) | 284 | // m_log.DebugFormat( |
283 | { | 285 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
284 | // m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); | 286 | // s.RegionInfo.RegionName, destination.RegionHandle); |
285 | AgentTransferModule.AgentArrivedAtDestination(id); | 287 | |
286 | return true; | 288 | m_scenes[originId].EntityTransferModule.AgentArrivedAtDestination(agentId); |
287 | // return s.IncomingReleaseAgent(id); | 289 | return true; |
288 | } | ||
289 | } | 290 | } |
291 | |||
290 | //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent " + origin); | 292 | //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent " + origin); |
291 | return false; | 293 | return false; |
292 | } | 294 | } |
@@ -296,17 +298,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
296 | if (destination == null) | 298 | if (destination == null) |
297 | return false; | 299 | return false; |
298 | 300 | ||
299 | foreach (Scene s in m_sceneList) | 301 | if (m_scenes.ContainsKey(destination.RegionID)) |
300 | { | 302 | { |
301 | if (s.RegionInfo.RegionID == destination.RegionID) | 303 | // m_log.DebugFormat( |
302 | { | 304 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
303 | //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent"); | 305 | // s.RegionInfo.RegionName, destination.RegionHandle); |
304 | // Let's spawn a threadlet right here, because this may take | 306 | |
305 | // a while | 307 | Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); |
306 | Util.FireAndForget(delegate { s.IncomingCloseAgent(id); }); | 308 | return true; |
307 | return true; | ||
308 | } | ||
309 | } | 309 | } |
310 | |||
310 | //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); | 311 | //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); |
311 | return false; | 312 | return false; |
312 | } | 313 | } |
@@ -320,25 +321,28 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
320 | if (destination == null) | 321 | if (destination == null) |
321 | return false; | 322 | return false; |
322 | 323 | ||
323 | foreach (Scene s in m_sceneList) | 324 | if (m_scenes.ContainsKey(destination.RegionID)) |
324 | { | 325 | { |
325 | if (s.RegionInfo.RegionHandle == destination.RegionHandle) | 326 | // m_log.DebugFormat( |
327 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | ||
328 | // s.RegionInfo.RegionName, destination.RegionHandle); | ||
329 | |||
330 | Scene s = m_scenes[destination.RegionID]; | ||
331 | |||
332 | if (isLocalCall) | ||
326 | { | 333 | { |
327 | //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); | 334 | // We need to make a local copy of the object |
328 | if (isLocalCall) | 335 | ISceneObject sogClone = sog.CloneForNewScene(); |
329 | { | 336 | sogClone.SetState(sog.GetStateSnapshot(), s); |
330 | // We need to make a local copy of the object | 337 | return s.IncomingCreateObject(newPosition, sogClone); |
331 | ISceneObject sogClone = sog.CloneForNewScene(); | 338 | } |
332 | sogClone.SetState(sog.GetStateSnapshot(), s); | 339 | else |
333 | return s.IncomingCreateObject(newPosition, sogClone); | 340 | { |
334 | } | 341 | // Use the object as it came through the wire |
335 | else | 342 | return s.IncomingCreateObject(newPosition, sog); |
336 | { | ||
337 | // Use the object as it came through the wire | ||
338 | return s.IncomingCreateObject(newPosition, sog); | ||
339 | } | ||
340 | } | 343 | } |
341 | } | 344 | } |
345 | |||
342 | return false; | 346 | return false; |
343 | } | 347 | } |
344 | 348 | ||
@@ -347,13 +351,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
347 | if (destination == null) | 351 | if (destination == null) |
348 | return false; | 352 | return false; |
349 | 353 | ||
350 | foreach (Scene s in m_sceneList) | 354 | if (m_scenes.ContainsKey(destination.RegionID)) |
351 | { | 355 | { |
352 | if (s.RegionInfo.RegionHandle == destination.RegionHandle) | 356 | // m_log.DebugFormat( |
353 | { | 357 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
354 | return s.IncomingCreateObject(userID, itemID); | 358 | // s.RegionInfo.RegionName, destination.RegionHandle); |
355 | } | 359 | |
360 | return m_scenes[destination.RegionID].IncomingCreateObject(userID, itemID); | ||
356 | } | 361 | } |
362 | |||
357 | return false; | 363 | return false; |
358 | } | 364 | } |
359 | 365 | ||
@@ -364,20 +370,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
364 | 370 | ||
365 | public bool IsLocalRegion(ulong regionhandle) | 371 | public bool IsLocalRegion(ulong regionhandle) |
366 | { | 372 | { |
367 | foreach (Scene s in m_sceneList) | 373 | foreach (Scene s in m_scenes.Values) |
368 | if (s.RegionInfo.RegionHandle == regionhandle) | 374 | if (s.RegionInfo.RegionHandle == regionhandle) |
369 | return true; | 375 | return true; |
376 | |||
370 | return false; | 377 | return false; |
371 | } | 378 | } |
372 | 379 | ||
373 | public bool IsLocalRegion(UUID id) | 380 | public bool IsLocalRegion(UUID id) |
374 | { | 381 | { |
375 | foreach (Scene s in m_sceneList) | 382 | return m_scenes.ContainsKey(id); |
376 | if (s.RegionInfo.RegionID == id) | ||
377 | return true; | ||
378 | return false; | ||
379 | } | 383 | } |
380 | 384 | ||
381 | #endregion | 385 | #endregion |
382 | } | 386 | } |
383 | } | 387 | } \ No newline at end of file |