diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/EventManager.cs | 14 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 522 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 3 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 53 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 9 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/UuidGatherer.cs | 4 |
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> |