aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs522
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs53
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs4
6 files changed, 354 insertions, 251 deletions
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index a8ff218..4c49b71 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -121,13 +121,21 @@ namespace OpenSim.Region.Framework.Scenes
121 /// </summary> 121 /// </summary>
122 /// <remarks> 122 /// <remarks>
123 /// This is triggered for both child and root agent client connections. 123 /// This is triggered for both child and root agent client connections.
124 ///
124 /// Triggered before OnClientLogin. 125 /// Triggered before OnClientLogin.
126 ///
127 /// This is triggered under per-agent lock. So if you want to perform any long-running operations, please
128 /// do this on a separate thread.
125 /// </remarks> 129 /// </remarks>
126 public event OnNewClientDelegate OnNewClient; 130 public event OnNewClientDelegate OnNewClient;
127 131
128 /// <summary> 132 /// <summary>
129 /// Fired if the client entering this sim is doing so as a new login 133 /// Fired if the client entering this sim is doing so as a new login
130 /// </summary> 134 /// </summary>
135 /// <remarks>
136 /// This is triggered under per-agent lock. So if you want to perform any long-running operations, please
137 /// do this on a separate thread.
138 /// </remarks>
131 public event Action<IClientAPI> OnClientLogin; 139 public event Action<IClientAPI> OnClientLogin;
132 140
133 public delegate void OnNewPresenceDelegate(ScenePresence presence); 141 public delegate void OnNewPresenceDelegate(ScenePresence presence);
@@ -149,6 +157,9 @@ namespace OpenSim.Region.Framework.Scenes
149 /// <remarks> 157 /// <remarks>
150 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> which is used by both 158 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> which is used by both
151 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see> 159 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see>
160 ///
161 /// Triggered under per-agent lock. So if you want to perform any long-running operations, please
162 /// do this on a separate thread.
152 /// </remarks> 163 /// </remarks>
153 public event OnRemovePresenceDelegate OnRemovePresence; 164 public event OnRemovePresenceDelegate OnRemovePresence;
154 165
@@ -425,6 +436,9 @@ namespace OpenSim.Region.Framework.Scenes
425 /// </summary> 436 /// </summary>
426 /// <remarks> 437 /// <remarks>
427 /// At the point of firing, the scene still contains the client's scene presence. 438 /// At the point of firing, the scene still contains the client's scene presence.
439 ///
440 /// This is triggered under per-agent lock. So if you want to perform any long-running operations, please
441 /// do this on a separate thread.
428 /// </remarks> 442 /// </remarks>
429 public event ClientClosed OnClientClosed; 443 public event ClientClosed OnClientClosed;
430 444
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)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 45bbbda..1fa6a75 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -3432,6 +3432,7 @@ namespace OpenSim.Region.Framework.Scenes
3432 /// <remarks> 3432 /// <remarks>
3433 /// When the physics engine has finished with it, the sculpt data is discarded to save memory. 3433 /// When the physics engine has finished with it, the sculpt data is discarded to save memory.
3434 /// </remarks> 3434 /// </remarks>
3435/*
3435 public void CheckSculptAndLoad() 3436 public void CheckSculptAndLoad()
3436 { 3437 {
3437 if (IsDeleted) 3438 if (IsDeleted)
@@ -3447,7 +3448,7 @@ namespace OpenSim.Region.Framework.Scenes
3447 for (int i = 0; i < parts.Length; i++) 3448 for (int i = 0; i < parts.Length; i++)
3448 parts[i].CheckSculptAndLoad(); 3449 parts[i].CheckSculptAndLoad();
3449 } 3450 }
3450 3451*/
3451 /// <summary> 3452 /// <summary>
3452 /// Set the user group to which this scene object belongs. 3453 /// Set the user group to which this scene object belongs.
3453 /// </summary> 3454 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 199526e..27ef4c9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1014,9 +1014,9 @@ namespace OpenSim.Region.Framework.Scenes
1014 { 1014 {
1015 actor.Size = m_shape.Scale; 1015 actor.Size = m_shape.Scale;
1016 1016
1017 if (Shape.SculptEntry) 1017// if (Shape.SculptEntry)
1018 CheckSculptAndLoad(); 1018// CheckSculptAndLoad();
1019 else 1019// else
1020 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 1020 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
1021 } 1021 }
1022 } 1022 }
@@ -1620,12 +1620,13 @@ namespace OpenSim.Region.Framework.Scenes
1620 1620
1621 if (userExposed) 1621 if (userExposed)
1622 { 1622 {
1623/*
1623 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero) 1624 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero)
1624 { 1625 {
1625 ParentGroup.Scene.AssetService.Get( 1626 ParentGroup.Scene.AssetService.Get(
1626 dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived); 1627 dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived);
1627 } 1628 }
1628 1629*/
1629 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 1630 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1630 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 1631 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
1631 } 1632 }
@@ -1643,6 +1644,7 @@ namespace OpenSim.Region.Framework.Scenes
1643 /// <param name="id">ID of asset received</param> 1644 /// <param name="id">ID of asset received</param>
1644 /// <param name="sender">Register</param> 1645 /// <param name="sender">Register</param>
1645 /// <param name="asset"></param> 1646 /// <param name="asset"></param>
1647/*
1646 protected void AssetReceived(string id, Object sender, AssetBase asset) 1648 protected void AssetReceived(string id, Object sender, AssetBase asset)
1647 { 1649 {
1648 if (asset != null) 1650 if (asset != null)
@@ -1652,7 +1654,7 @@ namespace OpenSim.Region.Framework.Scenes
1652 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", 1654 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1653 Name, UUID, id); 1655 Name, UUID, id);
1654 } 1656 }
1655 1657*/
1656 /// <summary> 1658 /// <summary>
1657 /// Do a physics property update for a NINJA joint. 1659 /// Do a physics property update for a NINJA joint.
1658 /// </summary> 1660 /// </summary>
@@ -1833,9 +1835,9 @@ namespace OpenSim.Region.Framework.Scenes
1833 1835
1834 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 1836 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
1835 // mesh data. 1837 // mesh data.
1836 if (Shape.SculptEntry) 1838// if (Shape.SculptEntry)
1837 CheckSculptAndLoad(); 1839// CheckSculptAndLoad();
1838 else 1840// else
1839 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 1841 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
1840 } 1842 }
1841 } 1843 }
@@ -2511,6 +2513,7 @@ namespace OpenSim.Region.Framework.Scenes
2511 /// Set sculpt and mesh data, and tell the physics engine to process the change. 2513 /// Set sculpt and mesh data, and tell the physics engine to process the change.
2512 /// </summary> 2514 /// </summary>
2513 /// <param name="texture">The mesh itself.</param> 2515 /// <param name="texture">The mesh itself.</param>
2516/*
2514 public void SculptTextureCallback(AssetBase texture) 2517 public void SculptTextureCallback(AssetBase texture)
2515 { 2518 {
2516 if (m_shape.SculptEntry) 2519 if (m_shape.SculptEntry)
@@ -2538,7 +2541,7 @@ namespace OpenSim.Region.Framework.Scenes
2538 } 2541 }
2539 } 2542 }
2540 } 2543 }
2541 2544*/
2542 /// <summary> 2545 /// <summary>
2543 /// Send a full update to the client for the given part 2546 /// Send a full update to the client for the given part
2544 /// </summary> 2547 /// </summary>
@@ -3783,7 +3786,7 @@ namespace OpenSim.Region.Framework.Scenes
3783 public void UpdateExtraParam(ushort type, bool inUse, byte[] data) 3786 public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
3784 { 3787 {
3785 m_shape.ReadInUpdateExtraParam(type, inUse, data); 3788 m_shape.ReadInUpdateExtraParam(type, inUse, data);
3786 3789/*
3787 if (type == 0x30) 3790 if (type == 0x30)
3788 { 3791 {
3789 if (m_shape.SculptEntry && m_shape.SculptTexture != UUID.Zero) 3792 if (m_shape.SculptEntry && m_shape.SculptTexture != UUID.Zero)
@@ -3791,7 +3794,7 @@ namespace OpenSim.Region.Framework.Scenes
3791 ParentGroup.Scene.AssetService.Get(m_shape.SculptTexture.ToString(), this, AssetReceived); 3794 ParentGroup.Scene.AssetService.Get(m_shape.SculptTexture.ToString(), this, AssetReceived);
3792 } 3795 }
3793 } 3796 }
3794 3797*/
3795 if (ParentGroup != null) 3798 if (ParentGroup != null)
3796 { 3799 {
3797 ParentGroup.HasGroupChanged = true; 3800 ParentGroup.HasGroupChanged = true;
@@ -4025,14 +4028,6 @@ namespace OpenSim.Region.Framework.Scenes
4025 if (!wasUsingPhysics) 4028 if (!wasUsingPhysics)
4026 { 4029 {
4027 DoPhysicsPropertyUpdate(UsePhysics, false); 4030 DoPhysicsPropertyUpdate(UsePhysics, false);
4028
4029 if (!ParentGroup.IsDeleted)
4030 {
4031 if (LocalId == ParentGroup.RootPart.LocalId)
4032 {
4033 ParentGroup.CheckSculptAndLoad();
4034 }
4035 }
4036 } 4031 }
4037 } 4032 }
4038 else 4033 else
@@ -4072,14 +4067,6 @@ namespace OpenSim.Region.Framework.Scenes
4072 pa.SetMaterial(Material); 4067 pa.SetMaterial(Material);
4073 DoPhysicsPropertyUpdate(UsePhysics, true); 4068 DoPhysicsPropertyUpdate(UsePhysics, true);
4074 4069
4075 if (!ParentGroup.IsDeleted)
4076 {
4077 if (LocalId == ParentGroup.RootPart.LocalId)
4078 {
4079 ParentGroup.CheckSculptAndLoad();
4080 }
4081 }
4082
4083 if ( 4070 if (
4084 ((AggregateScriptEvents & scriptEvents.collision) != 0) || 4071 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4085 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || 4072 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
@@ -4104,14 +4091,6 @@ namespace OpenSim.Region.Framework.Scenes
4104 else // it already has a physical representation 4091 else // it already has a physical representation
4105 { 4092 {
4106 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim 4093 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4107
4108 if (!ParentGroup.IsDeleted)
4109 {
4110 if (LocalId == ParentGroup.RootPart.LocalId)
4111 {
4112 ParentGroup.CheckSculptAndLoad();
4113 }
4114 }
4115 } 4094 }
4116 } 4095 }
4117 4096
@@ -4341,6 +4320,7 @@ namespace OpenSim.Region.Framework.Scenes
4341 /// <remarks> 4320 /// <remarks>
4342 /// When the physics engine has finished with it, the sculpt data is discarded to save memory. 4321 /// When the physics engine has finished with it, the sculpt data is discarded to save memory.
4343 /// </remarks> 4322 /// </remarks>
4323/*
4344 public void CheckSculptAndLoad() 4324 public void CheckSculptAndLoad()
4345 { 4325 {
4346// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4326// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
@@ -4366,7 +4346,7 @@ namespace OpenSim.Region.Framework.Scenes
4366 } 4346 }
4367 } 4347 }
4368 } 4348 }
4369 4349*/
4370 /// <summary> 4350 /// <summary>
4371 /// Update the texture entry for this part. 4351 /// Update the texture entry for this part.
4372 /// </summary> 4352 /// </summary>
@@ -4604,6 +4584,7 @@ namespace OpenSim.Region.Framework.Scenes
4604 } 4584 }
4605 4585
4606 Quaternion rot = Quaternion.Slerp(RotationOffset,APIDTarget,1.0f/(float)m_APIDIterations); 4586 Quaternion rot = Quaternion.Slerp(RotationOffset,APIDTarget,1.0f/(float)m_APIDIterations);
4587 rot.Normalize();
4607 UpdateRotation(rot); 4588 UpdateRotation(rot);
4608 4589
4609 m_APIDIterations--; 4590 m_APIDIterations--;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 821fd81..bdb0446 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -92,6 +92,15 @@ namespace OpenSim.Region.Framework.Scenes
92 QueryScriptStates(); 92 QueryScriptStates();
93 } 93 }
94 } 94 }
95
96 public int Count
97 {
98 get
99 {
100 lock (m_items)
101 return m_items.Count;
102 }
103 }
95 104
96 /// <summary> 105 /// <summary>
97 /// Constructor 106 /// Constructor
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index 28cd09f..e238d01 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -66,9 +66,9 @@ namespace OpenSim.Region.Framework.Scenes
66// /// </summary> 66// /// </summary>
67// private bool m_waitingForObjectAsset; 67// private bool m_waitingForObjectAsset;
68 68
69 public UuidGatherer(IAssetService assetCache) 69 public UuidGatherer(IAssetService assetService)
70 { 70 {
71 m_assetService = assetCache; 71 m_assetService = assetService;
72 } 72 }
73 73
74 /// <summary> 74 /// <summary>