diff options
author | Diva Canto | 2010-01-17 11:33:47 -0800 |
---|---|---|
committer | Diva Canto | 2010-01-17 11:33:47 -0800 |
commit | f276ba57bf5bd732fbc6a255213c9bb7f5f5f148 (patch) | |
tree | 65c49c571c4012b195a309866b8bf6ed2885f9ef /OpenSim/Region/CoreModules/Framework | |
parent | Copyright notices. (diff) | |
download | opensim-SC_OLD-f276ba57bf5bd732fbc6a255213c9bb7f5f5f148.zip opensim-SC_OLD-f276ba57bf5bd732fbc6a255213c9bb7f5f5f148.tar.gz opensim-SC_OLD-f276ba57bf5bd732fbc6a255213c9bb7f5f5f148.tar.bz2 opensim-SC_OLD-f276ba57bf5bd732fbc6a255213c9bb7f5f5f148.tar.xz |
HG agent transfers are starting to work. Gatekeeper handlers are missing.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 469 |
1 files changed, 240 insertions, 229 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 827dafe..d0171fe 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
61 | get { return null; } | 61 | get { return null; } |
62 | } | 62 | } |
63 | 63 | ||
64 | public string Name | 64 | public virtual string Name |
65 | { | 65 | { |
66 | get { return "BasicEntityTransferModule"; } | 66 | get { return "BasicEntityTransferModule"; } |
67 | } | 67 | } |
@@ -76,7 +76,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
76 | { | 76 | { |
77 | m_agentsInTransit = new List<UUID>(); | 77 | m_agentsInTransit = new List<UUID>(); |
78 | m_Enabled = true; | 78 | m_Enabled = true; |
79 | m_log.InfoFormat("[ENTITY TRANSFER MODULE]: {0} nabled.", Name); | 79 | m_log.InfoFormat("[ENTITY TRANSFER MODULE]: {0} enabled.", Name); |
80 | } | 80 | } |
81 | } | 81 | } |
82 | } | 82 | } |
@@ -135,296 +135,312 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
135 | // Reset animations; the viewer does that in teleports. | 135 | // Reset animations; the viewer does that in teleports. |
136 | sp.Animator.ResetAnimations(); | 136 | sp.Animator.ResetAnimations(); |
137 | 137 | ||
138 | if (regionHandle == sp.Scene.RegionInfo.RegionHandle) | 138 | try |
139 | { | 139 | { |
140 | m_log.DebugFormat( | 140 | if (regionHandle == sp.Scene.RegionInfo.RegionHandle) |
141 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", | ||
142 | position, sp.Scene.RegionInfo.RegionName); | ||
143 | |||
144 | // Teleport within the same region | ||
145 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) | ||
146 | { | ||
147 | Vector3 emergencyPos = new Vector3(128, 128, 128); | ||
148 | |||
149 | m_log.WarnFormat( | ||
150 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", | ||
151 | position, sp.Name, sp.UUID, emergencyPos); | ||
152 | position = emergencyPos; | ||
153 | } | ||
154 | |||
155 | // TODO: Get proper AVG Height | ||
156 | float localAVHeight = 1.56f; | ||
157 | float posZLimit = 22; | ||
158 | |||
159 | // TODO: Check other Scene HeightField | ||
160 | if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) | ||
161 | { | 141 | { |
162 | posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; | 142 | m_log.DebugFormat( |
163 | } | 143 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", |
164 | 144 | position, sp.Scene.RegionInfo.RegionName); | |
165 | float newPosZ = posZLimit + localAVHeight; | ||
166 | if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) | ||
167 | { | ||
168 | position.Z = newPosZ; | ||
169 | } | ||
170 | 145 | ||
171 | // Only send this if the event queue is null | 146 | // Teleport within the same region |
172 | if (eq == null) | 147 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) |
173 | sp.ControllingClient.SendTeleportLocationStart(); | 148 | { |
149 | Vector3 emergencyPos = new Vector3(128, 128, 128); | ||
174 | 150 | ||
175 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); | 151 | m_log.WarnFormat( |
176 | sp.Teleport(position); | 152 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", |
177 | } | 153 | position, sp.Name, sp.UUID, emergencyPos); |
178 | else | 154 | position = emergencyPos; |
179 | { | 155 | } |
180 | uint x = 0, y = 0; | ||
181 | Utils.LongToUInts(regionHandle, out x, out y); | ||
182 | GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); | ||
183 | 156 | ||
184 | if (reg != null) | 157 | // TODO: Get proper AVG Height |
185 | { | 158 | float localAVHeight = 1.56f; |
186 | m_log.DebugFormat( | 159 | float posZLimit = 22; |
187 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", | ||
188 | position, reg.RegionName); | ||
189 | 160 | ||
190 | uint newRegionX = (uint)(reg.RegionHandle >> 40); | 161 | // TODO: Check other Scene HeightField |
191 | uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); | 162 | if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) |
192 | uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); | 163 | { |
193 | uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); | 164 | posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; |
165 | } | ||
194 | 166 | ||
195 | ulong destinationHandle = GetRegionHandle(reg); | 167 | float newPosZ = posZLimit + localAVHeight; |
196 | GridRegion finalDestination = GetFinalDestination(reg); | 168 | if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) |
169 | { | ||
170 | position.Z = newPosZ; | ||
171 | } | ||
197 | 172 | ||
173 | // Only send this if the event queue is null | ||
198 | if (eq == null) | 174 | if (eq == null) |
199 | sp.ControllingClient.SendTeleportLocationStart(); | 175 | sp.ControllingClient.SendTeleportLocationStart(); |
200 | 176 | ||
201 | // Let's do DNS resolution only once in this process, please! | 177 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); |
202 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, | 178 | sp.Teleport(position); |
203 | // it's actually doing a lot of work. | 179 | } |
204 | IPEndPoint endPoint = reg.ExternalEndPoint; | 180 | else |
205 | if (endPoint.Address == null) | 181 | { |
206 | { | 182 | uint x = 0, y = 0; |
207 | // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. | 183 | Utils.LongToUInts(regionHandle, out x, out y); |
208 | destRegionUp = false; | 184 | GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); |
209 | } | ||
210 | 185 | ||
211 | if (destRegionUp) | 186 | if (reg != null) |
212 | { | 187 | { |
213 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from | 188 | m_log.DebugFormat( |
214 | // both regions | 189 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", |
215 | if (sp.ParentID != (uint)0) | 190 | position, reg.RegionName); |
216 | sp.StandUp(); | 191 | |
192 | uint newRegionX = (uint)(reg.RegionHandle >> 40); | ||
193 | uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); | ||
194 | uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); | ||
195 | uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); | ||
217 | 196 | ||
218 | if (!sp.ValidateAttachments()) | 197 | GridRegion finalDestination = GetFinalDestination(reg); |
198 | if (finalDestination == null) | ||
219 | { | 199 | { |
220 | sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); | 200 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport agent."); |
201 | sp.ControllingClient.SendTeleportFailed("Problem at destination"); | ||
221 | return; | 202 | return; |
222 | } | 203 | } |
204 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}", finalDestination.RegionLocX, finalDestination.RegionLocY, finalDestination.RegionID); | ||
205 | ulong destinationHandle = finalDestination.RegionHandle; | ||
223 | 206 | ||
224 | // the avatar.Close below will clear the child region list. We need this below for (possibly) | 207 | if (eq == null) |
225 | // closing the child agents, so save it here (we need a copy as it is Clear()-ed). | 208 | sp.ControllingClient.SendTeleportLocationStart(); |
226 | //List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList()); | 209 | |
227 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport | 210 | // Let's do DNS resolution only once in this process, please! |
228 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail | 211 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, |
229 | // once we reach here... | 212 | // it's actually doing a lot of work. |
230 | //avatar.Scene.RemoveCapsHandler(avatar.UUID); | 213 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; |
231 | 214 | if (endPoint.Address == null) | |
232 | string capsPath = String.Empty; | ||
233 | AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); | ||
234 | agentCircuit.BaseFolder = UUID.Zero; | ||
235 | agentCircuit.InventoryFolder = UUID.Zero; | ||
236 | agentCircuit.startpos = position; | ||
237 | agentCircuit.child = true; | ||
238 | agentCircuit.Appearance = sp.Appearance; | ||
239 | |||
240 | if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
241 | { | 215 | { |
242 | // brand new agent, let's create a new caps seed | 216 | // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. |
243 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | 217 | destRegionUp = false; |
244 | } | 218 | } |
245 | 219 | ||
246 | string reason = String.Empty; | 220 | if (destRegionUp) |
247 | |||
248 | // Let's create an agent there if one doesn't exist yet. | ||
249 | if (!m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason)) | ||
250 | { | 221 | { |
251 | sp.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", | 222 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from |
252 | reason)); | 223 | // both regions |
253 | return; | 224 | if (sp.ParentID != (uint)0) |
254 | } | 225 | sp.StandUp(); |
255 | 226 | ||
256 | // OK, it got this agent. Let's close some child agents | 227 | if (!sp.ValidateAttachments()) |
257 | sp.CloseChildAgents(newRegionX, newRegionY); | 228 | { |
229 | sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); | ||
230 | return; | ||
231 | } | ||
258 | 232 | ||
259 | if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) | 233 | // the avatar.Close below will clear the child region list. We need this below for (possibly) |
260 | { | 234 | // closing the child agents, so save it here (we need a copy as it is Clear()-ed). |
261 | #region IP Translation for NAT | 235 | //List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList()); |
262 | IClientIPEndpoint ipepClient; | 236 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport |
263 | if (sp.ClientView.TryGet(out ipepClient)) | 237 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail |
238 | // once we reach here... | ||
239 | //avatar.Scene.RemoveCapsHandler(avatar.UUID); | ||
240 | |||
241 | string capsPath = String.Empty; | ||
242 | AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); | ||
243 | agentCircuit.BaseFolder = UUID.Zero; | ||
244 | agentCircuit.InventoryFolder = UUID.Zero; | ||
245 | agentCircuit.startpos = position; | ||
246 | agentCircuit.child = true; | ||
247 | agentCircuit.Appearance = sp.Appearance; | ||
248 | |||
249 | if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
264 | { | 250 | { |
265 | capsPath | 251 | // brand new agent, let's create a new caps seed |
266 | = "http://" | 252 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); |
267 | + NetworkUtil.GetHostFor(ipepClient.EndPoint, reg.ExternalHostName) | ||
268 | + ":" | ||
269 | + reg.HttpPort | ||
270 | + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
271 | } | 253 | } |
272 | else | 254 | |
255 | string reason = String.Empty; | ||
256 | |||
257 | // Let's create an agent there if one doesn't exist yet. | ||
258 | if (!m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason)) | ||
273 | { | 259 | { |
274 | capsPath | 260 | sp.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", |
275 | = "http://" | 261 | reason)); |
276 | + reg.ExternalHostName | 262 | return; |
277 | + ":" | ||
278 | + reg.HttpPort | ||
279 | + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
280 | } | 263 | } |
281 | #endregion | ||
282 | 264 | ||
283 | if (eq != null) | 265 | // OK, it got this agent. Let's close some child agents |
266 | sp.CloseChildAgents(newRegionX, newRegionY); | ||
267 | |||
268 | if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
284 | { | 269 | { |
285 | #region IP Translation for NAT | 270 | #region IP Translation for NAT |
286 | // Uses ipepClient above | 271 | IClientIPEndpoint ipepClient; |
287 | if (sp.ClientView.TryGet(out ipepClient)) | 272 | if (sp.ClientView.TryGet(out ipepClient)) |
288 | { | 273 | { |
289 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | 274 | capsPath |
275 | = "http://" | ||
276 | + NetworkUtil.GetHostFor(ipepClient.EndPoint, finalDestination.ExternalHostName) | ||
277 | + ":" | ||
278 | + finalDestination.HttpPort | ||
279 | + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
280 | } | ||
281 | else | ||
282 | { | ||
283 | capsPath | ||
284 | = "http://" | ||
285 | + finalDestination.ExternalHostName | ||
286 | + ":" | ||
287 | + finalDestination.HttpPort | ||
288 | + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
290 | } | 289 | } |
291 | #endregion | 290 | #endregion |
292 | 291 | ||
293 | eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); | 292 | if (eq != null) |
293 | { | ||
294 | #region IP Translation for NAT | ||
295 | // Uses ipepClient above | ||
296 | if (sp.ClientView.TryGet(out ipepClient)) | ||
297 | { | ||
298 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | ||
299 | } | ||
300 | #endregion | ||
301 | |||
302 | eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); | ||
294 | 303 | ||
295 | // ES makes the client send a UseCircuitCode message to the destination, | 304 | // ES makes the client send a UseCircuitCode message to the destination, |
296 | // which triggers a bunch of things there. | 305 | // which triggers a bunch of things there. |
297 | // So let's wait | 306 | // So let's wait |
298 | Thread.Sleep(2000); | 307 | Thread.Sleep(2000); |
299 | 308 | ||
300 | eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); | 309 | eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); |
301 | 310 | ||
311 | } | ||
312 | else | ||
313 | { | ||
314 | sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); | ||
315 | } | ||
302 | } | 316 | } |
303 | else | 317 | else |
304 | { | 318 | { |
305 | sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); | 319 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); |
320 | capsPath = "http://" + finalDestination.ExternalHostName + ":" + finalDestination.HttpPort | ||
321 | + "/CAPS/" + agentCircuit.CapsPath + "0000/"; | ||
306 | } | 322 | } |
307 | } | ||
308 | else | ||
309 | { | ||
310 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); | ||
311 | capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort | ||
312 | + "/CAPS/" + agentCircuit.CapsPath + "0000/"; | ||
313 | } | ||
314 | |||
315 | // Expect avatar crossing is a heavy-duty function at the destination. | ||
316 | // That is where MakeRoot is called, which fetches appearance and inventory. | ||
317 | // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. | ||
318 | //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, | ||
319 | // position, false); | ||
320 | |||
321 | //{ | ||
322 | // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); | ||
323 | // // We should close that agent we just created over at destination... | ||
324 | // List<ulong> lst = new List<ulong>(); | ||
325 | // lst.Add(reg.RegionHandle); | ||
326 | // SendCloseChildAgentAsync(avatar.UUID, lst); | ||
327 | // return; | ||
328 | //} | ||
329 | 323 | ||
330 | SetInTransit(sp.UUID); | 324 | // Expect avatar crossing is a heavy-duty function at the destination. |
325 | // That is where MakeRoot is called, which fetches appearance and inventory. | ||
326 | // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. | ||
327 | //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, | ||
328 | // position, false); | ||
329 | |||
330 | //{ | ||
331 | // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); | ||
332 | // // We should close that agent we just created over at destination... | ||
333 | // List<ulong> lst = new List<ulong>(); | ||
334 | // lst.Add(reg.RegionHandle); | ||
335 | // SendCloseChildAgentAsync(avatar.UUID, lst); | ||
336 | // return; | ||
337 | //} | ||
338 | |||
339 | SetInTransit(sp.UUID); | ||
340 | |||
341 | // Let's send a full update of the agent. This is a synchronous call. | ||
342 | AgentData agent = new AgentData(); | ||
343 | sp.CopyTo(agent); | ||
344 | agent.Position = position; | ||
345 | agent.CallbackURI = "http://" + sp.Scene.RegionInfo.ExternalHostName + ":" + sp.Scene.RegionInfo.HttpPort + | ||
346 | "/agent/" + sp.UUID.ToString() + "/" + sp.Scene.RegionInfo.RegionID.ToString() + "/release/"; | ||
347 | |||
348 | // Straight to the region. Safe. | ||
349 | m_aScene.SimulationService.UpdateAgent(reg, agent); | ||
331 | 350 | ||
332 | // Let's send a full update of the agent. This is a synchronous call. | 351 | m_log.DebugFormat( |
333 | AgentData agent = new AgentData(); | 352 | "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); |
334 | sp.CopyTo(agent); | ||
335 | agent.Position = position; | ||
336 | agent.CallbackURI = "http://" + sp.Scene.RegionInfo.ExternalHostName + ":" + sp.Scene.RegionInfo.HttpPort + | ||
337 | "/agent/" + sp.UUID.ToString() + "/" + sp.Scene.RegionInfo.RegionID.ToString() + "/release/"; | ||
338 | 353 | ||
339 | m_aScene.SimulationService.UpdateAgent(reg, agent); | ||
340 | 354 | ||
341 | m_log.DebugFormat( | 355 | if (eq != null) |
342 | "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); | 356 | { |
357 | eq.TeleportFinishEvent(destinationHandle, 13, endPoint, | ||
358 | 0, teleportFlags, capsPath, sp.UUID); | ||
359 | } | ||
360 | else | ||
361 | { | ||
362 | sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, | ||
363 | teleportFlags, capsPath); | ||
364 | } | ||
343 | 365 | ||
366 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | ||
367 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | ||
368 | // that the client contacted the destination before we send the attachments and close things here. | ||
369 | if (!WaitForCallback(sp.UUID)) | ||
370 | { | ||
371 | // Client never contacted destination. Let's restore everything back | ||
372 | sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); | ||
344 | 373 | ||
345 | if (eq != null) | 374 | ResetFromTransit(sp.UUID); |
346 | { | ||
347 | eq.TeleportFinishEvent(destinationHandle, 13, endPoint, | ||
348 | 0, teleportFlags, capsPath, sp.UUID); | ||
349 | } | ||
350 | else | ||
351 | { | ||
352 | sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, | ||
353 | teleportFlags, capsPath); | ||
354 | } | ||
355 | 375 | ||
356 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | 376 | // Yikes! We should just have a ref to scene here. |
357 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | 377 | //sp.Scene.InformClientOfNeighbours(sp); |
358 | // that the client contacted the destination before we send the attachments and close things here. | 378 | EnableChildAgents(sp); |
359 | if (!WaitForCallback(sp.UUID)) | ||
360 | { | ||
361 | // Client never contacted destination. Let's restore everything back | ||
362 | sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); | ||
363 | 379 | ||
364 | ResetFromTransit(sp.UUID); | 380 | // Finally, kill the agent we just created at the destination. |
381 | m_aScene.SimulationService.CloseAgent(reg, sp.UUID); | ||
365 | 382 | ||
366 | // Yikes! We should just have a ref to scene here. | 383 | return; |
367 | //sp.Scene.InformClientOfNeighbours(sp); | 384 | } |
368 | EnableChildAgents(sp); | ||
369 | 385 | ||
370 | // Finally, kill the agent we just created at the destination. | 386 | KillEntity(sp.Scene, sp.LocalId); |
371 | m_aScene.SimulationService.CloseAgent(reg, sp.UUID); | ||
372 | 387 | ||
373 | return; | 388 | sp.MakeChildAgent(); |
374 | } | ||
375 | 389 | ||
376 | KillEntity(sp.Scene, sp.LocalId); | 390 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it |
391 | CrossAttachmentsIntoNewRegion(reg, sp, true); | ||
377 | 392 | ||
378 | sp.MakeChildAgent(); | 393 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
379 | 394 | ||
380 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | 395 | if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
381 | CrossAttachmentsIntoNewRegion(reg, sp, true); | 396 | { |
397 | Thread.Sleep(5000); | ||
398 | sp.Close(); | ||
399 | sp.Scene.IncomingCloseAgent(sp.UUID); | ||
400 | } | ||
401 | else | ||
402 | // now we have a child agent in this region. | ||
403 | sp.Reset(); | ||
382 | 404 | ||
383 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | ||
384 | 405 | ||
385 | if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 406 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! |
386 | { | 407 | if (sp.Scene.NeedSceneCacheClear(sp.UUID)) |
387 | Thread.Sleep(5000); | 408 | { |
388 | sp.Close(); | 409 | m_log.DebugFormat( |
389 | sp.Scene.IncomingCloseAgent(sp.UUID); | 410 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", |
411 | sp.UUID); | ||
412 | } | ||
390 | } | 413 | } |
391 | else | 414 | else |
392 | // now we have a child agent in this region. | ||
393 | sp.Reset(); | ||
394 | |||
395 | |||
396 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
397 | if (sp.Scene.NeedSceneCacheClear(sp.UUID)) | ||
398 | { | 415 | { |
399 | m_log.DebugFormat( | 416 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); |
400 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", | ||
401 | sp.UUID); | ||
402 | } | 417 | } |
403 | } | 418 | } |
404 | else | 419 | else |
405 | { | 420 | { |
406 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); | 421 | // TP to a place that doesn't exist (anymore) |
422 | // Inform the viewer about that | ||
423 | sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); | ||
424 | |||
425 | // and set the map-tile to '(Offline)' | ||
426 | uint regX, regY; | ||
427 | Utils.LongToUInts(regionHandle, out regX, out regY); | ||
428 | |||
429 | MapBlockData block = new MapBlockData(); | ||
430 | block.X = (ushort)(regX / Constants.RegionSize); | ||
431 | block.Y = (ushort)(regY / Constants.RegionSize); | ||
432 | block.Access = 254; // == not there | ||
433 | |||
434 | List<MapBlockData> blocks = new List<MapBlockData>(); | ||
435 | blocks.Add(block); | ||
436 | sp.ControllingClient.SendMapBlock(blocks, 0); | ||
407 | } | 437 | } |
408 | } | 438 | } |
409 | else | 439 | } |
410 | { | 440 | catch (Exception e) |
411 | // TP to a place that doesn't exist (anymore) | 441 | { |
412 | // Inform the viewer about that | 442 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0}\n{1}", e.Message, e.StackTrace); |
413 | sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); | 443 | sp.ControllingClient.SendTeleportFailed("Internal error"); |
414 | |||
415 | // and set the map-tile to '(Offline)' | ||
416 | uint regX, regY; | ||
417 | Utils.LongToUInts(regionHandle, out regX, out regY); | ||
418 | |||
419 | MapBlockData block = new MapBlockData(); | ||
420 | block.X = (ushort)(regX / Constants.RegionSize); | ||
421 | block.Y = (ushort)(regY / Constants.RegionSize); | ||
422 | block.Access = 254; // == not there | ||
423 | |||
424 | List<MapBlockData> blocks = new List<MapBlockData>(); | ||
425 | blocks.Add(block); | ||
426 | sp.ControllingClient.SendMapBlock(blocks, 0); | ||
427 | } | ||
428 | } | 444 | } |
429 | } | 445 | } |
430 | 446 | ||
@@ -433,11 +449,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
433 | scene.SendKillObject(localID); | 449 | scene.SendKillObject(localID); |
434 | } | 450 | } |
435 | 451 | ||
436 | protected virtual ulong GetRegionHandle(GridRegion region) | ||
437 | { | ||
438 | return region.RegionHandle; | ||
439 | } | ||
440 | |||
441 | protected virtual GridRegion GetFinalDestination(GridRegion region) | 452 | protected virtual GridRegion GetFinalDestination(GridRegion region) |
442 | { | 453 | { |
443 | return region; | 454 | return region; |