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.cs522
1 files changed, 310 insertions, 212 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 671feda..5f45529 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -80,6 +80,11 @@ namespace OpenSim.Region.Framework.Scenes
80 public SynchronizeSceneHandler SynchronizeScene; 80 public SynchronizeSceneHandler SynchronizeScene;
81 81
82 /// <summary> 82 /// <summary>
83 /// Used to prevent simultaneous calls to RemoveClient() for the same agent from interfering with each other.
84 /// </summary>
85 private object m_removeClientLock = new object();
86
87 /// <summary>
83 /// Statistical information for this scene. 88 /// Statistical information for this scene.
84 /// </summary> 89 /// </summary>
85 public SimStatsReporter StatsReporter { get; private set; } 90 public SimStatsReporter StatsReporter { get; private set; }
@@ -301,6 +306,31 @@ namespace OpenSim.Region.Framework.Scenes
301 } 306 }
302 private volatile bool m_shuttingDown; 307 private volatile bool m_shuttingDown;
303 308
309 /// <summary>
310 /// Is the scene active?
311 /// </summary>
312 /// <remarks>
313 /// If false, maintenance and update loops are not being run. Updates can still be triggered manually if
314 /// the scene is not active.
315 /// </remarks>
316 public bool Active
317 {
318 get { return m_active; }
319 set
320 {
321 if (value)
322 {
323 if (!m_active)
324 Start();
325 }
326 else
327 {
328 m_active = false;
329 }
330 }
331 }
332 private volatile bool m_active;
333
304// private int m_lastUpdate; 334// private int m_lastUpdate;
305// private bool m_firstHeartbeat = true; 335// private bool m_firstHeartbeat = true;
306 336
@@ -1154,6 +1184,14 @@ namespace OpenSim.Region.Framework.Scenes
1154 1184
1155 public void SetSceneCoreDebug(Dictionary<string, string> options) 1185 public void SetSceneCoreDebug(Dictionary<string, string> options)
1156 { 1186 {
1187 if (options.ContainsKey("active"))
1188 {
1189 bool active;
1190
1191 if (bool.TryParse(options["active"], out active))
1192 Active = active;
1193 }
1194
1157 if (options.ContainsKey("scripting")) 1195 if (options.ContainsKey("scripting"))
1158 { 1196 {
1159 bool enableScripts = true; 1197 bool enableScripts = true;
@@ -1293,6 +1331,8 @@ namespace OpenSim.Region.Framework.Scenes
1293 /// </summary> 1331 /// </summary>
1294 public void Start() 1332 public void Start()
1295 { 1333 {
1334 m_active = true;
1335
1296// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1336// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1297 1337
1298 //m_heartbeatTimer.Enabled = true; 1338 //m_heartbeatTimer.Enabled = true;
@@ -1334,7 +1374,7 @@ namespace OpenSim.Region.Framework.Scenes
1334 #region Update Methods 1374 #region Update Methods
1335 1375
1336 /// <summary> 1376 /// <summary>
1337 /// Performs per-frame updates regularly 1377 /// Activate the various loops necessary to continually update the scene.
1338 /// </summary> 1378 /// </summary>
1339 private void Heartbeat() 1379 private void Heartbeat()
1340 { 1380 {
@@ -1391,7 +1431,7 @@ namespace OpenSim.Region.Framework.Scenes
1391 List<Vector3> coarseLocations; 1431 List<Vector3> coarseLocations;
1392 List<UUID> avatarUUIDs; 1432 List<UUID> avatarUUIDs;
1393 1433
1394 while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) 1434 while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun))
1395 { 1435 {
1396 runtc = Util.EnvironmentTickCount(); 1436 runtc = Util.EnvironmentTickCount();
1397 ++MaintenanceRun; 1437 ++MaintenanceRun;
@@ -1450,7 +1490,7 @@ namespace OpenSim.Region.Framework.Scenes
1450 int previousFrameTick, tmpMS; 1490 int previousFrameTick, tmpMS;
1451 int maintc = Util.EnvironmentTickCount(); 1491 int maintc = Util.EnvironmentTickCount();
1452 1492
1453 while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) 1493 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1454 { 1494 {
1455 ++Frame; 1495 ++Frame;
1456 1496
@@ -2709,69 +2749,89 @@ namespace OpenSim.Region.Framework.Scenes
2709 2749
2710 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2750 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
2711 { 2751 {
2752 ScenePresence sp;
2753 bool vialogin;
2754
2712 // Validation occurs in LLUDPServer 2755 // Validation occurs in LLUDPServer
2756 //
2757 // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with
2758 // each other. In practice, this does not currently occur in the code.
2713 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2759 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2714 2760
2715 bool vialogin 2761 // We lock here on AgentCircuitData to prevent a race condition between the thread adding a new connection
2716 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 2762 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point
2717 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2763 // whilst connecting).
2718 2764 //
2719// CheckHeartbeat(); 2765 // It would be easier to lock across all NewUserConnection(), AddNewClient() and
2720 2766 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
2721 ScenePresence sp = GetScenePresence(client.AgentId); 2767 // response in some module listening to AddNewClient()) from holding up unrelated agent calls.
2722 2768 //
2723 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2769 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all
2724 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause 2770 // AddNewClient() operations (though not other ops).
2725 // other problems, and possible the code calling AddNewClient() should ensure that no client is already 2771 // In the future this can be relieved once locking per agent (not necessarily on AgentCircuitData) is improved.
2726 // connected. 2772 lock (aCircuit)
2727 if (sp == null) 2773 {
2728 { 2774 vialogin
2729 m_log.DebugFormat( 2775 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2730 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 2776 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2731 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); 2777
2732 2778 // CheckHeartbeat();
2733 m_clientManager.Add(client); 2779
2734 SubscribeToClientEvents(client); 2780 sp = GetScenePresence(client.AgentId);
2735
2736 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2737 m_eventManager.TriggerOnNewPresence(sp);
2738
2739 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2740 2781
2741 // The first agent upon login is a root agent by design. 2782 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
2742 // For this agent we will have to rez the attachments. 2783 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause
2743 // All other AddNewClient calls find aCircuit.child to be true. 2784 // other problems, and possible the code calling AddNewClient() should ensure that no client is already
2744 if (aCircuit.child == false) 2785 // connected.
2786 if (sp == null)
2745 { 2787 {
2746 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to 2788 m_log.DebugFormat(
2747 // start the scripts again (since this is done in RezAttachments()). 2789 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2748 // XXX: This is convoluted. 2790 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2749 sp.IsChildAgent = false; 2791
2750 2792 m_clientManager.Add(client);
2751 if (AttachmentsModule != null) 2793 SubscribeToClientEvents(client);
2752 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); 2794
2795 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2796 m_eventManager.TriggerOnNewPresence(sp);
2797
2798 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2799
2800 // The first agent upon login is a root agent by design.
2801 // For this agent we will have to rez the attachments.
2802 // All other AddNewClient calls find aCircuit.child to be true.
2803 if (aCircuit.child == false)
2804 {
2805 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to
2806 // start the scripts again (since this is done in RezAttachments()).
2807 // XXX: This is convoluted.
2808 sp.IsChildAgent = false;
2809
2810 if (AttachmentsModule != null)
2811 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
2812 }
2753 } 2813 }
2754 } 2814 else
2755 else 2815 {
2756 { 2816 m_log.WarnFormat(
2757 m_log.WarnFormat( 2817 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2758 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 2818 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2759 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2819 }
2760 } 2820
2821 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2822 // client is for a root or child agent.
2823 client.SceneAgent = sp;
2761 2824
2762 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 2825 // Cache the user's name
2763 // client is for a root or child agent. 2826 CacheUserName(sp, aCircuit);
2764 client.SceneAgent = sp; 2827
2828 EventManager.TriggerOnNewClient(client);
2829 if (vialogin)
2830 EventManager.TriggerOnClientLogin(client);
2831 }
2765 2832
2766 m_LastLogin = Util.EnvironmentTickCount(); 2833 m_LastLogin = Util.EnvironmentTickCount();
2767 2834
2768 // Cache the user's name
2769 CacheUserName(sp, aCircuit);
2770
2771 EventManager.TriggerOnNewClient(client);
2772 if (vialogin)
2773 EventManager.TriggerOnClientLogin(client);
2774
2775 return sp; 2835 return sp;
2776 } 2836 }
2777 2837
@@ -3300,109 +3360,129 @@ namespace OpenSim.Region.Framework.Scenes
3300 { 3360 {
3301// CheckHeartbeat(); 3361// CheckHeartbeat();
3302 bool isChildAgent = false; 3362 bool isChildAgent = false;
3303 ScenePresence avatar = GetScenePresence(agentID); 3363 AgentCircuitData acd;
3304 3364
3305 if (avatar == null) 3365 lock (m_removeClientLock)
3306 { 3366 {
3307 m_log.WarnFormat( 3367 acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3308 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3309
3310 return;
3311 }
3312 3368
3313 try 3369 if (acd == null)
3314 {
3315 isChildAgent = avatar.IsChildAgent;
3316
3317 m_log.DebugFormat(
3318 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3319 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3320
3321 // Don't do this to root agents, it's not nice for the viewer
3322 if (closeChildAgents && isChildAgent)
3323 { 3370 {
3324 // Tell a single agent to disconnect from the region. 3371 m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID);
3325 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3372 return;
3326 if (eq != null)
3327 {
3328 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3329 }
3330 else
3331 {
3332 avatar.ControllingClient.SendShutdownConnectionNotice();
3333 }
3334 } 3373 }
3335 3374 else
3336 // Only applies to root agents.
3337 if (avatar.ParentID != 0)
3338 { 3375 {
3339 avatar.StandUp(); 3376 // We remove the acd up here to avoid later raec conditions if two RemoveClient() calls occurred
3377 // simultaneously.
3378 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3340 } 3379 }
3380 }
3341 3381
3342 m_sceneGraph.removeUserCount(!isChildAgent); 3382 lock (acd)
3343 3383 {
3344 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3384 ScenePresence avatar = GetScenePresence(agentID);
3345 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3385
3346 if (closeChildAgents && CapsModule != null) 3386 if (avatar == null)
3347 CapsModule.RemoveCaps(agentID);
3348
3349 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3350 // this method is doing is HORRIBLE!!!
3351 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3352
3353 if (closeChildAgents && !isChildAgent)
3354 { 3387 {
3355 List<ulong> regions = avatar.KnownRegionHandles; 3388 m_log.WarnFormat(
3356 regions.Remove(RegionInfo.RegionHandle); 3389 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3357 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3390
3391 return;
3358 } 3392 }
3359 3393
3360 m_eventManager.TriggerClientClosed(agentID, this); 3394 try
3361 m_eventManager.TriggerOnRemovePresence(agentID);
3362
3363 if (!isChildAgent)
3364 { 3395 {
3365 if (AttachmentsModule != null) 3396 isChildAgent = avatar.IsChildAgent;
3397
3398 m_log.DebugFormat(
3399 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3400 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3401
3402 // Don't do this to root agents, it's not nice for the viewer
3403 if (closeChildAgents && isChildAgent)
3366 { 3404 {
3367 AttachmentsModule.DeRezAttachments(avatar); 3405 // Tell a single agent to disconnect from the region.
3406 IEventQueue eq = RequestModuleInterface<IEventQueue>();
3407 if (eq != null)
3408 {
3409 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3410 }
3411 else
3412 {
3413 avatar.ControllingClient.SendShutdownConnectionNotice();
3414 }
3368 } 3415 }
3369 3416
3370 ForEachClient( 3417 // Only applies to root agents.
3371 delegate(IClientAPI client) 3418 if (avatar.ParentID != 0)
3419 {
3420 avatar.StandUp();
3421 }
3422
3423 m_sceneGraph.removeUserCount(!isChildAgent);
3424
3425 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3426 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3427 if (closeChildAgents && CapsModule != null)
3428 CapsModule.RemoveCaps(agentID);
3429
3430 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3431 // this method is doing is HORRIBLE!!!
3432 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3433
3434 if (closeChildAgents && !isChildAgent)
3435 {
3436 List<ulong> regions = avatar.KnownRegionHandles;
3437 regions.Remove(RegionInfo.RegionHandle);
3438 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3439 }
3440
3441 m_eventManager.TriggerClientClosed(agentID, this);
3442 m_eventManager.TriggerOnRemovePresence(agentID);
3443
3444 if (!isChildAgent)
3445 {
3446 if (AttachmentsModule != null)
3372 { 3447 {
3373 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3448 AttachmentsModule.DeRezAttachments(avatar);
3374 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3449 }
3375 catch (NullReferenceException) { }
3376 });
3377 }
3378
3379 // It's possible for child agents to have transactions if changes are being made cross-border.
3380 if (AgentTransactionsModule != null)
3381 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3382 3450
3383 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3451 ForEachClient(
3384 } 3452 delegate(IClientAPI client)
3385 catch (Exception e) 3453 {
3386 { 3454 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3387 m_log.Error( 3455 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3388 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); 3456 catch (NullReferenceException) { }
3389 } 3457 });
3390 finally 3458 }
3391 {
3392 try
3393 {
3394 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3395 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3396 // the same cleanup exception continually.
3397 m_sceneGraph.RemoveScenePresence(agentID);
3398 m_clientManager.Remove(agentID);
3399 3459
3400 avatar.Close(); 3460 // It's possible for child agents to have transactions if changes are being made cross-border.
3461 if (AgentTransactionsModule != null)
3462 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3401 } 3463 }
3402 catch (Exception e) 3464 catch (Exception e)
3403 { 3465 {
3404 m_log.Error( 3466 m_log.Error(
3405 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); 3467 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e);
3468 }
3469 finally
3470 {
3471 try
3472 {
3473 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3474 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3475 // the same cleanup exception continually.
3476 m_sceneGraph.RemoveScenePresence(agentID);
3477 m_clientManager.Remove(agentID);
3478
3479 avatar.Close();
3480 }
3481 catch (Exception e)
3482 {
3483 m_log.Error(
3484 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e);
3485 }
3406 } 3486 }
3407 } 3487 }
3408 3488
@@ -3461,11 +3541,9 @@ namespace OpenSim.Region.Framework.Scenes
3461 3541
3462 /// <summary> 3542 /// <summary>
3463 /// Do the work necessary to initiate a new user connection for a particular scene. 3543 /// Do the work necessary to initiate a new user connection for a particular scene.
3464 /// At the moment, this consists of setting up the caps infrastructure
3465 /// The return bool should allow for connections to be refused, but as not all calling paths
3466 /// take proper notice of it let, we allowed banned users in still.
3467 /// </summary> 3544 /// </summary>
3468 /// <param name="agent">CircuitData of the agent who is connecting</param> 3545 /// <param name="agent">CircuitData of the agent who is connecting</param>
3546 /// <param name="teleportFlags"></param>
3469 /// <param name="reason">Outputs the reason for the false response on this string</param> 3547 /// <param name="reason">Outputs the reason for the false response on this string</param>
3470 /// <returns>True if the region accepts this agent. False if it does not. False will 3548 /// <returns>True if the region accepts this agent. False if it does not. False will
3471 /// also return a reason.</returns> 3549 /// also return a reason.</returns>
@@ -3476,10 +3554,20 @@ namespace OpenSim.Region.Framework.Scenes
3476 3554
3477 /// <summary> 3555 /// <summary>
3478 /// Do the work necessary to initiate a new user connection for a particular scene. 3556 /// Do the work necessary to initiate a new user connection for a particular scene.
3479 /// At the moment, this consists of setting up the caps infrastructure 3557 /// </summary>
3558 /// <remarks>
3559 /// The return bool should allow for connections to be refused, but as not all calling paths
3560 /// take proper notice of it yet, we still allowed banned users in.
3561 ///
3562 /// At the moment this method consists of setting up the caps infrastructure
3480 /// The return bool should allow for connections to be refused, but as not all calling paths 3563 /// The return bool should allow for connections to be refused, but as not all calling paths
3481 /// take proper notice of it let, we allowed banned users in still. 3564 /// take proper notice of it let, we allowed banned users in still.
3482 /// </summary> 3565 ///
3566 /// This method is called by the login service (in the case of login) or another simulator (in the case of region
3567 /// cross or teleport) to initiate the connection. It is not triggered by the viewer itself - the connection
3568 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
3569 /// the LLUDP stack).
3570 /// </remarks>
3483 /// <param name="agent">CircuitData of the agent who is connecting</param> 3571 /// <param name="agent">CircuitData of the agent who is connecting</param>
3484 /// <param name="reason">Outputs the reason for the false response on this string</param> 3572 /// <param name="reason">Outputs the reason for the false response on this string</param>
3485 /// <param name="requirePresenceLookup">True for normal presence. False for NPC 3573 /// <param name="requirePresenceLookup">True for normal presence. False for NPC
@@ -3564,88 +3652,97 @@ namespace OpenSim.Region.Framework.Scenes
3564 agent.firstname, agent.lastname, agent.Viewer); 3652 agent.firstname, agent.lastname, agent.Viewer);
3565 reason = "Access denied, your viewer is banned by the region owner"; 3653 reason = "Access denied, your viewer is banned by the region owner";
3566 return false; 3654 return false;
3567 }
3568
3569
3570 ScenePresence sp = GetScenePresence(agent.AgentID);
3571
3572 if (sp != null && !sp.IsChildAgent)
3573 {
3574 // We have a zombie from a crashed session.
3575 // Or the same user is trying to be root twice here, won't work.
3576 // Kill it.
3577 m_log.WarnFormat(
3578 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3579 sp.Name, sp.UUID, RegionInfo.RegionName);
3580
3581 sp.ControllingClient.Close(true);
3582 sp = null;
3583 } 3655 }
3584 3656
3585 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); 3657 ILandObject land;
3586 3658
3587 //On login test land permisions 3659 lock (agent)
3588 if (vialogin)
3589 { 3660 {
3590 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3661 ScenePresence sp = GetScenePresence(agent.AgentID);
3662
3663 if (sp != null && !sp.IsChildAgent)
3591 { 3664 {
3592 return false; 3665 // We have a zombie from a crashed session.
3666 // Or the same user is trying to be root twice here, won't work.
3667 // Kill it.
3668 m_log.WarnFormat(
3669 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3670 sp.Name, sp.UUID, RegionInfo.RegionName);
3671
3672 sp.ControllingClient.Close(true);
3673 sp = null;
3593 } 3674 }
3594 } 3675
3595 3676 land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3596 if (sp == null) // We don't have an [child] agent here already 3677
3597 { 3678 //On login test land permisions
3598 if (requirePresenceLookup) 3679 if (vialogin)
3599 { 3680 {
3600 try 3681 if (land != null && !TestLandRestrictions(agent, land, out reason))
3601 { 3682 {
3602 if (!VerifyUserPresence(agent, out reason))
3603 return false;
3604 } catch (Exception e)
3605 {
3606 m_log.ErrorFormat(
3607 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3608 return false; 3683 return false;
3609 } 3684 }
3610 } 3685 }
3611 3686
3612 try 3687 if (sp == null) // We don't have an [child] agent here already
3613 {
3614 if (!AuthorizeUser(agent, out reason))
3615 return false;
3616 } catch (Exception e)
3617 {
3618 m_log.ErrorFormat(
3619 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
3620 return false;
3621 }
3622
3623 m_log.InfoFormat(
3624 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3625 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3626 agent.AgentID, agent.circuitcode);
3627
3628 if (CapsModule != null)
3629 { 3688 {
3630 CapsModule.SetAgentCapsSeeds(agent); 3689 if (requirePresenceLookup)
3631 CapsModule.CreateCaps(agent.AgentID); 3690 {
3632 } 3691 try
3633 } else 3692 {
3634 { 3693 if (!VerifyUserPresence(agent, out reason))
3635 // Let the SP know how we got here. This has a lot of interesting 3694 return false;
3636 // uses down the line. 3695 }
3637 sp.TeleportFlags = (TPFlags)teleportFlags; 3696 catch (Exception e)
3697 {
3698 m_log.ErrorFormat(
3699 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3638 3700
3639 if (sp.IsChildAgent) 3701 return false;
3640 { 3702 }
3641 m_log.DebugFormat( 3703 }
3642 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", 3704
3643 agent.AgentID, RegionInfo.RegionName); 3705 try
3706 {
3707 if (!AuthorizeUser(agent, out reason))
3708 return false;
3709 }
3710 catch (Exception e)
3711 {
3712 m_log.ErrorFormat(
3713 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
3644 3714
3645 sp.AdjustKnownSeeds(); 3715 return false;
3646 3716 }
3717
3718 m_log.InfoFormat(
3719 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3720 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3721 agent.AgentID, agent.circuitcode);
3722
3647 if (CapsModule != null) 3723 if (CapsModule != null)
3724 {
3648 CapsModule.SetAgentCapsSeeds(agent); 3725 CapsModule.SetAgentCapsSeeds(agent);
3726 CapsModule.CreateCaps(agent.AgentID);
3727 }
3728 }
3729 else
3730 {
3731 // Let the SP know how we got here. This has a lot of interesting
3732 // uses down the line.
3733 sp.TeleportFlags = (TPFlags)teleportFlags;
3734
3735 if (sp.IsChildAgent)
3736 {
3737 m_log.DebugFormat(
3738 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3739 agent.AgentID, RegionInfo.RegionName);
3740
3741 sp.AdjustKnownSeeds();
3742
3743 if (CapsModule != null)
3744 CapsModule.SetAgentCapsSeeds(agent);
3745 }
3649 } 3746 }
3650 } 3747 }
3651 3748
@@ -4047,8 +4144,9 @@ namespace OpenSim.Region.Framework.Scenes
4047 return false; 4144 return false;
4048 } 4145 }
4049 4146
4050 // We have to wait until the viewer contacts this region after receiving EAC. 4147 // We have to wait until the viewer contacts this region
4051 // That calls AddNewClient, which finally creates the ScenePresence 4148 // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send
4149 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence.
4052 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4150 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
4053 4151
4054 if (childAgentUpdate != null) 4152 if (childAgentUpdate != null)