diff options
author | Melanie | 2012-05-27 19:24:30 +0100 |
---|---|---|
committer | Melanie | 2012-05-27 19:24:30 +0100 |
commit | 884c0e7bb10bd2c2a951901c6f1dd56a86ef6b9f (patch) | |
tree | dd692a54213f86fd64bd29c6662584df85088193 /OpenSim/Region/CoreModules/Framework/EntityTransfer | |
parent | Merge branch 'master' into careminster (diff) | |
parent | minor: code formatting from 0b72f773 (diff) | |
download | opensim-SC-884c0e7bb10bd2c2a951901c6f1dd56a86ef6b9f.zip opensim-SC-884c0e7bb10bd2c2a951901c6f1dd56a86ef6b9f.tar.gz opensim-SC-884c0e7bb10bd2c2a951901c6f1dd56a86ef6b9f.tar.bz2 opensim-SC-884c0e7bb10bd2c2a951901c6f1dd56a86ef6b9f.tar.xz |
Merge branch 'master' into careminster
Conflicts:
OpenSim/Data/MySQL/MySQLSimulationData.cs
OpenSim/Data/MySQL/Resources/RegionStore.migrations
OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
OpenSim/Region/Framework/Scenes/Scene.cs
OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 822 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | 55 |
2 files changed, 519 insertions, 358 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index f9e2b2f..5d9d67f 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -46,7 +46,30 @@ using Nini.Config; | |||
46 | 46 | ||
47 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | 47 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer |
48 | { | 48 | { |
49 | public class EntityTransferModule : ISharedRegionModule, IEntityTransferModule | 49 | /// <summary> |
50 | /// The possible states that an agent can be in when its being transferred between regions. | ||
51 | /// </summary> | ||
52 | /// <remarks> | ||
53 | /// This is a state machine. | ||
54 | /// | ||
55 | /// [Entry] => Preparing | ||
56 | /// Preparing => { Transferring || CleaningUp || [Exit] } | ||
57 | /// Transferring => { ReceivedAtDestination || CleaningUp } | ||
58 | /// ReceivedAtDestination => CleaningUp | ||
59 | /// CleaningUp => [Exit] | ||
60 | /// | ||
61 | /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp | ||
62 | /// However, any state can transition to CleaningUp if the teleport has failed. | ||
63 | /// </remarks> | ||
64 | enum AgentTransferState | ||
65 | { | ||
66 | Preparing, // The agent is being prepared for transfer | ||
67 | Transferring, // The agent is in the process of being transferred to a destination | ||
68 | ReceivedAtDestination, // The destination has notified us that the agent has been successfully received | ||
69 | CleaningUp // The agent is being changed to child/removed after a transfer | ||
70 | } | ||
71 | |||
72 | public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule | ||
50 | { | 73 | { |
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 74 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | 75 | ||
@@ -65,12 +88,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
65 | public bool EnableWaitForCallbackFromTeleportDest { get; set; } | 88 | public bool EnableWaitForCallbackFromTeleportDest { get; set; } |
66 | 89 | ||
67 | protected bool m_Enabled = false; | 90 | protected bool m_Enabled = false; |
68 | protected Scene m_aScene; | 91 | |
69 | protected List<Scene> m_Scenes = new List<Scene>(); | 92 | protected Scene m_scene; |
70 | protected List<UUID> m_agentsInTransit; | 93 | |
94 | private Dictionary<UUID, AgentTransferState> m_agentsInTransit; | ||
95 | |||
71 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = | 96 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = |
72 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); | 97 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); |
73 | 98 | ||
99 | private IEventQueue m_eqModule; | ||
100 | |||
74 | #region ISharedRegionModule | 101 | #region ISharedRegionModule |
75 | 102 | ||
76 | public Type ReplaceableInterface | 103 | public Type ReplaceableInterface |
@@ -116,7 +143,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
116 | MaxTransferDistance = DefaultMaxTransferDistance; | 143 | MaxTransferDistance = DefaultMaxTransferDistance; |
117 | } | 144 | } |
118 | 145 | ||
119 | m_agentsInTransit = new List<UUID>(); | 146 | m_agentsInTransit = new Dictionary<UUID, AgentTransferState>(); |
120 | m_Enabled = true; | 147 | m_Enabled = true; |
121 | } | 148 | } |
122 | 149 | ||
@@ -129,10 +156,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
129 | if (!m_Enabled) | 156 | if (!m_Enabled) |
130 | return; | 157 | return; |
131 | 158 | ||
132 | if (m_aScene == null) | 159 | m_scene = scene; |
133 | m_aScene = scene; | ||
134 | 160 | ||
135 | m_Scenes.Add(scene); | ||
136 | scene.RegisterModuleInterface<IEntityTransferModule>(this); | 161 | scene.RegisterModuleInterface<IEntityTransferModule>(this); |
137 | scene.EventManager.OnNewClient += OnNewClient; | 162 | scene.EventManager.OnNewClient += OnNewClient; |
138 | } | 163 | } |
@@ -143,26 +168,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
143 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; | 168 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; |
144 | } | 169 | } |
145 | 170 | ||
146 | public virtual void Close() | 171 | public virtual void Close() {} |
147 | { | ||
148 | if (!m_Enabled) | ||
149 | return; | ||
150 | } | ||
151 | |||
152 | public virtual void RemoveRegion(Scene scene) | ||
153 | { | ||
154 | if (!m_Enabled) | ||
155 | return; | ||
156 | if (scene == m_aScene) | ||
157 | m_aScene = null; | ||
158 | 172 | ||
159 | m_Scenes.Remove(scene); | 173 | public virtual void RemoveRegion(Scene scene) {} |
160 | } | ||
161 | 174 | ||
162 | public virtual void RegionLoaded(Scene scene) | 175 | public virtual void RegionLoaded(Scene scene) |
163 | { | 176 | { |
164 | if (!m_Enabled) | 177 | if (!m_Enabled) |
165 | return; | 178 | return; |
179 | |||
180 | m_eqModule = m_scene.RequestModuleInterface<IEventQueue>(); | ||
166 | } | 181 | } |
167 | 182 | ||
168 | #endregion | 183 | #endregion |
@@ -230,6 +245,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
230 | "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", | 245 | "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", |
231 | sp.Name, position, sp.Scene.RegionInfo.RegionName); | 246 | sp.Name, position, sp.Scene.RegionInfo.RegionName); |
232 | 247 | ||
248 | if (!SetInTransit(sp.UUID)) | ||
249 | { | ||
250 | m_log.DebugFormat( | ||
251 | "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", | ||
252 | sp.Name, sp.UUID, position); | ||
253 | |||
254 | return; | ||
255 | } | ||
256 | |||
233 | // Teleport within the same region | 257 | // Teleport within the same region |
234 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) | 258 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) |
235 | { | 259 | { |
@@ -258,6 +282,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
258 | position.Z = newPosZ; | 282 | position.Z = newPosZ; |
259 | } | 283 | } |
260 | 284 | ||
285 | UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | ||
286 | |||
261 | sp.ControllingClient.SendTeleportStart(teleportFlags); | 287 | sp.ControllingClient.SendTeleportStart(teleportFlags); |
262 | 288 | ||
263 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); | 289 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); |
@@ -265,10 +291,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
265 | sp.Velocity = Vector3.Zero; | 291 | sp.Velocity = Vector3.Zero; |
266 | sp.Teleport(position); | 292 | sp.Teleport(position); |
267 | 293 | ||
294 | UpdateInTransit(sp.UUID, AgentTransferState.ReceivedAtDestination); | ||
295 | |||
268 | foreach (SceneObjectGroup grp in sp.GetAttachments()) | 296 | foreach (SceneObjectGroup grp in sp.GetAttachments()) |
269 | { | 297 | { |
270 | sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); | 298 | sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); |
271 | } | 299 | } |
300 | |||
301 | UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | ||
302 | ResetFromTransit(sp.UUID); | ||
272 | } | 303 | } |
273 | 304 | ||
274 | /// <summary> | 305 | /// <summary> |
@@ -286,7 +317,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
286 | { | 317 | { |
287 | uint x = 0, y = 0; | 318 | uint x = 0, y = 0; |
288 | Utils.LongToUInts(regionHandle, out x, out y); | 319 | Utils.LongToUInts(regionHandle, out x, out y); |
289 | GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); | 320 | GridRegion reg = m_scene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); |
290 | 321 | ||
291 | if (reg != null) | 322 | if (reg != null) |
292 | { | 323 | { |
@@ -366,33 +397,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
366 | ScenePresence sp, GridRegion reg, GridRegion finalDestination, | 397 | ScenePresence sp, GridRegion reg, GridRegion finalDestination, |
367 | Vector3 position, Vector3 lookAt, uint teleportFlags) | 398 | Vector3 position, Vector3 lookAt, uint teleportFlags) |
368 | { | 399 | { |
369 | RegionInfo sourceRegion = sp.Scene.RegionInfo; | 400 | // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection |
370 | 401 | // of whether the destination region completes the teleport. | |
371 | if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) | 402 | if (!SetInTransit(sp.UUID)) |
372 | { | 403 | { |
373 | sp.ControllingClient.SendTeleportFailed( | 404 | m_log.DebugFormat( |
374 | string.Format( | 405 | "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", |
375 | "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", | 406 | sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); |
376 | finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY, | ||
377 | sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, | ||
378 | MaxTransferDistance)); | ||
379 | 407 | ||
380 | return; | 408 | return; |
381 | } | 409 | } |
382 | 410 | ||
383 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | ||
384 | |||
385 | if (reg == null || finalDestination == null) | 411 | if (reg == null || finalDestination == null) |
386 | { | 412 | { |
387 | sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); | 413 | sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); |
388 | return; | 414 | ResetFromTransit(sp.UUID); |
389 | } | ||
390 | |||
391 | if (!SetInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. | ||
392 | { | ||
393 | m_log.DebugFormat( | ||
394 | "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", | ||
395 | sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); | ||
396 | 415 | ||
397 | return; | 416 | return; |
398 | } | 417 | } |
@@ -402,6 +421,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
402 | sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName, | 421 | sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName, |
403 | reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); | 422 | reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); |
404 | 423 | ||
424 | RegionInfo sourceRegion = sp.Scene.RegionInfo; | ||
425 | |||
426 | if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) | ||
427 | { | ||
428 | sp.ControllingClient.SendTeleportFailed( | ||
429 | string.Format( | ||
430 | "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", | ||
431 | finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY, | ||
432 | sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, | ||
433 | MaxTransferDistance)); | ||
434 | |||
435 | ResetFromTransit(sp.UUID); | ||
436 | |||
437 | return; | ||
438 | } | ||
439 | |||
405 | uint newRegionX = (uint)(reg.RegionHandle >> 40); | 440 | uint newRegionX = (uint)(reg.RegionHandle >> 40); |
406 | uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); | 441 | uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); |
407 | uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); | 442 | uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); |
@@ -415,15 +450,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
415 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; | 450 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; |
416 | if (endPoint != null && endPoint.Address != null) | 451 | if (endPoint != null && endPoint.Address != null) |
417 | { | 452 | { |
418 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from | 453 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); |
419 | // both regions | 454 | ResetFromTransit(sp.UUID); |
420 | if (sp.ParentID != (uint)0) | ||
421 | sp.StandUp(); | ||
422 | 455 | ||
423 | if (!sp.ValidateAttachments()) | 456 | return; |
424 | m_log.DebugFormat( | 457 | } |
425 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", | 458 | |
426 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); | 459 | if (!sp.ValidateAttachments()) |
460 | m_log.DebugFormat( | ||
461 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", | ||
462 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); | ||
427 | 463 | ||
428 | // if (!sp.ValidateAttachments()) | 464 | // if (!sp.ValidateAttachments()) |
429 | // { | 465 | // { |
@@ -431,212 +467,219 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
431 | // return; | 467 | // return; |
432 | // } | 468 | // } |
433 | 469 | ||
434 | string reason; | 470 | string reason; |
435 | string version; | 471 | string version; |
436 | if (!m_aScene.SimulationService.QueryAccess( | 472 | if (!m_scene.SimulationService.QueryAccess( |
437 | finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) | 473 | finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) |
438 | { | 474 | { |
439 | sp.ControllingClient.SendTeleportFailed(reason); | 475 | sp.ControllingClient.SendTeleportFailed(reason); |
440 | ResetFromTransit(sp.UUID); | 476 | ResetFromTransit(sp.UUID); |
441 | 477 | ||
442 | m_log.DebugFormat( | 478 | m_log.DebugFormat( |
443 | "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", | 479 | "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", |
444 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); | 480 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); |
445 | 481 | ||
446 | return; | 482 | return; |
447 | } | 483 | } |
448 | 484 | ||
449 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); | 485 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); |
450 | 486 | ||
451 | sp.ControllingClient.SendTeleportStart(teleportFlags); | 487 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from |
488 | // both regions | ||
489 | if (sp.ParentID != (uint)0) | ||
490 | sp.StandUp(); | ||
452 | 491 | ||
453 | // the avatar.Close below will clear the child region list. We need this below for (possibly) | 492 | sp.ControllingClient.SendTeleportStart(teleportFlags); |
454 | // closing the child agents, so save it here (we need a copy as it is Clear()-ed). | ||
455 | //List<ulong> childRegions = avatar.KnownRegionHandles; | ||
456 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport | ||
457 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail | ||
458 | // once we reach here... | ||
459 | //avatar.Scene.RemoveCapsHandler(avatar.UUID); | ||
460 | 493 | ||
461 | string capsPath = String.Empty; | 494 | // the avatar.Close below will clear the child region list. We need this below for (possibly) |
495 | // closing the child agents, so save it here (we need a copy as it is Clear()-ed). | ||
496 | //List<ulong> childRegions = avatar.KnownRegionHandles; | ||
497 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport | ||
498 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail | ||
499 | // once we reach here... | ||
500 | //avatar.Scene.RemoveCapsHandler(avatar.UUID); | ||
462 | 501 | ||
463 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | 502 | string capsPath = String.Empty; |
464 | AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); | ||
465 | agentCircuit.startpos = position; | ||
466 | agentCircuit.child = true; | ||
467 | agentCircuit.Appearance = sp.Appearance; | ||
468 | if (currentAgentCircuit != null) | ||
469 | { | ||
470 | agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; | ||
471 | agentCircuit.IPAddress = currentAgentCircuit.IPAddress; | ||
472 | agentCircuit.Viewer = currentAgentCircuit.Viewer; | ||
473 | agentCircuit.Channel = currentAgentCircuit.Channel; | ||
474 | agentCircuit.Mac = currentAgentCircuit.Mac; | ||
475 | agentCircuit.Id0 = currentAgentCircuit.Id0; | ||
476 | } | ||
477 | 503 | ||
478 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 504 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); |
479 | { | 505 | AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); |
480 | // brand new agent, let's create a new caps seed | 506 | agentCircuit.startpos = position; |
481 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | 507 | agentCircuit.child = true; |
482 | } | 508 | agentCircuit.Appearance = sp.Appearance; |
509 | if (currentAgentCircuit != null) | ||
510 | { | ||
511 | agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; | ||
512 | agentCircuit.IPAddress = currentAgentCircuit.IPAddress; | ||
513 | agentCircuit.Viewer = currentAgentCircuit.Viewer; | ||
514 | agentCircuit.Channel = currentAgentCircuit.Channel; | ||
515 | agentCircuit.Mac = currentAgentCircuit.Mac; | ||
516 | agentCircuit.Id0 = currentAgentCircuit.Id0; | ||
517 | } | ||
483 | 518 | ||
484 | // Let's create an agent there if one doesn't exist yet. | 519 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) |
485 | bool logout = false; | 520 | { |
486 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) | 521 | // brand new agent, let's create a new caps seed |
487 | { | 522 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); |
488 | sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); | 523 | } |
489 | ResetFromTransit(sp.UUID); | ||
490 | 524 | ||
491 | m_log.DebugFormat( | 525 | // Let's create an agent there if one doesn't exist yet. |
492 | "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", | 526 | bool logout = false; |
493 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); | 527 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) |
528 | { | ||
529 | sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); | ||
530 | ResetFromTransit(sp.UUID); | ||
494 | 531 | ||
495 | return; | 532 | m_log.DebugFormat( |
496 | } | 533 | "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", |
534 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); | ||
535 | |||
536 | return; | ||
537 | } | ||
497 | 538 | ||
498 | // OK, it got this agent. Let's close some child agents | 539 | // Past this point we have to attempt clean up if the teleport fails, so update transfer state. |
499 | sp.CloseChildAgents(newRegionX, newRegionY); | 540 | UpdateInTransit(sp.UUID, AgentTransferState.Transferring); |
500 | 541 | ||
501 | IClientIPEndpoint ipepClient; | 542 | // OK, it got this agent. Let's close some child agents |
502 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 543 | sp.CloseChildAgents(newRegionX, newRegionY); |
544 | |||
545 | IClientIPEndpoint ipepClient; | ||
546 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
547 | { | ||
548 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | ||
549 | #region IP Translation for NAT | ||
550 | // Uses ipepClient above | ||
551 | if (sp.ClientView.TryGet(out ipepClient)) | ||
503 | { | 552 | { |
504 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | 553 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); |
505 | #region IP Translation for NAT | 554 | } |
506 | // Uses ipepClient above | 555 | #endregion |
507 | if (sp.ClientView.TryGet(out ipepClient)) | 556 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); |
508 | { | ||
509 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | ||
510 | } | ||
511 | #endregion | ||
512 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
513 | 557 | ||
514 | if (eq != null) | 558 | if (m_eqModule != null) |
515 | { | 559 | { |
516 | eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); | 560 | m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); |
517 | 561 | ||
518 | // ES makes the client send a UseCircuitCode message to the destination, | 562 | // ES makes the client send a UseCircuitCode message to the destination, |
519 | // which triggers a bunch of things there. | 563 | // which triggers a bunch of things there. |
520 | // So let's wait | 564 | // So let's wait |
521 | Thread.Sleep(200); | 565 | Thread.Sleep(200); |
522 | 566 | ||
523 | eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); | 567 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); |
524 | 568 | ||
525 | } | ||
526 | else | ||
527 | { | ||
528 | sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); | ||
529 | } | ||
530 | } | 569 | } |
531 | else | 570 | else |
532 | { | 571 | { |
533 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); | 572 | sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); |
534 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
535 | } | 573 | } |
574 | } | ||
575 | else | ||
576 | { | ||
577 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); | ||
578 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
579 | } | ||
536 | 580 | ||
537 | // Let's send a full update of the agent. This is a synchronous call. | 581 | // Let's send a full update of the agent. This is a synchronous call. |
538 | AgentData agent = new AgentData(); | 582 | AgentData agent = new AgentData(); |
539 | sp.CopyTo(agent); | 583 | sp.CopyTo(agent); |
540 | agent.Position = position; | 584 | agent.Position = position; |
541 | SetCallbackURL(agent, sp.Scene.RegionInfo); | 585 | SetCallbackURL(agent, sp.Scene.RegionInfo); |
542 | 586 | ||
543 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); | 587 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); |
544 | 588 | ||
545 | if (!UpdateAgent(reg, finalDestination, agent)) | 589 | if (!UpdateAgent(reg, finalDestination, agent)) |
546 | { | 590 | { |
547 | // Region doesn't take it | 591 | // Region doesn't take it |
548 | m_log.WarnFormat( | 592 | m_log.WarnFormat( |
549 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", | 593 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", |
550 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 594 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); |
551 | 595 | ||
552 | Fail(sp, finalDestination, logout); | 596 | Fail(sp, finalDestination, logout); |
553 | return; | 597 | return; |
554 | } | 598 | } |
555 | 599 | ||
556 | sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); | 600 | sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); |
557 | 601 | ||
558 | m_log.DebugFormat( | 602 | m_log.DebugFormat( |
559 | "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", | 603 | "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", |
560 | capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); | 604 | capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); |
561 | 605 | ||
562 | if (eq != null) | 606 | if (m_eqModule != null) |
563 | { | 607 | { |
564 | eq.TeleportFinishEvent(destinationHandle, 13, endPoint, | 608 | m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); |
565 | 0, teleportFlags, capsPath, sp.UUID); | 609 | } |
566 | } | 610 | else |
567 | else | 611 | { |
568 | { | 612 | sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, |
569 | sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, | 613 | teleportFlags, capsPath); |
570 | teleportFlags, capsPath); | 614 | } |
571 | } | ||
572 | 615 | ||
573 | // Let's set this to true tentatively. This does not trigger OnChildAgent | 616 | // Let's set this to true tentatively. This does not trigger OnChildAgent |
574 | sp.IsChildAgent = true; | 617 | sp.IsChildAgent = true; |
575 | 618 | ||
576 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | 619 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which |
577 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | 620 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation |
578 | // that the client contacted the destination before we close things here. | 621 | // that the client contacted the destination before we close things here. |
579 | if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) | 622 | if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) |
580 | { | 623 | { |
581 | m_log.WarnFormat( | 624 | m_log.WarnFormat( |
582 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", | 625 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", |
583 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 626 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); |
584 | 627 | ||
585 | Fail(sp, finalDestination, logout); | 628 | Fail(sp, finalDestination, logout); |
586 | return; | 629 | return; |
587 | } | 630 | } |
588 | 631 | ||
589 | // For backwards compatibility | 632 | UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); |
590 | if (version == "Unknown" || version == string.Empty) | ||
591 | { | ||
592 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | ||
593 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); | ||
594 | CrossAttachmentsIntoNewRegion(finalDestination, sp, true); | ||
595 | } | ||
596 | 633 | ||
597 | // May need to logout or other cleanup | 634 | // For backwards compatibility |
598 | AgentHasMovedAway(sp, logout); | 635 | if (version == "Unknown" || version == string.Empty) |
636 | { | ||
637 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | ||
638 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); | ||
639 | CrossAttachmentsIntoNewRegion(finalDestination, sp, true); | ||
640 | } | ||
599 | 641 | ||
600 | // Well, this is it. The agent is over there. | 642 | // May need to logout or other cleanup |
601 | KillEntity(sp.Scene, sp.LocalId); | 643 | AgentHasMovedAway(sp, logout); |
602 | 644 | ||
603 | // Now let's make it officially a child agent | 645 | // Well, this is it. The agent is over there. |
604 | sp.MakeChildAgent(); | 646 | KillEntity(sp.Scene, sp.LocalId); |
647 | |||
648 | // Now let's make it officially a child agent | ||
649 | sp.MakeChildAgent(); | ||
605 | 650 | ||
606 | // sp.Scene.CleanDroppedAttachments(); | 651 | // sp.Scene.CleanDroppedAttachments(); |
607 | 652 | ||
608 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 653 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
609 | 654 | ||
610 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 655 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
611 | { | 656 | { |
612 | // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before | 657 | // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before |
613 | // they regard the new region as the current region after receiving the AgentMovementComplete | 658 | // they regard the new region as the current region after receiving the AgentMovementComplete |
614 | // response. If close is sent before then, it will cause the viewer to quit instead. | 659 | // response. If close is sent before then, it will cause the viewer to quit instead. |
615 | // However, if this delay is longer, then a viewer can teleport back to this region and experience | 660 | // |
616 | // a failure because the old ScenePresence has not yet been cleaned up. | 661 | // This sleep can be increased if necessary. However, whilst it's active, |
617 | Thread.Sleep(2000); | 662 | // an agent cannot teleport back to this region if it has teleported away. |
618 | 663 | Thread.Sleep(2000); | |
619 | sp.Close(); | ||
620 | sp.Scene.IncomingCloseAgent(sp.UUID); | ||
621 | } | ||
622 | else | ||
623 | { | ||
624 | // now we have a child agent in this region. | ||
625 | sp.Reset(); | ||
626 | } | ||
627 | 664 | ||
628 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | 665 | sp.Close(); |
629 | if (sp.Scene.NeedSceneCacheClear(sp.UUID)) | 666 | sp.Scene.IncomingCloseAgent(sp.UUID); |
630 | { | ||
631 | m_log.DebugFormat( | ||
632 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", | ||
633 | sp.UUID); | ||
634 | } | ||
635 | } | 667 | } |
636 | else | 668 | else |
637 | { | 669 | { |
638 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); | 670 | // now we have a child agent in this region. |
671 | sp.Reset(); | ||
672 | } | ||
673 | |||
674 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
675 | if (sp.Scene.NeedSceneCacheClear(sp.UUID)) | ||
676 | { | ||
677 | m_log.DebugFormat( | ||
678 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", | ||
679 | sp.UUID); | ||
639 | } | 680 | } |
681 | |||
682 | ResetFromTransit(sp.UUID); | ||
640 | } | 683 | } |
641 | 684 | ||
642 | protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) | 685 | protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) |
@@ -652,7 +695,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
652 | EnableChildAgents(sp); | 695 | EnableChildAgents(sp); |
653 | 696 | ||
654 | // Finally, kill the agent we just created at the destination. | 697 | // Finally, kill the agent we just created at the destination. |
655 | m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID); | 698 | m_scene.SimulationService.CloseAgent(finalDestination, sp.UUID); |
656 | 699 | ||
657 | sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); | 700 | sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); |
658 | } | 701 | } |
@@ -660,7 +703,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
660 | protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) | 703 | protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) |
661 | { | 704 | { |
662 | logout = false; | 705 | logout = false; |
663 | bool success = m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); | 706 | bool success = m_scene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); |
664 | 707 | ||
665 | if (success) | 708 | if (success) |
666 | sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); | 709 | sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); |
@@ -670,7 +713,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
670 | 713 | ||
671 | protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) | 714 | protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) |
672 | { | 715 | { |
673 | return m_aScene.SimulationService.UpdateAgent(finalDestination, agent); | 716 | return m_scene.SimulationService.UpdateAgent(finalDestination, agent); |
674 | } | 717 | } |
675 | 718 | ||
676 | protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) | 719 | protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) |
@@ -722,7 +765,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
722 | return false; | 765 | return false; |
723 | } | 766 | } |
724 | 767 | ||
725 | |||
726 | #endregion | 768 | #endregion |
727 | 769 | ||
728 | #region Landmark Teleport | 770 | #region Landmark Teleport |
@@ -734,7 +776,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
734 | /// <param name="position"></param> | 776 | /// <param name="position"></param> |
735 | public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) | 777 | public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) |
736 | { | 778 | { |
737 | GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); | 779 | GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); |
738 | 780 | ||
739 | if (info == null) | 781 | if (info == null) |
740 | { | 782 | { |
@@ -760,8 +802,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
760 | m_log.DebugFormat( | 802 | m_log.DebugFormat( |
761 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); | 803 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); |
762 | 804 | ||
763 | //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_aScene.PresenceService.GetAgent(client.SessionId); | 805 | //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_scene.PresenceService.GetAgent(client.SessionId); |
764 | GridUserInfo uinfo = m_aScene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); | 806 | GridUserInfo uinfo = m_scene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); |
765 | 807 | ||
766 | if (uinfo != null) | 808 | if (uinfo != null) |
767 | { | 809 | { |
@@ -771,7 +813,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
771 | client.SendTeleportFailed("You don't have a home position set."); | 813 | client.SendTeleportFailed("You don't have a home position set."); |
772 | return false; | 814 | return false; |
773 | } | 815 | } |
774 | GridRegion regionInfo = m_aScene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); | 816 | GridRegion regionInfo = m_scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); |
775 | if (regionInfo == null) | 817 | if (regionInfo == null) |
776 | { | 818 | { |
777 | // can't find the Home region: Tell viewer and abort | 819 | // can't find the Home region: Tell viewer and abort |
@@ -1016,107 +1058,123 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1016 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, | 1058 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, |
1017 | bool isFlying, string version) | 1059 | bool isFlying, string version) |
1018 | { | 1060 | { |
1061 | if (neighbourRegion == null) | ||
1062 | return agent; | ||
1063 | |||
1019 | try | 1064 | try |
1020 | { | 1065 | { |
1066 | SetInTransit(agent.UUID); | ||
1067 | |||
1021 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 1068 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); |
1022 | 1069 | ||
1023 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); | 1070 | m_log.DebugFormat( |
1071 | "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", | ||
1072 | agent.Firstname, agent.Lastname, neighbourx, neighboury, version); | ||
1024 | 1073 | ||
1025 | Scene m_scene = agent.Scene; | 1074 | Scene m_scene = agent.Scene; |
1026 | |||
1027 | if (neighbourRegion != null) | ||
1028 | { | ||
1029 | if (!agent.ValidateAttachments()) | ||
1030 | m_log.DebugFormat( | ||
1031 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", | ||
1032 | agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); | ||
1033 | 1075 | ||
1034 | pos = pos + agent.Velocity; | 1076 | if (!agent.ValidateAttachments()) |
1035 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); | 1077 | m_log.DebugFormat( |
1078 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", | ||
1079 | agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); | ||
1036 | 1080 | ||
1037 | agent.RemoveFromPhysicalScene(); | 1081 | pos = pos + agent.Velocity; |
1038 | SetInTransit(agent.UUID); | 1082 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); |
1039 | 1083 | ||
1040 | AgentData cAgent = new AgentData(); | 1084 | agent.RemoveFromPhysicalScene(); |
1041 | agent.CopyTo(cAgent); | ||
1042 | cAgent.Position = pos; | ||
1043 | if (isFlying) | ||
1044 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | ||
1045 | 1085 | ||
1046 | // We don't need the callback anymnore | 1086 | AgentData cAgent = new AgentData(); |
1047 | cAgent.CallbackURI = String.Empty; | 1087 | agent.CopyTo(cAgent); |
1088 | cAgent.Position = pos; | ||
1089 | if (isFlying) | ||
1090 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | ||
1048 | 1091 | ||
1049 | if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) | 1092 | // We don't need the callback anymnore |
1050 | { | 1093 | cAgent.CallbackURI = String.Empty; |
1051 | // region doesn't take it | ||
1052 | ReInstantiateScripts(agent); | ||
1053 | agent.AddToPhysicalScene(isFlying); | ||
1054 | ResetFromTransit(agent.UUID); | ||
1055 | return agent; | ||
1056 | } | ||
1057 | |||
1058 | //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); | ||
1059 | agent.ControllingClient.RequestClientInfo(); | ||
1060 | |||
1061 | //m_log.Debug("BEFORE CROSS"); | ||
1062 | //Scene.DumpChildrenSeeds(UUID); | ||
1063 | //DumpKnownRegions(); | ||
1064 | string agentcaps; | ||
1065 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | ||
1066 | { | ||
1067 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", | ||
1068 | neighbourRegion.RegionHandle); | ||
1069 | return agent; | ||
1070 | } | ||
1071 | // No turning back | ||
1072 | agent.IsChildAgent = true; | ||
1073 | 1094 | ||
1074 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); | 1095 | // Beyond this point, extra cleanup is needed beyond removing transit state |
1075 | 1096 | UpdateInTransit(agent.UUID, AgentTransferState.Transferring); | |
1076 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); | ||
1077 | 1097 | ||
1078 | IEventQueue eq = agent.Scene.RequestModuleInterface<IEventQueue>(); | 1098 | if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) |
1079 | if (eq != null) | 1099 | { |
1080 | { | 1100 | // region doesn't take it |
1081 | eq.CrossRegion(neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | 1101 | UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
1082 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | ||
1083 | } | ||
1084 | else | ||
1085 | { | ||
1086 | agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, | ||
1087 | capsPath); | ||
1088 | } | ||
1089 | 1102 | ||
1090 | // SUCCESS! | 1103 | ReInstantiateScripts(agent); |
1091 | agent.MakeChildAgent(); | 1104 | agent.AddToPhysicalScene(isFlying); |
1092 | ResetFromTransit(agent.UUID); | 1105 | ResetFromTransit(agent.UUID); |
1093 | 1106 | ||
1094 | // now we have a child agent in this region. Request all interesting data about other (root) agents | 1107 | return agent; |
1095 | agent.SendOtherAgentsAvatarDataToMe(); | 1108 | } |
1096 | agent.SendOtherAgentsAppearanceToMe(); | ||
1097 | 1109 | ||
1098 | // Backwards compatibility. Best effort | 1110 | //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); |
1099 | if (version == "Unknown" || version == string.Empty) | 1111 | agent.ControllingClient.RequestClientInfo(); |
1100 | { | ||
1101 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); | ||
1102 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback | ||
1103 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | ||
1104 | } | ||
1105 | 1112 | ||
1113 | //m_log.Debug("BEFORE CROSS"); | ||
1114 | //Scene.DumpChildrenSeeds(UUID); | ||
1115 | //DumpKnownRegions(); | ||
1116 | string agentcaps; | ||
1117 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | ||
1118 | { | ||
1119 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", | ||
1120 | neighbourRegion.RegionHandle); | ||
1121 | return agent; | ||
1122 | } | ||
1123 | // No turning back | ||
1124 | agent.IsChildAgent = true; | ||
1106 | 1125 | ||
1107 | // Next, let's close the child agent connections that are too far away. | 1126 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); |
1108 | agent.CloseChildAgents(neighbourx, neighboury); | 1127 | |
1109 | 1128 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); | |
1110 | AgentHasMovedAway(agent, false); | 1129 | |
1111 | 1130 | if (m_eqModule != null) | |
1112 | // the user may change their profile information in other region, | 1131 | { |
1113 | // so the userinfo in UserProfileCache is not reliable any more, delete it | 1132 | m_eqModule.CrossRegion( |
1114 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | 1133 | neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, |
1115 | if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | 1134 | capsPath, agent.UUID, agent.ControllingClient.SessionId); |
1116 | { | 1135 | } |
1117 | m_log.DebugFormat( | 1136 | else |
1118 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | 1137 | { |
1119 | } | 1138 | agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, |
1139 | capsPath); | ||
1140 | } | ||
1141 | |||
1142 | // SUCCESS! | ||
1143 | UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); | ||
1144 | |||
1145 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. | ||
1146 | UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); | ||
1147 | |||
1148 | agent.MakeChildAgent(); | ||
1149 | |||
1150 | // FIXME: Possibly this should occur lower down after other commands to close other agents, | ||
1151 | // but not sure yet what the side effects would be. | ||
1152 | ResetFromTransit(agent.UUID); | ||
1153 | |||
1154 | // now we have a child agent in this region. Request all interesting data about other (root) agents | ||
1155 | agent.SendOtherAgentsAvatarDataToMe(); | ||
1156 | agent.SendOtherAgentsAppearanceToMe(); | ||
1157 | |||
1158 | // Backwards compatibility. Best effort | ||
1159 | if (version == "Unknown" || version == string.Empty) | ||
1160 | { | ||
1161 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); | ||
1162 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback | ||
1163 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | ||
1164 | } | ||
1165 | |||
1166 | // Next, let's close the child agent connections that are too far away. | ||
1167 | agent.CloseChildAgents(neighbourx, neighboury); | ||
1168 | |||
1169 | AgentHasMovedAway(agent, false); | ||
1170 | |||
1171 | // the user may change their profile information in other region, | ||
1172 | // so the userinfo in UserProfileCache is not reliable any more, delete it | ||
1173 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
1174 | if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | ||
1175 | { | ||
1176 | m_log.DebugFormat( | ||
1177 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | ||
1120 | } | 1178 | } |
1121 | 1179 | ||
1122 | //m_log.Debug("AFTER CROSS"); | 1180 | //m_log.Debug("AFTER CROSS"); |
@@ -1128,11 +1186,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1128 | m_log.ErrorFormat( | 1186 | m_log.ErrorFormat( |
1129 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", | 1187 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", |
1130 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); | 1188 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); |
1189 | |||
1190 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. | ||
1131 | } | 1191 | } |
1132 | 1192 | ||
1133 | return agent; | 1193 | return agent; |
1134 | } | 1194 | } |
1135 | 1195 | ||
1136 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) | 1196 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) |
1137 | { | 1197 | { |
1138 | CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; | 1198 | CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; |
@@ -1431,8 +1491,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1431 | 1491 | ||
1432 | if (regionAccepted && newAgent) | 1492 | if (regionAccepted && newAgent) |
1433 | { | 1493 | { |
1434 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | 1494 | if (m_eqModule != null) |
1435 | if (eq != null) | ||
1436 | { | 1495 | { |
1437 | #region IP Translation for NAT | 1496 | #region IP Translation for NAT |
1438 | IClientIPEndpoint ipepClient; | 1497 | IClientIPEndpoint ipepClient; |
@@ -1446,8 +1505,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1446 | "and EstablishAgentCommunication with seed cap {4}", | 1505 | "and EstablishAgentCommunication with seed cap {4}", |
1447 | scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); | 1506 | scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); |
1448 | 1507 | ||
1449 | eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); | 1508 | m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); |
1450 | eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); | 1509 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); |
1451 | } | 1510 | } |
1452 | else | 1511 | else |
1453 | { | 1512 | { |
@@ -1573,8 +1632,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1573 | #region Agent Arrived | 1632 | #region Agent Arrived |
1574 | public void AgentArrivedAtDestination(UUID id) | 1633 | public void AgentArrivedAtDestination(UUID id) |
1575 | { | 1634 | { |
1576 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Agent {0} released", id); | 1635 | lock (m_agentsInTransit) |
1577 | ResetFromTransit(id); | 1636 | { |
1637 | if (!m_agentsInTransit.ContainsKey(id)) | ||
1638 | { | ||
1639 | m_log.WarnFormat( | ||
1640 | "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but no teleport request is active", | ||
1641 | m_scene.RegionInfo.RegionName, id); | ||
1642 | |||
1643 | return; | ||
1644 | } | ||
1645 | |||
1646 | AgentTransferState currentState = m_agentsInTransit[id]; | ||
1647 | |||
1648 | if (currentState == AgentTransferState.ReceivedAtDestination) | ||
1649 | { | ||
1650 | // An anomoly but don't make this an outright failure - destination region could be overzealous in sending notification. | ||
1651 | m_log.WarnFormat( | ||
1652 | "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but notification has already previously been received", | ||
1653 | m_scene.RegionInfo.RegionName, id); | ||
1654 | } | ||
1655 | else if (currentState != AgentTransferState.Transferring) | ||
1656 | { | ||
1657 | m_log.ErrorFormat( | ||
1658 | "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but agent is in transfer state {2}", | ||
1659 | m_scene.RegionInfo.RegionName, id, currentState); | ||
1660 | |||
1661 | return; | ||
1662 | } | ||
1663 | |||
1664 | m_agentsInTransit[id] = AgentTransferState.ReceivedAtDestination; | ||
1665 | } | ||
1578 | } | 1666 | } |
1579 | 1667 | ||
1580 | #endregion | 1668 | #endregion |
@@ -1845,8 +1933,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1845 | //// And the new channel... | 1933 | //// And the new channel... |
1846 | //if (m_interregionCommsOut != null) | 1934 | //if (m_interregionCommsOut != null) |
1847 | // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true); | 1935 | // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true); |
1848 | if (m_aScene.SimulationService != null) | 1936 | if (m_scene.SimulationService != null) |
1849 | successYN = m_aScene.SimulationService.CreateObject(destination, newPosition, grp, true); | 1937 | successYN = m_scene.SimulationService.CreateObject(destination, newPosition, grp, true); |
1850 | 1938 | ||
1851 | if (successYN) | 1939 | if (successYN) |
1852 | { | 1940 | { |
@@ -1925,10 +2013,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1925 | 2013 | ||
1926 | #region Misc | 2014 | #region Misc |
1927 | 2015 | ||
1928 | protected bool WaitForCallback(UUID id) | 2016 | private bool WaitForCallback(UUID id) |
1929 | { | 2017 | { |
2018 | lock (m_agentsInTransit) | ||
2019 | { | ||
2020 | if (!IsInTransit(id)) | ||
2021 | throw new Exception( | ||
2022 | string.Format( | ||
2023 | "Asked to wait for destination callback for agent with ID {0} but it is not in transit")); | ||
2024 | |||
2025 | AgentTransferState currentState = m_agentsInTransit[id]; | ||
2026 | |||
2027 | if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) | ||
2028 | throw new Exception( | ||
2029 | string.Format( | ||
2030 | "Asked to wait for destination callback for agent with ID {0} but it is in state {1}", | ||
2031 | currentState)); | ||
2032 | } | ||
2033 | |||
1930 | int count = 200; | 2034 | int count = 200; |
1931 | while (m_agentsInTransit.Contains(id) && count-- > 0) | 2035 | |
2036 | // There should be no race condition here since no other code should be removing the agent transfer or | ||
2037 | // changing the state to another other than Transferring => ReceivedAtDestination. | ||
2038 | while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0) | ||
1932 | { | 2039 | { |
1933 | // m_log.Debug(" >>> Waiting... " + count); | 2040 | // m_log.Debug(" >>> Waiting... " + count); |
1934 | Thread.Sleep(100); | 2041 | Thread.Sleep(100); |
@@ -1938,17 +2045,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1938 | } | 2045 | } |
1939 | 2046 | ||
1940 | /// <summary> | 2047 | /// <summary> |
1941 | /// Set that an agent is in the process of being teleported. | 2048 | /// Set that an agent is in transit. |
1942 | /// </summary> | 2049 | /// </summary> |
1943 | /// <param name='id'>The ID of the agent being teleported</param> | 2050 | /// <param name='id'>The ID of the agent being teleported</param> |
1944 | /// <returns>true if the agent was not already in transit, false if it was</returns> | 2051 | /// <returns>true if the agent was not already in transit, false if it was</returns> |
1945 | protected bool SetInTransit(UUID id) | 2052 | private bool SetInTransit(UUID id) |
1946 | { | 2053 | { |
1947 | lock (m_agentsInTransit) | 2054 | lock (m_agentsInTransit) |
1948 | { | 2055 | { |
1949 | if (!m_agentsInTransit.Contains(id)) | 2056 | if (!m_agentsInTransit.ContainsKey(id)) |
1950 | { | 2057 | { |
1951 | m_agentsInTransit.Add(id); | 2058 | m_agentsInTransit[id] = AgentTransferState.Preparing; |
1952 | return true; | 2059 | return true; |
1953 | } | 2060 | } |
1954 | } | 2061 | } |
@@ -1957,34 +2064,87 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1957 | } | 2064 | } |
1958 | 2065 | ||
1959 | /// <summary> | 2066 | /// <summary> |
1960 | /// Show whether the given agent is being teleported. | 2067 | /// Updates the state of an agent that is already in transit. |
1961 | /// </summary> | 2068 | /// </summary> |
1962 | /// <returns>true if the agent is in the process of being teleported, false otherwise.</returns> | 2069 | /// <param name='id'></param> |
1963 | /// <param name='id'>The agent ID</para></param> | 2070 | /// <param name='newState'></param> |
1964 | protected bool IsInTransit(UUID id) | 2071 | /// <returns></returns> |
2072 | /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> | ||
2073 | private void UpdateInTransit(UUID id, AgentTransferState newState) | ||
2074 | { | ||
2075 | lock (m_agentsInTransit) | ||
2076 | { | ||
2077 | // Illegal to try and update an agent that's not actually in transit. | ||
2078 | if (!m_agentsInTransit.ContainsKey(id)) | ||
2079 | throw new Exception(string.Format("Agent with ID {0} is not registered as in transit", id)); | ||
2080 | |||
2081 | AgentTransferState oldState = m_agentsInTransit[id]; | ||
2082 | |||
2083 | bool transitionOkay = false; | ||
2084 | |||
2085 | if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) | ||
2086 | transitionOkay = true; | ||
2087 | else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) | ||
2088 | transitionOkay = true; | ||
2089 | else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) | ||
2090 | transitionOkay = true; | ||
2091 | |||
2092 | if (transitionOkay) | ||
2093 | m_agentsInTransit[id] = newState; | ||
2094 | else | ||
2095 | throw new Exception( | ||
2096 | string.Format( | ||
2097 | "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2}", | ||
2098 | id, oldState, newState)); | ||
2099 | } | ||
2100 | } | ||
2101 | |||
2102 | public bool IsInTransit(UUID id) | ||
1965 | { | 2103 | { |
1966 | lock (m_agentsInTransit) | 2104 | lock (m_agentsInTransit) |
1967 | return m_agentsInTransit.Contains(id); | 2105 | return m_agentsInTransit.ContainsKey(id); |
1968 | } | 2106 | } |
1969 | 2107 | ||
1970 | /// <summary> | 2108 | /// <summary> |
1971 | /// Set that an agent is no longer being teleported. | 2109 | /// Removes an agent from the transit state machine. |
1972 | /// </summary> | 2110 | /// </summary> |
1973 | /// <returns></returns> | 2111 | /// <param name='id'></param> |
1974 | /// <param name='id'> | 2112 | /// <returns>true if the agent was flagged as being teleported when this method was called, false otherwise</returns> |
1975 | /// true if the agent was flagged as being teleported when this method was called, false otherwise | 2113 | private bool ResetFromTransit(UUID id) |
1976 | /// </param> | ||
1977 | protected bool ResetFromTransit(UUID id) | ||
1978 | { | 2114 | { |
1979 | lock (m_agentsInTransit) | 2115 | lock (m_agentsInTransit) |
1980 | { | 2116 | { |
1981 | if (m_agentsInTransit.Contains(id)) | 2117 | if (m_agentsInTransit.ContainsKey(id)) |
1982 | { | 2118 | { |
2119 | AgentTransferState state = m_agentsInTransit[id]; | ||
2120 | |||
2121 | if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination) | ||
2122 | { | ||
2123 | // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed | ||
2124 | // to be handled properly - ResetFromTransit() could be invoked at any step along the process | ||
2125 | m_log.WarnFormat( | ||
2126 | "[ENTITY TRANSFER MODULE]: Agent with ID should not exit directly from state {1}, should go to {2} state first", | ||
2127 | state, AgentTransferState.CleaningUp); | ||
2128 | |||
2129 | // throw new Exception( | ||
2130 | // "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first", | ||
2131 | // state, AgentTransferState.CleaningUp); | ||
2132 | } | ||
2133 | |||
1983 | m_agentsInTransit.Remove(id); | 2134 | m_agentsInTransit.Remove(id); |
2135 | |||
2136 | m_log.DebugFormat( | ||
2137 | "[ENTITY TRANSFER MODULE]: Agent {0} cleared from transit in {1}", | ||
2138 | id, m_scene.RegionInfo.RegionName); | ||
2139 | |||
1984 | return true; | 2140 | return true; |
1985 | } | 2141 | } |
1986 | } | 2142 | } |
1987 | 2143 | ||
2144 | m_log.WarnFormat( | ||
2145 | "[ENTITY TRANSFER MODULE]: Agent {0} requested to clear from transit in {1} but was already cleared.", | ||
2146 | id, m_scene.RegionInfo.RegionName); | ||
2147 | |||
1988 | return false; | 2148 | return false; |
1989 | } | 2149 | } |
1990 | 2150 | ||
@@ -2015,4 +2175,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2015 | #endregion | 2175 | #endregion |
2016 | 2176 | ||
2017 | } | 2177 | } |
2018 | } \ No newline at end of file | 2178 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 6e27299..44ea2b1 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -45,11 +45,11 @@ using Nini.Config; | |||
45 | 45 | ||
46 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | 46 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer |
47 | { | 47 | { |
48 | public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule | 48 | public class HGEntityTransferModule |
49 | : EntityTransferModule, INonSharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule | ||
49 | { | 50 | { |
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | 52 | ||
52 | private bool m_Initialized = false; | ||
53 | private int m_levelHGTeleport = 0; | 53 | private int m_levelHGTeleport = 0; |
54 | 54 | ||
55 | private GatekeeperServiceConnector m_GatekeeperConnector; | 55 | private GatekeeperServiceConnector m_GatekeeperConnector; |
@@ -64,6 +64,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
64 | public override void Initialise(IConfigSource source) | 64 | public override void Initialise(IConfigSource source) |
65 | { | 65 | { |
66 | IConfig moduleConfig = source.Configs["Modules"]; | 66 | IConfig moduleConfig = source.Configs["Modules"]; |
67 | |||
67 | if (moduleConfig != null) | 68 | if (moduleConfig != null) |
68 | { | 69 | { |
69 | string name = moduleConfig.GetString("EntityTransferModule", ""); | 70 | string name = moduleConfig.GetString("EntityTransferModule", ""); |
@@ -82,10 +83,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
82 | public override void AddRegion(Scene scene) | 83 | public override void AddRegion(Scene scene) |
83 | { | 84 | { |
84 | base.AddRegion(scene); | 85 | base.AddRegion(scene); |
86 | |||
85 | if (m_Enabled) | 87 | if (m_Enabled) |
86 | { | ||
87 | scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); | 88 | scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); |
88 | } | ||
89 | } | 89 | } |
90 | 90 | ||
91 | protected override void OnNewClient(IClientAPI client) | 91 | protected override void OnNewClient(IClientAPI client) |
@@ -98,33 +98,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
98 | public override void RegionLoaded(Scene scene) | 98 | public override void RegionLoaded(Scene scene) |
99 | { | 99 | { |
100 | base.RegionLoaded(scene); | 100 | base.RegionLoaded(scene); |
101 | if (m_Enabled) | ||
102 | if (!m_Initialized) | ||
103 | { | ||
104 | m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); | ||
105 | m_Initialized = true; | ||
106 | |||
107 | } | ||
108 | 101 | ||
102 | if (m_Enabled) | ||
103 | m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); | ||
109 | } | 104 | } |
105 | |||
110 | public override void RemoveRegion(Scene scene) | 106 | public override void RemoveRegion(Scene scene) |
111 | { | 107 | { |
112 | base.AddRegion(scene); | 108 | base.AddRegion(scene); |
109 | |||
113 | if (m_Enabled) | 110 | if (m_Enabled) |
114 | { | ||
115 | scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); | 111 | scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); |
116 | } | ||
117 | } | 112 | } |
118 | 113 | ||
119 | |||
120 | #endregion | 114 | #endregion |
121 | 115 | ||
122 | #region HG overrides of IEntiryTransferModule | 116 | #region HG overrides of IEntiryTransferModule |
123 | 117 | ||
124 | protected override GridRegion GetFinalDestination(GridRegion region) | 118 | protected override GridRegion GetFinalDestination(GridRegion region) |
125 | { | 119 | { |
126 | int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID); | 120 | int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, region.RegionID); |
127 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); | 121 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); |
122 | |||
128 | if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) | 123 | if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) |
129 | { | 124 | { |
130 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); | 125 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); |
@@ -135,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
135 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion to Gatekeeper {0} failed", region.ServerURI); | 130 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion to Gatekeeper {0} failed", region.ServerURI); |
136 | return real_destination; | 131 | return real_destination; |
137 | } | 132 | } |
133 | |||
138 | return region; | 134 | return region; |
139 | } | 135 | } |
140 | 136 | ||
@@ -143,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
143 | if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 139 | if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
144 | return true; | 140 | return true; |
145 | 141 | ||
146 | int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); | 142 | int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID); |
147 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) | 143 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) |
148 | return true; | 144 | return true; |
149 | 145 | ||
@@ -156,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
156 | if (logout) | 152 | if (logout) |
157 | { | 153 | { |
158 | // Log them out of this grid | 154 | // Log them out of this grid |
159 | m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); | 155 | m_scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); |
160 | } | 156 | } |
161 | } | 157 | } |
162 | 158 | ||
@@ -165,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
165 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); | 161 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); |
166 | reason = string.Empty; | 162 | reason = string.Empty; |
167 | logout = false; | 163 | logout = false; |
168 | int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); | 164 | int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID); |
169 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) | 165 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) |
170 | { | 166 | { |
171 | // this user is going to another grid | 167 | // this user is going to another grid |
@@ -210,7 +206,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
210 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); | 206 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); |
211 | 207 | ||
212 | // Let's find out if this is a foreign user or a local user | 208 | // Let's find out if this is a foreign user or a local user |
213 | IUserManagement uMan = m_aScene.RequestModuleInterface<IUserManagement>(); | 209 | IUserManagement uMan = m_scene.RequestModuleInterface<IUserManagement>(); |
214 | if (uMan != null && uMan.IsLocalGridUser(id)) | 210 | if (uMan != null && uMan.IsLocalGridUser(id)) |
215 | { | 211 | { |
216 | // local grid user | 212 | // local grid user |
@@ -265,19 +261,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
265 | { | 261 | { |
266 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", | 262 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", |
267 | (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); | 263 | (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); |
264 | |||
268 | if (lm.Gatekeeper == string.Empty) | 265 | if (lm.Gatekeeper == string.Empty) |
269 | { | 266 | { |
270 | base.RequestTeleportLandmark(remoteClient, lm); | 267 | base.RequestTeleportLandmark(remoteClient, lm); |
271 | return; | 268 | return; |
272 | } | 269 | } |
273 | 270 | ||
274 | GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); | 271 | GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); |
275 | 272 | ||
276 | // Local region? | 273 | // Local region? |
277 | if (info != null) | 274 | if (info != null) |
278 | { | 275 | { |
279 | ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, | 276 | ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, |
280 | Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); | 277 | Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); |
278 | |||
281 | return; | 279 | return; |
282 | } | 280 | } |
283 | else | 281 | else |
@@ -288,6 +286,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
288 | GridRegion gatekeeper = new GridRegion(); | 286 | GridRegion gatekeeper = new GridRegion(); |
289 | gatekeeper.ServerURI = lm.Gatekeeper; | 287 | gatekeeper.ServerURI = lm.Gatekeeper; |
290 | GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID)); | 288 | GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID)); |
289 | |||
291 | if (finalDestination != null) | 290 | if (finalDestination != null) |
292 | { | 291 | { |
293 | ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId); | 292 | ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId); |
@@ -317,8 +316,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
317 | IUserAgentService security = new UserAgentServiceConnector(url); | 316 | IUserAgentService security = new UserAgentServiceConnector(url); |
318 | return security.VerifyClient(aCircuit.SessionID, token); | 317 | return security.VerifyClient(aCircuit.SessionID, token); |
319 | } | 318 | } |
320 | else | 319 | else |
321 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", aCircuit.firstname, aCircuit.lastname); | 320 | { |
321 | m_log.DebugFormat( | ||
322 | "[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", | ||
323 | aCircuit.firstname, aCircuit.lastname); | ||
324 | } | ||
322 | 325 | ||
323 | return false; | 326 | return false; |
324 | } | 327 | } |
@@ -335,8 +338,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
335 | } | 338 | } |
336 | 339 | ||
337 | // Let's find out if this is a foreign user or a local user | 340 | // Let's find out if this is a foreign user or a local user |
338 | IUserManagement uMan = m_aScene.RequestModuleInterface<IUserManagement>(); | 341 | IUserManagement uMan = m_scene.RequestModuleInterface<IUserManagement>(); |
339 | UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, obj.AgentId); | 342 | // UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, obj.AgentId); |
340 | if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) | 343 | if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) |
341 | { | 344 | { |
342 | // local grid user | 345 | // local grid user |
@@ -359,7 +362,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
359 | 362 | ||
360 | #endregion | 363 | #endregion |
361 | 364 | ||
362 | |||
363 | private GridRegion MakeRegion(AgentCircuitData aCircuit) | 365 | private GridRegion MakeRegion(AgentCircuitData aCircuit) |
364 | { | 366 | { |
365 | GridRegion region = new GridRegion(); | 367 | GridRegion region = new GridRegion(); |
@@ -376,6 +378,5 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
376 | region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); | 378 | region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); |
377 | return region; | 379 | return region; |
378 | } | 380 | } |
379 | |||
380 | } | 381 | } |
381 | } | 382 | } \ No newline at end of file |