aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs152
1 files changed, 71 insertions, 81 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index a804e29..3095382 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3384,10 +3384,23 @@ namespace OpenSim.Region.Framework.Scenes
3384// CheckHeartbeat(); 3384// CheckHeartbeat();
3385 bool isChildAgent = false; 3385 bool isChildAgent = false;
3386 ScenePresence avatar = GetScenePresence(agentID); 3386 ScenePresence avatar = GetScenePresence(agentID);
3387 if (avatar != null) 3387
3388 if (avatar == null)
3389 {
3390 m_log.WarnFormat(
3391 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3392
3393 return;
3394 }
3395
3396 try
3388 { 3397 {
3389 isChildAgent = avatar.IsChildAgent; 3398 isChildAgent = avatar.IsChildAgent;
3390 3399
3400 m_log.DebugFormat(
3401 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3402 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3403
3391 // Don't do this to root agents, it's not nice for the viewer 3404 // Don't do this to root agents, it's not nice for the viewer
3392 if (closeChildAgents && isChildAgent) 3405 if (closeChildAgents && isChildAgent)
3393 { 3406 {
@@ -3409,101 +3422,78 @@ namespace OpenSim.Region.Framework.Scenes
3409 avatar.StandUp(); 3422 avatar.StandUp();
3410 } 3423 }
3411 3424
3412 try 3425 m_sceneGraph.removeUserCount(!isChildAgent);
3413 {
3414 m_log.DebugFormat(
3415 "[SCENE]: Removing {0} agent {1} {2} from region {3}",
3416 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3417
3418 m_sceneGraph.removeUserCount(!isChildAgent);
3419 3426
3420 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3427 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3421 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3428 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3422 if (closeChildAgents && CapsModule != null) 3429 if (closeChildAgents && CapsModule != null)
3423 CapsModule.RemoveCaps(agentID); 3430 CapsModule.RemoveCaps(agentID);
3424 3431
3425 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever 3432 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3426 // this method is doing is HORRIBLE!!! 3433 // this method is doing is HORRIBLE!!!
3427 avatar.Scene.NeedSceneCacheClear(avatar.UUID); 3434 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3428 3435
3429 if (closeChildAgents && !avatar.IsChildAgent) 3436 if (closeChildAgents && !isChildAgent)
3430 {
3431 List<ulong> regions = avatar.KnownRegionHandles;
3432 regions.Remove(RegionInfo.RegionHandle);
3433 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3434 }
3435 m_log.Debug("[Scene] Beginning ClientClosed");
3436 m_eventManager.TriggerClientClosed(agentID, this);
3437 m_log.Debug("[Scene] Finished ClientClosed");
3438 }
3439 catch (NullReferenceException)
3440 { 3437 {
3441 // We don't know which count to remove it from 3438 List<ulong> regions = avatar.KnownRegionHandles;
3442 // Avatar is already disposed :/ 3439 regions.Remove(RegionInfo.RegionHandle);
3440 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3443 } 3441 }
3444 3442
3445 try 3443 m_eventManager.TriggerClientClosed(agentID, this);
3444 m_eventManager.TriggerOnRemovePresence(agentID);
3445
3446 if (!isChildAgent)
3446 { 3447 {
3447 m_eventManager.TriggerOnRemovePresence(agentID); 3448 if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc)
3448
3449 if (!isChildAgent)
3450 { 3449 {
3451 if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc) 3450 IUserManagement uMan = RequestModuleInterface<IUserManagement>();
3452 { 3451 // Don't save attachments for HG visitors, it
3453 IUserManagement uMan = RequestModuleInterface<IUserManagement>(); 3452 // messes up their inventory. When a HG visitor logs
3454 // Don't save attachments for HG visitors, it 3453 // out on a foreign grid, their attachments will be
3455 // messes up their inventory. When a HG visitor logs 3454 // reloaded in the state they were in when they left
3456 // out on a foreign grid, their attachments will be 3455 // the home grid. This is best anyway as the visited
3457 // reloaded in the state they were in when they left 3456 // grid may use an incompatible script engine.
3458 // the home grid. This is best anyway as the visited 3457 if (uMan == null || uMan.IsLocalGridUser(avatar.UUID))
3459 // grid may use an incompatible script engine. 3458 AttachmentsModule.SaveChangedAttachments(avatar, false);
3460 if (uMan == null || uMan.IsLocalGridUser(avatar.UUID))
3461 AttachmentsModule.SaveChangedAttachments(avatar, false);
3462 }
3463
3464 ForEachClient(
3465 delegate(IClientAPI client)
3466 {
3467 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3468 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3469 catch (NullReferenceException) { }
3470 });
3471 } 3459 }
3472 3460
3473 // It's possible for child agents to have transactions if changes are being made cross-border. 3461 ForEachClient(
3474 if (AgentTransactionsModule != null) 3462 delegate(IClientAPI client)
3475 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); 3463 {
3476 } 3464 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3477 finally 3465 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3478 { 3466 catch (NullReferenceException) { }
3479 // Always clean these structures up so that any failure above doesn't cause them to remain in the 3467 });
3480 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3481 // the same cleanup exception continually.
3482 // TODO: This should probably extend to the whole method, but we don't want to also catch the NRE
3483 // since this would hide the underlying failure and other associated problems.
3484 m_sceneGraph.RemoveScenePresence(agentID);
3485 m_clientManager.Remove(agentID);
3486 } 3468 }
3487 3469
3488 try 3470 // It's possible for child agents to have transactions if changes are being made cross-border.
3489 { 3471 if (AgentTransactionsModule != null)
3490 avatar.Close(); 3472 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3491 } 3473
3492 catch (NullReferenceException) 3474 avatar.Close();
3493 { 3475
3494 //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
3495 }
3496 catch (Exception e)
3497 {
3498 m_log.ErrorFormat("[SCENE] Scene.cs:RemoveClient exception {0}{1}", e.Message, e.StackTrace);
3499 }
3500 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3501 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3476 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3502// CleanDroppedAttachments();
3503 m_log.Debug("[Scene] The avatar has left the building"); 3477 m_log.Debug("[Scene] The avatar has left the building");
3504 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3505 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3506 } 3478 }
3479 catch (Exception e)
3480 {
3481 m_log.Error(
3482 string.Format("[SCENE]: Exception removing {0} from {1}, ", avatar.Name, RegionInfo.RegionName), e);
3483 }
3484 finally
3485 {
3486 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3487 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3488 // the same cleanup exception continually.
3489 // TODO: This should probably extend to the whole method, but we don't want to also catch the NRE
3490 // since this would hide the underlying failure and other associated problems.
3491 m_sceneGraph.RemoveScenePresence(agentID);
3492 m_clientManager.Remove(agentID);
3493 }
3494
3495 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3496 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3507 } 3497 }
3508 3498
3509 /// <summary> 3499 /// <summary>