diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 266 |
1 files changed, 151 insertions, 115 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 779fd6b..b547317 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -170,8 +170,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
170 | if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) | 170 | if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) |
171 | return; | 171 | return; |
172 | 172 | ||
173 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | ||
174 | |||
175 | // Reset animations; the viewer does that in teleports. | 173 | // Reset animations; the viewer does that in teleports. |
176 | sp.Animator.ResetAnimations(); | 174 | sp.Animator.ResetAnimations(); |
177 | 175 | ||
@@ -183,145 +181,183 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
183 | { | 181 | { |
184 | destinationRegionName = sp.Scene.RegionInfo.RegionName; | 182 | destinationRegionName = sp.Scene.RegionInfo.RegionName; |
185 | 183 | ||
186 | m_log.DebugFormat( | 184 | TeleportAgentWithinRegion(sp, position, lookAt, teleportFlags); |
187 | "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", | 185 | } |
188 | sp.Name, position, destinationRegionName); | 186 | else // Another region possibly in another simulator |
187 | { | ||
188 | GridRegion finalDestination; | ||
189 | TeleportAgentToDifferentRegion( | ||
190 | sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); | ||
189 | 191 | ||
190 | // Teleport within the same region | 192 | if (finalDestination != null) |
191 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) | 193 | destinationRegionName = finalDestination.RegionName; |
192 | { | 194 | } |
193 | Vector3 emergencyPos = new Vector3(128, 128, 128); | 195 | } |
196 | catch (Exception e) | ||
197 | { | ||
198 | m_log.ErrorFormat( | ||
199 | "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}", | ||
200 | sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, | ||
201 | e.Message, e.StackTrace); | ||
194 | 202 | ||
195 | m_log.WarnFormat( | 203 | sp.ControllingClient.SendTeleportFailed("Internal error"); |
196 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", | 204 | } |
197 | position, sp.Name, sp.UUID, emergencyPos); | 205 | } |
198 | 206 | ||
199 | position = emergencyPos; | 207 | /// <summary> |
200 | } | 208 | /// Teleports the agent within its current region. |
209 | /// </summary> | ||
210 | /// <param name="sp"></param> | ||
211 | /// <param name="position"></param> | ||
212 | /// <param name="lookAt"></param> | ||
213 | /// <param name="teleportFlags"></param | ||
214 | private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) | ||
215 | { | ||
216 | m_log.DebugFormat( | ||
217 | "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", | ||
218 | sp.Name, position, sp.Scene.RegionInfo.RegionName); | ||
201 | 219 | ||
202 | // TODO: Get proper AVG Height | 220 | // Teleport within the same region |
203 | float localAVHeight = 1.56f; | 221 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) |
204 | float posZLimit = 22; | 222 | { |
223 | Vector3 emergencyPos = new Vector3(128, 128, 128); | ||
205 | 224 | ||
206 | // TODO: Check other Scene HeightField | 225 | m_log.WarnFormat( |
207 | if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) | 226 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", |
208 | { | 227 | position, sp.Name, sp.UUID, emergencyPos); |
209 | posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; | ||
210 | } | ||
211 | 228 | ||
212 | float newPosZ = posZLimit + localAVHeight; | 229 | position = emergencyPos; |
213 | if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) | 230 | } |
214 | { | ||
215 | position.Z = newPosZ; | ||
216 | } | ||
217 | 231 | ||
218 | sp.ControllingClient.SendTeleportStart(teleportFlags); | 232 | // TODO: Get proper AVG Height |
233 | float localAVHeight = 1.56f; | ||
234 | float posZLimit = 22; | ||
219 | 235 | ||
220 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); | 236 | // TODO: Check other Scene HeightField |
221 | sp.Velocity = Vector3.Zero; | 237 | if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) |
222 | sp.Teleport(position); | 238 | { |
239 | posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; | ||
240 | } | ||
223 | 241 | ||
224 | foreach (SceneObjectGroup grp in sp.GetAttachments()) | 242 | float newPosZ = posZLimit + localAVHeight; |
225 | { | 243 | if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) |
226 | sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); | 244 | { |
227 | } | 245 | position.Z = newPosZ; |
228 | } | 246 | } |
229 | else // Another region possibly in another simulator | ||
230 | { | ||
231 | uint x = 0, y = 0; | ||
232 | Utils.LongToUInts(regionHandle, out x, out y); | ||
233 | GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); | ||
234 | 247 | ||
235 | if (reg != null) | 248 | sp.ControllingClient.SendTeleportStart(teleportFlags); |
236 | { | ||
237 | GridRegion finalDestination = GetFinalDestination(reg); | ||
238 | if (finalDestination == null) | ||
239 | { | ||
240 | m_log.WarnFormat( | ||
241 | "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}", | ||
242 | sp.Name, sp.UUID); | ||
243 | 249 | ||
244 | sp.ControllingClient.SendTeleportFailed("Problem at destination"); | 250 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); |
245 | return; | 251 | sp.Velocity = Vector3.Zero; |
246 | } | 252 | sp.Teleport(position); |
247 | 253 | ||
248 | destinationRegionName = finalDestination.RegionName; | 254 | foreach (SceneObjectGroup grp in sp.GetAttachments()) |
255 | { | ||
256 | sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); | ||
257 | } | ||
258 | } | ||
249 | 259 | ||
250 | uint curX = 0, curY = 0; | 260 | /// <summary> |
251 | Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); | 261 | /// Teleports the agent to a different region. |
252 | int curCellX = (int)(curX / Constants.RegionSize); | 262 | /// </summary> |
253 | int curCellY = (int)(curY / Constants.RegionSize); | 263 | /// <param name='sp'></param> |
254 | int destCellX = (int)(finalDestination.RegionLocX / Constants.RegionSize); | 264 | /// <param name='regionHandle'>/param> |
255 | int destCellY = (int)(finalDestination.RegionLocY / Constants.RegionSize); | 265 | /// <param name='position'></param> |
266 | /// <param name='lookAt'></param> | ||
267 | /// <param name='teleportFlags'></param> | ||
268 | /// <param name='finalDestination'></param> | ||
269 | private void TeleportAgentToDifferentRegion( | ||
270 | ScenePresence sp, ulong regionHandle, Vector3 position, | ||
271 | Vector3 lookAt, uint teleportFlags, out GridRegion finalDestination) | ||
272 | { | ||
273 | uint x = 0, y = 0; | ||
274 | Utils.LongToUInts(regionHandle, out x, out y); | ||
275 | GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); | ||
276 | |||
277 | if (reg != null) | ||
278 | { | ||
279 | finalDestination = GetFinalDestination(reg); | ||
280 | |||
281 | if (finalDestination == null) | ||
282 | { | ||
283 | m_log.WarnFormat( | ||
284 | "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}", | ||
285 | sp.Name, sp.UUID); | ||
286 | |||
287 | sp.ControllingClient.SendTeleportFailed("Problem at destination"); | ||
288 | return; | ||
289 | } | ||
290 | |||
291 | uint curX = 0, curY = 0; | ||
292 | Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); | ||
293 | int curCellX = (int)(curX / Constants.RegionSize); | ||
294 | int curCellY = (int)(curY / Constants.RegionSize); | ||
295 | int destCellX = (int)(finalDestination.RegionLocX / Constants.RegionSize); | ||
296 | int destCellY = (int)(finalDestination.RegionLocY / Constants.RegionSize); | ||
256 | 297 | ||
257 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); | 298 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); |
258 | // | 299 | // |
259 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", | 300 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", |
260 | // destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); | 301 | // destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); |
261 | 302 | ||
262 | // Check that these are not the same coordinates | 303 | // Check that these are not the same coordinates |
263 | if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && | 304 | if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && |
264 | finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) | 305 | finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) |
265 | { | 306 | { |
266 | // Can't do. Viewer crashes | 307 | // Can't do. Viewer crashes |
267 | sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again."); | 308 | sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again."); |
268 | return; | 309 | return; |
269 | } | 310 | } |
270 | 311 | ||
271 | if (Math.Abs(curCellX - destCellX) > MaxTransferDistance || Math.Abs(curCellY - destCellY) > MaxTransferDistance) | 312 | if (Math.Abs(curCellX - destCellX) > MaxTransferDistance || Math.Abs(curCellY - destCellY) > MaxTransferDistance) |
272 | { | 313 | { |
273 | sp.ControllingClient.SendTeleportFailed( | 314 | sp.ControllingClient.SendTeleportFailed( |
274 | string.Format( | 315 | string.Format( |
275 | "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", | 316 | "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", |
276 | finalDestination.RegionName, destCellX, destCellY, | 317 | finalDestination.RegionName, destCellX, destCellY, |
277 | sp.Scene.RegionInfo.RegionName, curCellX, curCellY, | 318 | sp.Scene.RegionInfo.RegionName, curCellX, curCellY, |
278 | MaxTransferDistance)); | 319 | MaxTransferDistance)); |
279 | 320 | ||
280 | return; | 321 | return; |
281 | } | ||
282 | |||
283 | // | ||
284 | // This is it | ||
285 | // | ||
286 | DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags, eq); | ||
287 | // | ||
288 | // | ||
289 | // | ||
290 | } | ||
291 | else | ||
292 | { | ||
293 | // TP to a place that doesn't exist (anymore) | ||
294 | // Inform the viewer about that | ||
295 | sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); | ||
296 | |||
297 | // and set the map-tile to '(Offline)' | ||
298 | uint regX, regY; | ||
299 | Utils.LongToUInts(regionHandle, out regX, out regY); | ||
300 | |||
301 | MapBlockData block = new MapBlockData(); | ||
302 | block.X = (ushort)(regX / Constants.RegionSize); | ||
303 | block.Y = (ushort)(regY / Constants.RegionSize); | ||
304 | block.Access = 254; // == not there | ||
305 | |||
306 | List<MapBlockData> blocks = new List<MapBlockData>(); | ||
307 | blocks.Add(block); | ||
308 | sp.ControllingClient.SendMapBlock(blocks, 0); | ||
309 | } | ||
310 | } | 322 | } |
323 | |||
324 | // | ||
325 | // This is it | ||
326 | // | ||
327 | DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags); | ||
328 | // | ||
329 | // | ||
330 | // | ||
311 | } | 331 | } |
312 | catch (Exception e) | 332 | else |
313 | { | 333 | { |
314 | m_log.ErrorFormat( | 334 | finalDestination = null; |
315 | "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}", | 335 | |
316 | sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, | 336 | // TP to a place that doesn't exist (anymore) |
317 | e.Message, e.StackTrace); | 337 | // Inform the viewer about that |
318 | 338 | sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); | |
319 | sp.ControllingClient.SendTeleportFailed("Internal error"); | 339 | |
340 | // and set the map-tile to '(Offline)' | ||
341 | uint regX, regY; | ||
342 | Utils.LongToUInts(regionHandle, out regX, out regY); | ||
343 | |||
344 | MapBlockData block = new MapBlockData(); | ||
345 | block.X = (ushort)(regX / Constants.RegionSize); | ||
346 | block.Y = (ushort)(regY / Constants.RegionSize); | ||
347 | block.Access = 254; // == not there | ||
348 | |||
349 | List<MapBlockData> blocks = new List<MapBlockData>(); | ||
350 | blocks.Add(block); | ||
351 | sp.ControllingClient.SendMapBlock(blocks, 0); | ||
320 | } | 352 | } |
321 | } | 353 | } |
322 | 354 | ||
323 | public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) | 355 | public void DoTeleport( |
356 | ScenePresence sp, GridRegion reg, GridRegion finalDestination, | ||
357 | Vector3 position, Vector3 lookAt, uint teleportFlags) | ||
324 | { | 358 | { |
359 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | ||
360 | |||
325 | if (reg == null || finalDestination == null) | 361 | if (reg == null || finalDestination == null) |
326 | { | 362 | { |
327 | sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); | 363 | sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); |