diff options
Diffstat (limited to 'OpenSim/Region')
3 files changed, 267 insertions, 230 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; |
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index 68cf060..08a90a2 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | <Extension path = "/OpenSim/RegionModules"> | 10 | <Extension path = "/OpenSim/RegionModules"> |
11 | <RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" /> | 11 | <RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" /> |
12 | <RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" /> | ||
12 | <RegionModule id="LandManagementModule" type="OpenSim.Region.CoreModules.World.Land.LandManagementModule" /> | 13 | <RegionModule id="LandManagementModule" type="OpenSim.Region.CoreModules.World.Land.LandManagementModule" /> |
13 | <RegionModule id="ExportSerialisationModule" type="OpenSim.Region.CoreModules.World.Serialiser.SerialiserModule" /> | 14 | <RegionModule id="ExportSerialisationModule" type="OpenSim.Region.CoreModules.World.Serialiser.SerialiserModule" /> |
14 | <RegionModule id="ArchiverModule" type="OpenSim.Region.CoreModules.World.Archiver.ArchiverModule" /> | 15 | <RegionModule id="ArchiverModule" type="OpenSim.Region.CoreModules.World.Archiver.ArchiverModule" /> |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs index 773286c..07f3cdc 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs | |||
@@ -48,7 +48,7 @@ using Nini.Config; | |||
48 | 48 | ||
49 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | 49 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid |
50 | { | 50 | { |
51 | public class HGGridConnector : ISharedRegionModule, IGridService | 51 | public class HGGridConnector : ISharedRegionModule, IGridService, IHypergridService |
52 | { | 52 | { |
53 | private static readonly ILog m_log = | 53 | private static readonly ILog m_log = |
54 | LogManager.GetLogger( | 54 | LogManager.GetLogger( |
@@ -148,6 +148,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
148 | 148 | ||
149 | m_LocalScenes[scene.RegionInfo.RegionHandle] = scene; | 149 | m_LocalScenes[scene.RegionInfo.RegionHandle] = scene; |
150 | scene.RegisterModuleInterface<IGridService>(this); | 150 | scene.RegisterModuleInterface<IGridService>(this); |
151 | scene.RegisterModuleInterface<IHypergridService>(this); | ||
151 | 152 | ||
152 | ((ISharedRegionModule)m_GridServiceConnector).AddRegion(scene); | 153 | ((ISharedRegionModule)m_GridServiceConnector).AddRegion(scene); |
153 | 154 | ||
@@ -158,6 +159,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
158 | if (m_Enabled) | 159 | if (m_Enabled) |
159 | { | 160 | { |
160 | m_LocalScenes.Remove(scene.RegionInfo.RegionHandle); | 161 | m_LocalScenes.Remove(scene.RegionInfo.RegionHandle); |
162 | scene.UnregisterModuleInterface<IGridService>(this); | ||
163 | scene.UnregisterModuleInterface<IHypergridService>(this); | ||
161 | ((ISharedRegionModule)m_GridServiceConnector).RemoveRegion(scene); | 164 | ((ISharedRegionModule)m_GridServiceConnector).RemoveRegion(scene); |
162 | } | 165 | } |
163 | } | 166 | } |
@@ -278,5 +281,27 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
278 | 281 | ||
279 | #endregion | 282 | #endregion |
280 | 283 | ||
284 | #region IHypergridService | ||
285 | |||
286 | public bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string imageURL, out string reason) | ||
287 | { | ||
288 | return m_HypergridService.LinkRegion(regionDescriptor, out regionID, out regionHandle, out imageURL, out reason); | ||
289 | } | ||
290 | |||
291 | public GridRegion GetHyperlinkRegion(GridRegion gateway, UUID regionID) | ||
292 | { | ||
293 | if (m_LocalScenes.ContainsKey(gateway.RegionHandle)) | ||
294 | return gateway; | ||
295 | |||
296 | return m_HypergridService.GetHyperlinkRegion(gateway, regionID); | ||
297 | } | ||
298 | |||
299 | public GridRegion GetRegionByUUID(UUID regionID) { return null; } | ||
300 | public GridRegion GetRegionByPosition(int x, int y) { return null; } | ||
301 | public GridRegion GetRegionByName(string name) { return null; } | ||
302 | public List<GridRegion> GetRegionsByName(string name) { return null; } | ||
303 | public List<GridRegion> GetRegionRange(int xmin, int xmax, int ymin, int ymax) { return null; } | ||
304 | |||
305 | #endregion | ||
281 | } | 306 | } |
282 | } | 307 | } |