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/Animation/AnimationSet.cs13
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs534
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs22
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs699
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs80
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs35
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs62
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs106
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs302
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs58
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs99
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs35
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs58
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs90
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs17
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs36
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs138
19 files changed, 1706 insertions, 704 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
index ad421ee..65ae445 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
@@ -41,6 +41,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
41 { 41 {
42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 43
44 private OpenSim.Framework.Animation m_implicitDefaultAnimation = new OpenSim.Framework.Animation();
44 private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation(); 45 private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation();
45 private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>(); 46 private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>();
46 47
@@ -49,6 +50,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation
49 get { return m_defaultAnimation; } 50 get { return m_defaultAnimation; }
50 } 51 }
51 52
53 public OpenSim.Framework.Animation ImplicitDefaultAnimation
54 {
55 get { return m_implicitDefaultAnimation; }
56 }
57
52 public AnimationSet() 58 public AnimationSet()
53 { 59 {
54 ResetDefaultAnimation(); 60 ResetDefaultAnimation();
@@ -119,11 +125,18 @@ namespace OpenSim.Region.Framework.Scenes.Animation
119 if (m_defaultAnimation.AnimID != animID) 125 if (m_defaultAnimation.AnimID != animID)
120 { 126 {
121 m_defaultAnimation = new OpenSim.Framework.Animation(animID, sequenceNum, objectID); 127 m_defaultAnimation = new OpenSim.Framework.Animation(animID, sequenceNum, objectID);
128 m_implicitDefaultAnimation = m_defaultAnimation;
122 return true; 129 return true;
123 } 130 }
124 return false; 131 return false;
125 } 132 }
126 133
134 // Called from serialization only
135 public void SetImplicitDefaultAnimation(UUID animID, int sequenceNum, UUID objectID)
136 {
137 m_implicitDefaultAnimation = new OpenSim.Framework.Animation(animID, sequenceNum, objectID);
138 }
139
127 protected bool ResetDefaultAnimation() 140 protected bool ResetDefaultAnimation()
128 { 141 {
129 return TrySetDefaultAnimation("STAND", 1, UUID.Zero); 142 return TrySetDefaultAnimation("STAND", 1, UUID.Zero);
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 7916c42..5b1c9f4 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -47,30 +47,75 @@ namespace OpenSim.Region.Framework.Scenes
47 47
48 public delegate void OnFrameDelegate(); 48 public delegate void OnFrameDelegate();
49 49
50 /// <summary>
51 /// Triggered on each sim frame.
52 /// </summary>
53 /// <remarks>
54 /// This gets triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.Update"/>
55 /// Core uses it for things like Sun, Wind & Clouds
56 /// The MRM module also uses it.
57 /// </remarks>
50 public event OnFrameDelegate OnFrame; 58 public event OnFrameDelegate OnFrame;
51 59
52 public delegate void ClientMovement(ScenePresence client); 60 public delegate void ClientMovement(ScenePresence client);
53 61
62 /// <summary>
63 /// Trigerred when an agent moves.
64 /// </summary>
65 /// <remarks>
66 /// This gets triggered in <see cref="OpenSim.Region.Framework.Scenes.ScenePresence.HandleAgentUpdate"/>
67 /// prior to <see cref="OpenSim.Region.Framework.Scenes.ScenePresence.TriggerScenePresenceUpdated"/>
68 /// </remarks>
54 public event ClientMovement OnClientMovement; 69 public event ClientMovement OnClientMovement;
55 70
56 public delegate void OnTerrainTaintedDelegate(); 71 public delegate void OnTerrainTaintedDelegate();
57 72
73 /// <summary>
74 /// Triggered if the terrain has been edited
75 /// </summary>
76 /// <remarks>
77 /// This gets triggered in <see cref="OpenSim.Region.CoreModules.World.Terrain.CheckForTerrainUpdates"/>
78 /// after it determines that an update has been made.
79 /// </remarks>
58 public event OnTerrainTaintedDelegate OnTerrainTainted; 80 public event OnTerrainTaintedDelegate OnTerrainTainted;
59 81
60 public delegate void OnTerrainTickDelegate(); 82 public delegate void OnTerrainTickDelegate();
61 83
62 public delegate void OnTerrainUpdateDelegate(); 84 /// <summary>
63 85 /// Triggered if the terrain has been edited
86 /// </summary>
87 /// <remarks>
88 /// This gets triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.UpdateTerrain"/>
89 /// but is used by core solely to update the physics engine.
90 /// </remarks>
64 public event OnTerrainTickDelegate OnTerrainTick; 91 public event OnTerrainTickDelegate OnTerrainTick;
65 92
93 public delegate void OnTerrainUpdateDelegate();
94
66 public event OnTerrainUpdateDelegate OnTerrainUpdate; 95 public event OnTerrainUpdateDelegate OnTerrainUpdate;
67 96
68 public delegate void OnBackupDelegate(ISimulationDataService datastore, bool forceBackup); 97 public delegate void OnBackupDelegate(ISimulationDataService datastore, bool forceBackup);
69 98
99 /// <summary>
100 /// Triggered when a region is backed up/persisted to storage
101 /// </summary>
102 /// <remarks>
103 /// This gets triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.Backup"/>
104 /// and is fired before the persistence occurs.
105 /// </remarks>
70 public event OnBackupDelegate OnBackup; 106 public event OnBackupDelegate OnBackup;
71 107
72 public delegate void OnClientConnectCoreDelegate(IClientCore client); 108 public delegate void OnClientConnectCoreDelegate(IClientCore client);
73 109
110 /// <summary>
111 /// Triggered when a new client connects to the scene.
112 /// </summary>
113 /// <remarks>
114 /// This gets triggered in <see cref="TriggerOnNewClient"/>,
115 /// which checks if an instance of <see cref="OpenSim.Framework.IClientAPI"/>
116 /// also implements <see cref="OpenSim.Framework.Client.IClientCore"/> and as such,
117 /// is not triggered by <see cref="OpenSim.Region.OptionalModules.World.NPC">NPCs</see>.
118 /// </remarks>
74 public event OnClientConnectCoreDelegate OnClientConnect; 119 public event OnClientConnectCoreDelegate OnClientConnect;
75 120
76 public delegate void OnNewClientDelegate(IClientAPI client); 121 public delegate void OnNewClientDelegate(IClientAPI client);
@@ -80,33 +125,96 @@ namespace OpenSim.Region.Framework.Scenes
80 /// </summary> 125 /// </summary>
81 /// <remarks> 126 /// <remarks>
82 /// This is triggered for both child and root agent client connections. 127 /// This is triggered for both child and root agent client connections.
128 ///
83 /// Triggered before OnClientLogin. 129 /// Triggered before OnClientLogin.
130 ///
131 /// This is triggered under per-agent lock. So if you want to perform any long-running operations, please
132 /// do this on a separate thread.
84 /// </remarks> 133 /// </remarks>
85 public event OnNewClientDelegate OnNewClient; 134 public event OnNewClientDelegate OnNewClient;
86 135
87 /// <summary> 136 /// <summary>
88 /// Fired if the client entering this sim is doing so as a new login 137 /// Fired if the client entering this sim is doing so as a new login
89 /// </summary> 138 /// </summary>
139 /// <remarks>
140 /// This is triggered under per-agent lock. So if you want to perform any long-running operations, please
141 /// do this on a separate thread.
142 /// </remarks>
90 public event Action<IClientAPI> OnClientLogin; 143 public event Action<IClientAPI> OnClientLogin;
91 144
92 public delegate void OnNewPresenceDelegate(ScenePresence presence); 145 public delegate void OnNewPresenceDelegate(ScenePresence presence);
93 146
147 /// <summary>
148 /// Triggered when a new presence is added to the scene
149 /// </summary>
150 /// <remarks>
151 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> which is used by both
152 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see>
153 /// </remarks>
94 public event OnNewPresenceDelegate OnNewPresence; 154 public event OnNewPresenceDelegate OnNewPresence;
95 155
96 public delegate void OnRemovePresenceDelegate(UUID agentId); 156 public delegate void OnRemovePresenceDelegate(UUID agentId);
97 157
158 /// <summary>
159 /// Triggered when a presence is removed from the scene
160 /// </summary>
161 /// <remarks>
162 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> which is used by both
163 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see>
164 ///
165 /// Triggered under per-agent lock. So if you want to perform any long-running operations, please
166 /// do this on a separate thread.
167 /// </remarks>
98 public event OnRemovePresenceDelegate OnRemovePresence; 168 public event OnRemovePresenceDelegate OnRemovePresence;
99 169
100 public delegate void OnParcelPrimCountUpdateDelegate(); 170 public delegate void OnParcelPrimCountUpdateDelegate();
101 171
172 /// <summary>
173 /// Triggered whenever the prim count may have been altered, or prior
174 /// to an action that requires the current prim count to be accurate.
175 /// </summary>
176 /// <remarks>
177 /// Triggered by <see cref="TriggerParcelPrimCountUpdate"/> in
178 /// <see cref="OpenSim.OpenSimBase.CreateRegion"/>,
179 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandManagementModule.EventManagerOnRequestParcelPrimCountUpdate"/>,
180 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandManagementModule.ClientOnParcelObjectOwnerRequest"/>,
181 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandObject.GetPrimsFree"/>,
182 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandObject.UpdateLandSold"/>,
183 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandObject.DeedToGroup"/>,
184 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandObject.SendLandUpdateToClient"/>
185 /// </remarks>
102 public event OnParcelPrimCountUpdateDelegate OnParcelPrimCountUpdate; 186 public event OnParcelPrimCountUpdateDelegate OnParcelPrimCountUpdate;
103 187
104 public delegate void OnParcelPrimCountAddDelegate(SceneObjectGroup obj); 188 public delegate void OnParcelPrimCountAddDelegate(SceneObjectGroup obj);
105 189
190 /// <summary>
191 /// Triggered in response to <see cref="OnParcelPrimCountUpdate"/> for
192 /// objects that actually contribute to parcel prim count.
193 /// </summary>
194 /// <remarks>
195 /// Triggered by <see cref="TriggerParcelPrimCountAdd"/> in
196 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandManagementModule.EventManagerOnParcelPrimCountUpdate"/>
197 /// </remarks>
106 public event OnParcelPrimCountAddDelegate OnParcelPrimCountAdd; 198 public event OnParcelPrimCountAddDelegate OnParcelPrimCountAdd;
107 199
108 public delegate void OnPluginConsoleDelegate(string[] args); 200 public delegate void OnPluginConsoleDelegate(string[] args);
109 201
202 /// <summary>
203 /// Triggered after <see cref="OpenSim.IApplicationPlugin.PostInitialise"/>
204 /// has been called for all <see cref="OpenSim.IApplicationPlugin"/>
205 /// loaded via <see cref="OpenSim.OpenSimBase.LoadPlugins"/>.
206 /// Handlers for this event are typically used to parse the arguments
207 /// from <see cref="OnPluginConsoleDelegate"/> in order to process or
208 /// filter the arguments and pass them onto <see cref="OpenSim.Region.CoreModules.Framework.InterfaceCommander.Commander.ProcessConsoleCommand"/>
209 /// </summary>
210 /// <remarks>
211 /// Triggered by <see cref="TriggerOnPluginConsole"/> in
212 /// <see cref="Scene.SendCommandToPlugins"/> via
213 /// <see cref="SceneManager.SendCommandToPluginModules"/> via
214 /// <see cref="OpenSim.OpenSimBase.HandleCommanderCommand"/> via
215 /// <see cref="OpenSim.OpenSimBase.AddPluginCommands"/> via
216 /// <see cref="OpenSim.OpenSimBase.StartupSpecific"/>
217 /// </remarks>
110 public event OnPluginConsoleDelegate OnPluginConsole; 218 public event OnPluginConsoleDelegate OnPluginConsole;
111 219
112 /// <summary> 220 /// <summary>
@@ -121,8 +229,28 @@ namespace OpenSim.Region.Framework.Scenes
121 229
122 public delegate void OnSetRootAgentSceneDelegate(UUID agentID, Scene scene); 230 public delegate void OnSetRootAgentSceneDelegate(UUID agentID, Scene scene);
123 231
232 /// <summary>
233 /// Triggered before the grunt work for adding a root agent to a
234 /// scene has been performed (resuming attachment scripts, physics,
235 /// animations etc.)
236 /// </summary>
237 /// <remarks>
238 /// Triggered before <see cref="OnMakeRootAgent"/>
239 /// by <see cref="TriggerSetRootAgentScene"/>
240 /// in <see cref="ScenePresence.MakeRootAgent"/>
241 /// via <see cref="Scene.AgentCrossing"/>
242 /// and <see cref="ScenePresence.CompleteMovement"/>
243 /// </remarks>
124 public event OnSetRootAgentSceneDelegate OnSetRootAgentScene; 244 public event OnSetRootAgentSceneDelegate OnSetRootAgentScene;
125 245
246 /// <summary>
247 /// Triggered after parcel properties have been updated.
248 /// </summary>
249 /// <remarks>
250 /// Triggered by <see cref="TriggerOnParcelPropertiesUpdateRequest"/> in
251 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandManagementModule.ClientOnParcelPropertiesUpdateRequest"/>,
252 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandManagementModule.ProcessPropertiesUpdate"/>
253 /// </remarks>
126 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; 254 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
127 255
128 /// <summary> 256 /// <summary>
@@ -137,13 +265,45 @@ namespace OpenSim.Region.Framework.Scenes
137 /// <summary> 265 /// <summary>
138 /// Fired when an object is touched/grabbed. 266 /// Fired when an object is touched/grabbed.
139 /// </summary> 267 /// </summary>
268 /// <remarks>
140 /// The originalID is the local ID of the part that was actually touched. The localID itself is always that of 269 /// The originalID is the local ID of the part that was actually touched. The localID itself is always that of
141 /// the root part. 270 /// the root part.
271 /// Triggerd in response to <see cref="OpenSim.Framework.IClientAPI.OnGrabObject"/>
272 /// via <see cref="TriggerObjectGrab"/>
273 /// in <see cref="Scene.ProcessObjectGrab"/>
274 /// </remarks>
142 public event ObjectGrabDelegate OnObjectGrab; 275 public event ObjectGrabDelegate OnObjectGrab;
143 public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs); 276 public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
144 277
278 /// <summary>
279 /// Triggered when an object is being touched/grabbed continuously.
280 /// </summary>
281 /// <remarks>
282 /// Triggered in response to <see cref="OpenSim.Framework.IClientAPI.OnGrabUpdate"/>
283 /// via <see cref="TriggerObjectGrabbing"/>
284 /// in <see cref="Scene.ProcessObjectGrabUpdate"/>
285 /// </remarks>
145 public event ObjectGrabDelegate OnObjectGrabbing; 286 public event ObjectGrabDelegate OnObjectGrabbing;
287
288 /// <summary>
289 /// Triggered when an object stops being touched/grabbed.
290 /// </summary>
291 /// <remarks>
292 /// Triggered in response to <see cref="OpenSim.Framework.IClientAPI.OnDeGrabObject"/>
293 /// via <see cref="TriggerObjectDeGrab"/>
294 /// in <see cref="Scene.ProcessObjectDeGrab"/>
295 /// </remarks>
146 public event ObjectDeGrabDelegate OnObjectDeGrab; 296 public event ObjectDeGrabDelegate OnObjectDeGrab;
297
298 /// <summary>
299 /// Triggered when a script resets.
300 /// </summary>
301 /// <remarks>
302 /// Triggered by <see cref="TriggerScriptReset"/>
303 /// in <see cref="Scene.ProcessScriptReset"/>
304 /// via <see cref="OpenSim.Framework.IClientAPI.OnScriptReset"/>
305 /// via <see cref="OpenSim.Region.ClientStack.LindenUDP.LLClientView.HandleScriptReset"/>
306 /// </remarks>
147 public event ScriptResetDelegate OnScriptReset; 307 public event ScriptResetDelegate OnScriptReset;
148 308
149 public event OnPermissionErrorDelegate OnPermissionError; 309 public event OnPermissionErrorDelegate OnPermissionError;
@@ -153,29 +313,105 @@ namespace OpenSim.Region.Framework.Scenes
153 /// </summary> 313 /// </summary>
154 /// <remarks> 314 /// <remarks>
155 /// Occurs after OnNewScript. 315 /// Occurs after OnNewScript.
316 /// Triggered by <see cref="TriggerRezScript"/>
317 /// in <see cref="SceneObjectPartInventory.CreateScriptInstance"/>
156 /// </remarks> 318 /// </remarks>
157 public event NewRezScript OnRezScript; 319 public event NewRezScript OnRezScript;
158 public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource); 320 public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource);
159 321
160 public delegate void RemoveScript(uint localID, UUID itemID); 322 public delegate void RemoveScript(uint localID, UUID itemID);
323
324 /// <summary>
325 /// Triggered when a script is removed from an object.
326 /// </summary>
327 /// <remarks>
328 /// Triggered by <see cref="TriggerRemoveScript"/>
329 /// in <see cref="Scene.RemoveTaskInventory"/>,
330 /// <see cref="Scene.CreateAgentInventoryItemFromTask"/>,
331 /// <see cref="SceneObjectPartInventory.RemoveScriptInstance"/>,
332 /// <see cref="SceneObjectPartInventory.RemoveInventoryItem"/>
333 /// </remarks>
161 public event RemoveScript OnRemoveScript; 334 public event RemoveScript OnRemoveScript;
162 335
163 public delegate void StartScript(uint localID, UUID itemID); 336 public delegate void StartScript(uint localID, UUID itemID);
337
338 /// <summary>
339 /// Triggered when a script starts.
340 /// </summary>
341 /// <remarks>
342 /// Triggered by <see cref="TriggerStartScript"/>
343 /// in <see cref="Scene.SetScriptRunning"/>
344 /// via <see cref="OpenSim.Framework.IClientAPI.OnSetScriptRunning"/>,
345 /// via <see cref="OpenSim.Region.ClientStack.LindenUDP.HandleSetScriptRunning"/>
346 /// </remarks>
164 public event StartScript OnStartScript; 347 public event StartScript OnStartScript;
165 348
166 public delegate void StopScript(uint localID, UUID itemID); 349 public delegate void StopScript(uint localID, UUID itemID);
350
351 /// <summary>
352 /// Triggered when a script stops.
353 /// </summary>
354 /// <remarks>
355 /// Triggered by <see cref="TriggerStopScript"/>,
356 /// in <see cref="SceneObjectPartInventory.CreateScriptInstance"/>,
357 /// <see cref="SceneObjectPartInventory.StopScriptInstance"/>,
358 /// <see cref="Scene.SetScriptRunning"/>
359 /// </remarks>
167 public event StopScript OnStopScript; 360 public event StopScript OnStopScript;
168 361
169 public delegate bool SceneGroupMoved(UUID groupID, Vector3 delta); 362 public delegate bool SceneGroupMoved(UUID groupID, Vector3 delta);
363
364 /// <summary>
365 /// Triggered when an object is moved.
366 /// </summary>
367 /// <remarks>
368 /// Triggered by <see cref="TriggerGroupMove"/>
369 /// in <see cref="SceneObjectGroup.UpdateGroupPosition"/>,
370 /// <see cref="SceneObjectGroup.GrabMovement"/>
371 /// </remarks>
170 public event SceneGroupMoved OnSceneGroupMove; 372 public event SceneGroupMoved OnSceneGroupMove;
171 373
172 public delegate void SceneGroupGrabed(UUID groupID, Vector3 offset, UUID userID); 374 public delegate void SceneGroupGrabed(UUID groupID, Vector3 offset, UUID userID);
375
376 /// <summary>
377 /// Triggered when an object is grabbed.
378 /// </summary>
379 /// <remarks>
380 /// Triggered by <see cref="TriggerGroupGrab"/>
381 /// in <see cref="SceneObjectGroup.OnGrabGroup"/>
382 /// via <see cref="SceneObjectGroup.ObjectGrabHandler"/>
383 /// via <see cref="Scene.ProcessObjectGrab"/>
384 /// via <see cref="OpenSim.Framework.IClientAPI.OnGrabObject"/>
385 /// via <see cref="OpenSim.Region.ClientStack.LindenUDP.LLClientView.HandleObjectGrab"/>
386 /// </remarks>
173 public event SceneGroupGrabed OnSceneGroupGrab; 387 public event SceneGroupGrabed OnSceneGroupGrab;
174 388
175 public delegate bool SceneGroupSpinStarted(UUID groupID); 389 public delegate bool SceneGroupSpinStarted(UUID groupID);
390
391 /// <summary>
392 /// Triggered when an object starts to spin.
393 /// </summary>
394 /// <remarks>
395 /// Triggered by <see cref="TriggerGroupSpinStart"/>
396 /// in <see cref="SceneObjectGroup.SpinStart"/>
397 /// via <see cref="SceneGraph.SpinStart"/>
398 /// via <see cref="OpenSim.Framework.IClientAPI.OnSpinStart"/>
399 /// via <see cref="OpenSim.Region.ClientStack.LindenUDP.LLClientView.HandleObjectSpinStart"/>
400 /// </remarks>
176 public event SceneGroupSpinStarted OnSceneGroupSpinStart; 401 public event SceneGroupSpinStarted OnSceneGroupSpinStart;
177 402
178 public delegate bool SceneGroupSpun(UUID groupID, Quaternion rotation); 403 public delegate bool SceneGroupSpun(UUID groupID, Quaternion rotation);
404
405 /// <summary>
406 /// Triggered when an object is being spun.
407 /// </summary>
408 /// <remarks>
409 /// Triggered by <see cref="TriggerGroupSpin"/>
410 /// in <see cref="SceneObjectGroup.SpinMovement"/>
411 /// via <see cref="SceneGraph.SpinObject"/>
412 /// via <see cref="OpenSim.Framework.IClientAPI.OnSpinUpdate"/>
413 /// via <see cref="OpenSim.Region.ClientStack.LindenUDP.LLClientView.HandleObjectSpinUpdate"/>
414 /// </remarks>
179 public event SceneGroupSpun OnSceneGroupSpin; 415 public event SceneGroupSpun OnSceneGroupSpin;
180 416
181 public delegate void LandObjectAdded(ILandObject newParcel); 417 public delegate void LandObjectAdded(ILandObject newParcel);
@@ -204,6 +440,9 @@ namespace OpenSim.Region.Framework.Scenes
204 /// </summary> 440 /// </summary>
205 /// <remarks> 441 /// <remarks>
206 /// At the point of firing, the scene still contains the client's scene presence. 442 /// At the point of firing, the scene still contains the client's scene presence.
443 ///
444 /// This is triggered under per-agent lock. So if you want to perform any long-running operations, please
445 /// do this on a separate thread.
207 /// </remarks> 446 /// </remarks>
208 public event ClientClosed OnClientClosed; 447 public event ClientClosed OnClientClosed;
209 448
@@ -214,6 +453,9 @@ namespace OpenSim.Region.Framework.Scenes
214 /// </summary> 453 /// </summary>
215 /// <remarks> 454 /// <remarks>
216 /// Occurs before OnRezScript 455 /// Occurs before OnRezScript
456 /// Triggered by <see cref="TriggerNewScript"/>
457 /// in <see cref="Scene.RezScriptFromAgentInventory"/>,
458 /// <see cref="Scene.RezNewScript"/>
217 /// </remarks> 459 /// </remarks>
218 public event NewScript OnNewScript; 460 public event NewScript OnNewScript;
219 461
@@ -248,6 +490,12 @@ namespace OpenSim.Region.Framework.Scenes
248 /// </summary> 490 /// </summary>
249 /// <remarks> 491 /// <remarks>
250 /// Triggered after the scene receives a client's upload of an updated script and has stored it in an asset. 492 /// Triggered after the scene receives a client's upload of an updated script and has stored it in an asset.
493 /// Triggered by <see cref="TriggerUpdateScript"/>
494 /// in <see cref="Scene.CapsUpdateTaskInventoryScriptAsset"/>
495 /// via <see cref="Scene.CapsUpdateTaskInventoryScriptAsset"/>
496 /// via <see cref="OpenSim.Region.ClientStack.Linden.BunchOfCaps.TaskScriptUpdated"/>
497 /// via <see cref="OpenSim.Region.ClientStack.Linden.TaskInventoryScriptUpdater.OnUpLoad"/>
498 /// via <see cref="OpenSim.Region.ClientStack.Linden.TaskInventoryScriptUpdater.uploaderCaps"/>
251 /// </remarks> 499 /// </remarks>
252 public event UpdateScript OnUpdateScript; 500 public event UpdateScript OnUpdateScript;
253 501
@@ -273,48 +521,203 @@ namespace OpenSim.Region.Framework.Scenes
273 } 521 }
274 522
275 /// <summary> 523 /// <summary>
524 /// Triggered when some scene object properties change.
525 /// </summary>
526 /// <remarks>
276 /// ScriptChangedEvent is fired when a scene object property that a script might be interested 527 /// ScriptChangedEvent is fired when a scene object property that a script might be interested
277 /// in (such as color, scale or inventory) changes. Only enough information sent is for the LSL changed event. 528 /// in (such as color, scale or inventory) changes. Only enough information sent is for the LSL changed event.
278 /// This is not an indication that the script has changed (see OnUpdateScript for that). 529 /// This is not an indication that the script has changed (see OnUpdateScript for that).
279 /// This event is sent to a script to tell it that some property changed on 530 /// This event is sent to a script to tell it that some property changed on
280 /// the object the script is in. See http://lslwiki.net/lslwiki/wakka.php?wakka=changed . 531 /// the object the script is in. See http://lslwiki.net/lslwiki/wakka.php?wakka=changed .
281 /// </summary> 532 /// Triggered by <see cref="TriggerOnScriptChangedEvent"/>
533 /// in <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.TeleportAgentWithinRegion"/>,
534 /// <see cref="SceneObjectPart.TriggerScriptChangedEvent"/>
535 /// </remarks>
282 public event ScriptChangedEvent OnScriptChangedEvent; 536 public event ScriptChangedEvent OnScriptChangedEvent;
283 public delegate void ScriptChangedEvent(uint localID, uint change); 537 public delegate void ScriptChangedEvent(uint localID, uint change);
284 538
285 public delegate void ScriptControlEvent(UUID item, UUID avatarID, uint held, uint changed); 539 public delegate void ScriptControlEvent(UUID item, UUID avatarID, uint held, uint changed);
540
541 /// <summary>
542 /// Triggered when a script receives control input from an agent.
543 /// </summary>
544 /// <remarks>
545 /// Triggered by <see cref="TriggerControlEvent"/>
546 /// in <see cref="ScenePresence.SendControlsToScripts"/>
547 /// via <see cref="ScenePresence.HandleAgentUpdate"/>
548 /// via <see cref="OpenSim.Framework.IClientAPI.OnAgentUpdate"/>
549 /// via <see cref="OpenSim.Region.ClientStack.LindenUDP.LLClientView.HandleAgentUpdate"/>
550 /// </remarks>
286 public event ScriptControlEvent OnScriptControlEvent; 551 public event ScriptControlEvent OnScriptControlEvent;
287 552
288 public delegate void ScriptAtTargetEvent(uint localID, uint handle, Vector3 targetpos, Vector3 atpos); 553 public delegate void ScriptAtTargetEvent(uint localID, uint handle, Vector3 targetpos, Vector3 atpos);
554
555 /// <summary>
556 /// Triggered when an object has arrived within a tolerance distance
557 /// of a motion target.
558 /// </summary>
559 /// <remarks>
560 /// Triggered by <see cref="TriggerAtTargetEvent"/>
561 /// in <see cref="SceneObjectGroup.checkAtTargets"/>
562 /// via <see cref="SceneObjectGroup.ScheduleGroupForFullUpdate"/>,
563 /// <see cref="Scene.CheckAtTargets"/> via <see cref="Scene.Update"/>
564 /// </remarks>
289 public event ScriptAtTargetEvent OnScriptAtTargetEvent; 565 public event ScriptAtTargetEvent OnScriptAtTargetEvent;
290 566
291 public delegate void ScriptNotAtTargetEvent(uint localID); 567 public delegate void ScriptNotAtTargetEvent(uint localID);
568
569 /// <summary>
570 /// Triggered when an object has a motion target but has not arrived
571 /// within a tolerance distance.
572 /// </summary>
573 /// <remarks>
574 /// Triggered by <see cref="TriggerNotAtTargetEvent"/>
575 /// in <see cref="SceneObjectGroup.checkAtTargets"/>
576 /// via <see cref="SceneObjectGroup.ScheduleGroupForFullUpdate"/>,
577 /// <see cref="Scene.CheckAtTargets"/> via <see cref="Scene.Update"/>
578 /// </remarks>
292 public event ScriptNotAtTargetEvent OnScriptNotAtTargetEvent; 579 public event ScriptNotAtTargetEvent OnScriptNotAtTargetEvent;
293 580
294 public delegate void ScriptAtRotTargetEvent(uint localID, uint handle, Quaternion targetrot, Quaternion atrot); 581 public delegate void ScriptAtRotTargetEvent(uint localID, uint handle, Quaternion targetrot, Quaternion atrot);
582
583 /// <summary>
584 /// Triggered when an object has arrived within a tolerance rotation
585 /// of a rotation target.
586 /// </summary>
587 /// <remarks>
588 /// Triggered by <see cref="TriggerAtRotTargetEvent"/>
589 /// in <see cref="SceneObjectGroup.checkAtTargets"/>
590 /// via <see cref="SceneObjectGroup.ScheduleGroupForFullUpdate"/>,
591 /// <see cref="Scene.CheckAtTargets"/> via <see cref="Scene.Update"/>
592 /// </remarks>
295 public event ScriptAtRotTargetEvent OnScriptAtRotTargetEvent; 593 public event ScriptAtRotTargetEvent OnScriptAtRotTargetEvent;
296 594
297 public delegate void ScriptNotAtRotTargetEvent(uint localID); 595 public delegate void ScriptNotAtRotTargetEvent(uint localID);
596
597 /// <summary>
598 /// Triggered when an object has a rotation target but has not arrived
599 /// within a tolerance rotation.
600 /// </summary>
601 /// <remarks>
602 /// Triggered by <see cref="TriggerNotAtRotTargetEvent"/>
603 /// in <see cref="SceneObjectGroup.checkAtTargets"/>
604 /// via <see cref="SceneObjectGroup.ScheduleGroupForFullUpdate"/>,
605 /// <see cref="Scene.CheckAtTargets"/> via <see cref="Scene.Update"/>
606 /// </remarks>
298 public event ScriptNotAtRotTargetEvent OnScriptNotAtRotTargetEvent; 607 public event ScriptNotAtRotTargetEvent OnScriptNotAtRotTargetEvent;
299 608
300 public delegate void ScriptColliding(uint localID, ColliderArgs colliders); 609 public delegate void ScriptColliding(uint localID, ColliderArgs colliders);
610
611 /// <summary>
612 /// Triggered when a physical collision has started between a prim
613 /// and something other than the region terrain.
614 /// </summary>
615 /// <remarks>
616 /// Triggered by <see cref="TriggerScriptCollidingStart"/>
617 /// in <see cref="SceneObjectPart.SendCollisionEvent"/>
618 /// via <see cref="SceneObjectPart.PhysicsCollision"/>
619 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
620 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
621 /// </remarks>
301 public event ScriptColliding OnScriptColliderStart; 622 public event ScriptColliding OnScriptColliderStart;
623
624 /// <summary>
625 /// Triggered when something that previously collided with a prim has
626 /// not stopped colliding with it.
627 /// </summary>
628 /// <remarks>
629 /// <seealso cref="OnScriptColliderStart"/>
630 /// Triggered by <see cref="TriggerScriptColliding"/>
631 /// in <see cref="SceneObjectPart.SendCollisionEvent"/>
632 /// via <see cref="SceneObjectPart.PhysicsCollision"/>
633 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
634 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
635 /// </remarks>
302 public event ScriptColliding OnScriptColliding; 636 public event ScriptColliding OnScriptColliding;
637
638 /// <summary>
639 /// Triggered when something that previously collided with a prim has
640 /// stopped colliding with it.
641 /// </summary>
642 /// <remarks>
643 /// Triggered by <see cref="TriggerScriptCollidingEnd"/>
644 /// in <see cref="SceneObjectPart.SendCollisionEvent"/>
645 /// via <see cref="SceneObjectPart.PhysicsCollision"/>
646 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
647 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
648 /// </remarks>
303 public event ScriptColliding OnScriptCollidingEnd; 649 public event ScriptColliding OnScriptCollidingEnd;
650
651 /// <summary>
652 /// Triggered when a physical collision has started between an object
653 /// and the region terrain.
654 /// </summary>
655 /// <remarks>
656 /// Triggered by <see cref="TriggerScriptLandCollidingStart"/>
657 /// in <see cref="SceneObjectPart.SendLandCollisionEvent"/>
658 /// via <see cref="SceneObjectPart.PhysicsCollision"/>
659 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
660 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
661 /// </remarks>
304 public event ScriptColliding OnScriptLandColliderStart; 662 public event ScriptColliding OnScriptLandColliderStart;
663
664 /// <summary>
665 /// Triggered when an object that previously collided with the region
666 /// terrain has not yet stopped colliding with it.
667 /// </summary>
668 /// <remarks>
669 /// Triggered by <see cref="TriggerScriptLandColliding"/>
670 /// in <see cref="SceneObjectPart.SendLandCollisionEvent"/>
671 /// via <see cref="SceneObjectPart.PhysicsCollision"/>
672 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
673 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
674 /// </remarks>
305 public event ScriptColliding OnScriptLandColliding; 675 public event ScriptColliding OnScriptLandColliding;
676
677 /// <summary>
678 /// Triggered when an object that previously collided with the region
679 /// terrain has stopped colliding with it.
680 /// </summary>
681 /// <remarks>
682 /// Triggered by <see cref="TriggerScriptLandCollidingEnd"/>
683 /// in <see cref="SceneObjectPart.SendLandCollisionEvent"/>
684 /// via <see cref="SceneObjectPart.PhysicsCollision"/>
685 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
686 /// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
687 /// </remarks>
306 public event ScriptColliding OnScriptLandColliderEnd; 688 public event ScriptColliding OnScriptLandColliderEnd;
307 689
308 public delegate void OnMakeChildAgentDelegate(ScenePresence presence); 690 public delegate void OnMakeChildAgentDelegate(ScenePresence presence);
691
692 /// <summary>
693 /// Triggered when an agent has been made a child agent of a scene.
694 /// </summary>
695 /// <remarks>
696 /// Triggered by <see cref="TriggerOnMakeChildAgent"/>
697 /// in <see cref="ScenePresence.MakeChildAgent"/>
698 /// via <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.CrossAgentToNewRegionAsync"/>,
699 /// <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.DoTeleport"/>,
700 /// <see cref="OpenSim.Region.CoreModules.InterGrid.KillAUser.ShutdownNoLogout"/>
701 /// </remarks>
309 public event OnMakeChildAgentDelegate OnMakeChildAgent; 702 public event OnMakeChildAgentDelegate OnMakeChildAgent;
310 703
311 public delegate void OnSaveNewWindlightProfileDelegate(); 704 public delegate void OnSaveNewWindlightProfileDelegate();
312 public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionLightShareData wl, UUID user); 705 public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionLightShareData wl, UUID user);
313 706
314 /// <summary> 707 /// <summary>
708 /// Triggered after the grunt work for adding a root agent to a
709 /// scene has been performed (resuming attachment scripts, physics,
710 /// animations etc.)
711 /// </summary>
712 /// <remarks>
315 /// This event is on the critical path for transferring an avatar from one region to another. Try and do 713 /// This event is on the critical path for transferring an avatar from one region to another. Try and do
316 /// as little work on this event as possible, or do work asynchronously. 714 /// as little work on this event as possible, or do work asynchronously.
317 /// </summary> 715 /// Triggered after <see cref="OnSetRootAgentScene"/>
716 /// by <see cref="TriggerOnMakeRootAgent"/>
717 /// in <see cref="ScenePresence.MakeRootAgent"/>
718 /// via <see cref="Scene.AgentCrossing"/>
719 /// and <see cref="ScenePresence.CompleteMovement"/>
720 /// </remarks>
318 public event Action<ScenePresence> OnMakeRootAgent; 721 public event Action<ScenePresence> OnMakeRootAgent;
319 722
320 public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted; 723 public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted;
@@ -340,9 +743,17 @@ namespace OpenSim.Region.Framework.Scenes
340 public event AvatarKillData OnAvatarKilled; 743 public event AvatarKillData OnAvatarKilled;
341 public delegate void AvatarKillData(uint KillerLocalID, ScenePresence avatar); 744 public delegate void AvatarKillData(uint KillerLocalID, ScenePresence avatar);
342 745
343// public delegate void ScriptTimerEvent(uint localID, double timerinterval); 746 /*
344 747 public delegate void ScriptTimerEvent(uint localID, double timerinterval);
345// public event ScriptTimerEvent OnScriptTimerEvent; 748 /// <summary>
749 /// Used to be triggered when the LSL timer event fires.
750 /// </summary>
751 /// <remarks>
752 /// Triggered by <see cref="TriggerTimerEvent"/>
753 /// via <see cref="SceneObjectPart.handleTimerAccounting"/>
754 /// </remarks>
755 public event ScriptTimerEvent OnScriptTimerEvent;
756 */
346 757
347 public delegate void EstateToolsSunUpdate(ulong regionHandle, bool FixedTime, bool EstateSun, float LindenHour); 758 public delegate void EstateToolsSunUpdate(ulong regionHandle, bool FixedTime, bool EstateSun, float LindenHour);
348 public delegate void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID); 759 public delegate void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID);
@@ -352,12 +763,27 @@ namespace OpenSim.Region.Framework.Scenes
352 /// <summary> 763 /// <summary>
353 /// Triggered when an object is added to the scene. 764 /// Triggered when an object is added to the scene.
354 /// </summary> 765 /// </summary>
766 /// <remarks>
767 /// Triggered by <see cref="TriggerObjectAddedToScene"/>
768 /// in <see cref="Scene.AddNewSceneObject"/>,
769 /// <see cref="Scene.DuplicateObject"/>,
770 /// <see cref="Scene.doObjectDuplicateOnRay"/>
771 /// </remarks>
355 public event Action<SceneObjectGroup> OnObjectAddedToScene; 772 public event Action<SceneObjectGroup> OnObjectAddedToScene;
356 773
357 /// <summary> 774 /// <summary>
358 /// Triggered when an object is removed from the scene. 775 /// Delegate for <see cref="OnObjectBeingRemovedFromScene"/>
359 /// </summary> 776 /// </summary>
777 /// <param name="obj">The object being removed from the scene</param>
360 public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj); 778 public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj);
779
780 /// <summary>
781 /// Triggered when an object is removed from the scene.
782 /// </summary>
783 /// <remarks>
784 /// Triggered by <see cref="TriggerObjectBeingRemovedFromScene"/>
785 /// in <see cref="Scene.DeleteSceneObject"/>
786 /// </remarks>
361 public event ObjectBeingRemovedFromScene OnObjectBeingRemovedFromScene; 787 public event ObjectBeingRemovedFromScene OnObjectBeingRemovedFromScene;
362 788
363 public delegate void NoticeNoLandDataFromStorage(); 789 public delegate void NoticeNoLandDataFromStorage();
@@ -373,9 +799,27 @@ namespace OpenSim.Region.Framework.Scenes
373 public event RequestParcelPrimCountUpdate OnRequestParcelPrimCountUpdate; 799 public event RequestParcelPrimCountUpdate OnRequestParcelPrimCountUpdate;
374 800
375 public delegate void ParcelPrimCountTainted(); 801 public delegate void ParcelPrimCountTainted();
802
803 /// <summary>
804 /// Triggered when the parcel prim count has been altered.
805 /// </summary>
806 /// <remarks>
807 /// Triggered by <see cref="TriggerParcelPrimCountTainted"/> in
808 /// <see cref="OpenSim.Region.CoreModules.Avatar.Attachments.AttachmentsModule.DetachSingleAttachmentToGround"/>,
809 /// <see cref="OpenSim.Region.CoreModules.Avatar.Attachments.AttachmentsModule.AttachToAgent"/>,
810 /// <see cref="Scene.DeleteSceneObject"/>,
811 /// <see cref="Scene.SelectPrim"/>,
812 /// <see cref="Scene.DeselectPrim"/>,
813 /// <see cref="SceneObjectGroup.UpdatePrimFlags"/>,
814 /// <see cref="SceneObjectGroup.AbsolutePosition"/>
815 /// </remarks>
376 public event ParcelPrimCountTainted OnParcelPrimCountTainted; 816 public event ParcelPrimCountTainted OnParcelPrimCountTainted;
377 public event GetScriptRunning OnGetScriptRunning; 817 public event GetScriptRunning OnGetScriptRunning;
378 818
819 public delegate void ThrottleUpdate(ScenePresence scenePresence);
820
821 public event ThrottleUpdate OnThrottleUpdate;
822
379 /// <summary> 823 /// <summary>
380 /// RegisterCapsEvent is called by Scene after the Caps object 824 /// RegisterCapsEvent is called by Scene after the Caps object
381 /// has been instantiated and before it is return to the 825 /// has been instantiated and before it is return to the
@@ -432,7 +876,7 @@ namespace OpenSim.Region.Framework.Scenes
432 /// the scripts may not have started yet 876 /// the scripts may not have started yet
433 /// Message is non empty string if there were problems loading the oar file 877 /// Message is non empty string if there were problems loading the oar file
434 /// </summary> 878 /// </summary>
435 public delegate void OarFileLoaded(Guid guid, string message); 879 public delegate void OarFileLoaded(Guid guid, List<UUID> loadedScenes, string message);
436 public event OarFileLoaded OnOarFileLoaded; 880 public event OarFileLoaded OnOarFileLoaded;
437 881
438 /// <summary> 882 /// <summary>
@@ -485,10 +929,13 @@ namespace OpenSim.Region.Framework.Scenes
485 /// <param name="copy"></param> 929 /// <param name="copy"></param>
486 /// <param name="original"></param> 930 /// <param name="original"></param>
487 /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param> 931 /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
932 /// <remarks>
933 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.SceneObjectPart.Copy"/>
934 /// </remarks>
488 public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy; 935 public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy;
489 public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed); 936 public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed);
490 937
491 public delegate void SceneObjectPartUpdated(SceneObjectPart sop); 938 public delegate void SceneObjectPartUpdated(SceneObjectPart sop, bool full);
492 public event SceneObjectPartUpdated OnSceneObjectPartUpdated; 939 public event SceneObjectPartUpdated OnSceneObjectPartUpdated;
493 940
494 public delegate void ScenePresenceUpdated(ScenePresence sp); 941 public delegate void ScenePresenceUpdated(ScenePresence sp);
@@ -526,9 +973,28 @@ namespace OpenSim.Region.Framework.Scenes
526 public event PrimsLoaded OnPrimsLoaded; 973 public event PrimsLoaded OnPrimsLoaded;
527 974
528 public delegate void TeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout); 975 public delegate void TeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout);
976
977 /// <summary>
978 /// Triggered when a teleport starts
979 /// </summary>
980 /// <remarks>
981 /// Triggered by <see cref="TriggerTeleportStart"/>
982 /// in <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.CreateAgent"/>
983 /// and <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule.CreateAgent"/>
984 /// via <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.DoTeleport"/>
985 /// </remarks>
529 public event TeleportStart OnTeleportStart; 986 public event TeleportStart OnTeleportStart;
530 987
531 public delegate void TeleportFail(IClientAPI client, bool gridLogout); 988 public delegate void TeleportFail(IClientAPI client, bool gridLogout);
989
990 /// <summary>
991 /// Trigered when a teleport fails.
992 /// </summary>
993 /// <remarks>
994 /// Triggered by <see cref="TriggerTeleportFail"/>
995 /// in <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.Fail"/>
996 /// via <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.DoTeleport"/>
997 /// </remarks>
532 public event TeleportFail OnTeleportFail; 998 public event TeleportFail OnTeleportFail;
533 999
534 public class MoneyTransferArgs : EventArgs 1000 public class MoneyTransferArgs : EventArgs
@@ -536,7 +1002,9 @@ namespace OpenSim.Region.Framework.Scenes
536 public UUID sender; 1002 public UUID sender;
537 public UUID receiver; 1003 public UUID receiver;
538 1004
539 // Always false. The SL protocol sucks. 1005 /// <summary>
1006 /// Always false. The SL protocol sucks.
1007 /// </summary>
540 public bool authenticated = false; 1008 public bool authenticated = false;
541 1009
542 public int amount; 1010 public int amount;
@@ -593,8 +1061,29 @@ namespace OpenSim.Region.Framework.Scenes
593 1061
594 public delegate void LandBuy(Object sender, LandBuyArgs e); 1062 public delegate void LandBuy(Object sender, LandBuyArgs e);
595 1063
1064 /// <summary>
1065 /// Triggered when an attempt to transfer grid currency occurs
1066 /// </summary>
1067 /// <remarks>
1068 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.ProcessMoneyTransferRequest"/>
1069 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientGridEvents"/>
1070 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientEvents"/>
1071 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/>
1072 /// </remarks>
596 public event MoneyTransferEvent OnMoneyTransfer; 1073 public event MoneyTransferEvent OnMoneyTransfer;
1074
1075 /// <summary>
1076 /// Triggered after after <see cref="OnValidateLandBuy"/>
1077 /// </summary>
597 public event LandBuy OnLandBuy; 1078 public event LandBuy OnLandBuy;
1079
1080 /// <summary>
1081 /// Triggered to allow or prevent a real estate transaction
1082 /// </summary>
1083 /// <remarks>
1084 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.ProcessParcelBuy"/>
1085 /// <seealso cref="OpenSim.Region.OptionalModules.World.MoneyModule.SampleMoneyModule.ValidateLandBuy"/>
1086 /// </remarks>
598 public event LandBuy OnValidateLandBuy; 1087 public event LandBuy OnValidateLandBuy;
599 1088
600 public void TriggerOnAttach(uint localID, UUID itemID, UUID avatarID) 1089 public void TriggerOnAttach(uint localID, UUID itemID, UUID avatarID)
@@ -2031,7 +2520,11 @@ namespace OpenSim.Region.Framework.Scenes
2031 } 2520 }
2032 } 2521 }
2033 2522
2034 // this lets us keep track of nasty script events like timer, etc. 2523 /// <summary>
2524 /// this lets us keep track of nasty script events like timer, etc.
2525 /// </summary>
2526 /// <param name="objLocalID"></param>
2527 /// <param name="Interval"></param>
2035 public void TriggerTimerEvent(uint objLocalID, double Interval) 2528 public void TriggerTimerEvent(uint objLocalID, double Interval)
2036 { 2529 {
2037 throw new NotImplementedException("TriggerTimerEvent was thought to be not used anymore and the registration for the event from scene object part has been commented out due to a memory leak"); 2530 throw new NotImplementedException("TriggerTimerEvent was thought to be not used anymore and the registration for the event from scene object part has been commented out due to a memory leak");
@@ -2093,7 +2586,7 @@ namespace OpenSim.Region.Framework.Scenes
2093 return 6; 2586 return 6;
2094 } 2587 }
2095 2588
2096 public void TriggerOarFileLoaded(Guid requestId, string message) 2589 public void TriggerOarFileLoaded(Guid requestId, List<UUID> loadedScenes, string message)
2097 { 2590 {
2098 OarFileLoaded handlerOarFileLoaded = OnOarFileLoaded; 2591 OarFileLoaded handlerOarFileLoaded = OnOarFileLoaded;
2099 if (handlerOarFileLoaded != null) 2592 if (handlerOarFileLoaded != null)
@@ -2102,7 +2595,7 @@ namespace OpenSim.Region.Framework.Scenes
2102 { 2595 {
2103 try 2596 try
2104 { 2597 {
2105 d(requestId, message); 2598 d(requestId, loadedScenes, message);
2106 } 2599 }
2107 catch (Exception e) 2600 catch (Exception e)
2108 { 2601 {
@@ -2387,7 +2880,7 @@ namespace OpenSim.Region.Framework.Scenes
2387 } 2880 }
2388 } 2881 }
2389 2882
2390 public void TriggerSceneObjectPartUpdated(SceneObjectPart sop) 2883 public void TriggerSceneObjectPartUpdated(SceneObjectPart sop, bool full)
2391 { 2884 {
2392 SceneObjectPartUpdated handler = OnSceneObjectPartUpdated; 2885 SceneObjectPartUpdated handler = OnSceneObjectPartUpdated;
2393 if (handler != null) 2886 if (handler != null)
@@ -2396,7 +2889,7 @@ namespace OpenSim.Region.Framework.Scenes
2396 { 2889 {
2397 try 2890 try
2398 { 2891 {
2399 d(sop); 2892 d(sop, full);
2400 } 2893 }
2401 catch (Exception e) 2894 catch (Exception e)
2402 { 2895 {
@@ -2641,5 +3134,14 @@ namespace OpenSim.Region.Framework.Scenes
2641 } 3134 }
2642 } 3135 }
2643 } 3136 }
3137
3138 public void TriggerThrottleUpdate(ScenePresence scenePresence)
3139 {
3140 ThrottleUpdate handler = OnThrottleUpdate;
3141 if (handler != null)
3142 {
3143 handler(scenePresence);
3144 }
3145 }
2644 } 3146 }
2645} 3147}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 906c1ee..c9d1205 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -93,7 +93,7 @@ namespace OpenSim.Region.Framework.Scenes
93 /// </summary> 93 /// </summary>
94 public void StartScripts() 94 public void StartScripts()
95 { 95 {
96 m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName); 96// m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName);
97 97
98 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>(); 98 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
99 99
@@ -1469,7 +1469,7 @@ namespace OpenSim.Region.Framework.Scenes
1469 return newFolderID; 1469 return newFolderID;
1470 } 1470 }
1471 1471
1472 private void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems) 1472 public void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems)
1473 { 1473 {
1474 if (folder == null) 1474 if (folder == null)
1475 return; 1475 return;
@@ -1954,8 +1954,19 @@ namespace OpenSim.Region.Framework.Scenes
1954 } 1954 }
1955 } 1955 }
1956 1956
1957 public virtual void DeRezObjects(IClientAPI remoteClient, List<uint> localIDs, 1957 /// <summary>
1958 UUID groupID, DeRezAction action, UUID destinationID) 1958 /// Derez one or more objects from the scene.
1959 /// </summary>
1960 /// <remarks>
1961 /// Won't actually remove the scene object in the case where the object is being copied to a user inventory.
1962 /// </remarks>
1963 /// <param name='remoteClient'>Client requesting derez</param>
1964 /// <param name='localIDs'>Local ids of root parts of objects to delete.</param>
1965 /// <param name='groupID'>Not currently used. Here because the client passes this to us.</param>
1966 /// <param name='action'>DeRezAction</param>
1967 /// <param name='destinationID'>User folder ID to place derezzed object</param>
1968 public virtual void DeRezObjects(
1969 IClientAPI remoteClient, List<uint> localIDs, UUID groupID, DeRezAction action, UUID destinationID)
1959 { 1970 {
1960 // First, see of we can perform the requested action and 1971 // First, see of we can perform the requested action and
1961 // build a list of eligible objects 1972 // build a list of eligible objects
@@ -1997,6 +2008,9 @@ namespace OpenSim.Region.Framework.Scenes
1997 // If child prims have invalid perms, fix them 2008 // If child prims have invalid perms, fix them
1998 grp.AdjustChildPrimPermissions(); 2009 grp.AdjustChildPrimPermissions();
1999 2010
2011 // If child prims have invalid perms, fix them
2012 grp.AdjustChildPrimPermissions();
2013
2000 if (remoteClient == null) 2014 if (remoteClient == null)
2001 { 2015 {
2002 // Autoreturn has a null client. Nothing else does. So 2016 // Autoreturn has a null client. Nothing else does. So
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index e970543..ce6415a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -38,8 +38,20 @@ namespace OpenSim.Region.Framework.Scenes
38{ 38{
39 public partial class Scene 39 public partial class Scene
40 { 40 {
41 /// <summary>
42 /// Send chat to listeners.
43 /// </summary>
44 /// <param name='message'></param>
45 /// <param name='type'>/param>
46 /// <param name='channel'></param>
47 /// <param name='fromPos'></param>
48 /// <param name='fromName'></param>
49 /// <param name='fromID'></param>
50 /// <param name='targetID'></param>
51 /// <param name='fromAgent'></param>
52 /// <param name='broadcast'></param>
41 public void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, 53 public void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
42 UUID fromID, bool fromAgent, bool broadcast, UUID destination) 54 UUID fromID, UUID targetID, bool fromAgent, bool broadcast)
43 { 55 {
44 OSChatMessage args = new OSChatMessage(); 56 OSChatMessage args = new OSChatMessage();
45 57
@@ -49,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes
49 args.Position = fromPos; 61 args.Position = fromPos;
50 args.SenderUUID = fromID; 62 args.SenderUUID = fromID;
51 args.Scene = this; 63 args.Scene = this;
52 args.Destination = destination; 64 args.Destination = targetID;
53 65
54 if (fromAgent) 66 if (fromAgent)
55 { 67 {
@@ -66,6 +78,10 @@ namespace OpenSim.Region.Framework.Scenes
66 args.From = fromName; 78 args.From = fromName;
67 //args. 79 //args.
68 80
81// m_log.DebugFormat(
82// "[SCENE]: Sending message {0} on channel {1}, type {2} from {3}, broadcast {4}",
83// args.Message.Replace("\n", "\\n"), args.Channel, args.Type, fromName, broadcast);
84
69 if (broadcast) 85 if (broadcast)
70 EventManager.TriggerOnChatBroadcast(this, args); 86 EventManager.TriggerOnChatBroadcast(this, args);
71 else 87 else
@@ -75,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes
75 protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, 91 protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
76 UUID fromID, bool fromAgent, bool broadcast) 92 UUID fromID, bool fromAgent, bool broadcast)
77 { 93 {
78 SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, broadcast, UUID.Zero); 94 SimChat(message, type, channel, fromPos, fromName, fromID, UUID.Zero, fromAgent, broadcast);
79 } 95 }
80 96
81 /// <summary> 97 /// <summary>
@@ -543,7 +559,7 @@ namespace OpenSim.Region.Framework.Scenes
543 if (!InventoryService.AddFolder(folder)) 559 if (!InventoryService.AddFolder(folder))
544 { 560 {
545 m_log.WarnFormat( 561 m_log.WarnFormat(
546 "[AGENT INVENTORY]: Failed to move create folder for user {0} {1}", 562 "[AGENT INVENTORY]: Failed to create folder for user {0} {1}",
547 remoteClient.Name, remoteClient.AgentId); 563 remoteClient.Name, remoteClient.AgentId);
548 } 564 }
549 } 565 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 649d545..c99e37e 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; }
@@ -103,8 +108,31 @@ namespace OpenSim.Region.Framework.Scenes
103 /// </summary> 108 /// </summary>
104 public bool CollidablePrims { get; private set; } 109 public bool CollidablePrims { get; private set; }
105 110
111 /// <summary>
112 /// Minimum value of the size of a non-physical prim in each axis
113 /// </summary>
114 public float m_minNonphys = 0.001f;
115
116 /// <summary>
117 /// Maximum value of the size of a non-physical prim in each axis
118 /// </summary>
106 public float m_maxNonphys = 256; 119 public float m_maxNonphys = 256;
120
121 /// <summary>
122 /// Minimum value of the size of a physical prim in each axis
123 /// </summary>
124 public float m_minPhys = 0.01f;
125
126 /// <summary>
127 /// Maximum value of the size of a physical prim in each axis
128 /// </summary>
107 public float m_maxPhys = 10; 129 public float m_maxPhys = 10;
130
131 /// <summary>
132 /// Max prims an object will hold
133 /// </summary>
134 public int m_linksetCapacity = 0;
135
108 public bool m_clampPrimSize; 136 public bool m_clampPrimSize;
109 public bool m_trustBinaries; 137 public bool m_trustBinaries;
110 public bool m_allowScriptCrossings; 138 public bool m_allowScriptCrossings;
@@ -149,7 +177,6 @@ namespace OpenSim.Region.Framework.Scenes
149 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 177 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
150 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 178 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
151 protected string m_simulatorVersion = "OpenSimulator Server"; 179 protected string m_simulatorVersion = "OpenSimulator Server";
152 protected ModuleLoader m_moduleLoader;
153 protected AgentCircuitManager m_authenticateHandler; 180 protected AgentCircuitManager m_authenticateHandler;
154 protected SceneCommunicationService m_sceneGridService; 181 protected SceneCommunicationService m_sceneGridService;
155 protected ISnmpModule m_snmpService = null; 182 protected ISnmpModule m_snmpService = null;
@@ -285,6 +312,31 @@ namespace OpenSim.Region.Framework.Scenes
285 } 312 }
286 private volatile bool m_shuttingDown; 313 private volatile bool m_shuttingDown;
287 314
315 /// <summary>
316 /// Is the scene active?
317 /// </summary>
318 /// <remarks>
319 /// If false, maintenance and update loops are not being run. Updates can still be triggered manually if
320 /// the scene is not active.
321 /// </remarks>
322 public bool Active
323 {
324 get { return m_active; }
325 set
326 {
327 if (value)
328 {
329 if (!m_active)
330 Start();
331 }
332 else
333 {
334 m_active = false;
335 }
336 }
337 }
338 private volatile bool m_active;
339
288// private int m_lastUpdate; 340// private int m_lastUpdate;
289 private bool m_firstHeartbeat = true; 341 private bool m_firstHeartbeat = true;
290 342
@@ -626,7 +678,7 @@ namespace OpenSim.Region.Framework.Scenes
626 public Scene(RegionInfo regInfo, AgentCircuitManager authen, 678 public Scene(RegionInfo regInfo, AgentCircuitManager authen,
627 SceneCommunicationService sceneGridService, 679 SceneCommunicationService sceneGridService,
628 ISimulationDataService simDataService, IEstateDataService estateDataService, 680 ISimulationDataService simDataService, IEstateDataService estateDataService,
629 ModuleLoader moduleLoader, bool dumpAssetsToFile, 681 bool dumpAssetsToFile,
630 IConfigSource config, string simulatorVersion) 682 IConfigSource config, string simulatorVersion)
631 : this(regInfo) 683 : this(regInfo)
632 { 684 {
@@ -637,7 +689,6 @@ namespace OpenSim.Region.Framework.Scenes
637 Random random = new Random(); 689 Random random = new Random();
638 690
639 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4); 691 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4);
640 m_moduleLoader = moduleLoader;
641 m_authenticateHandler = authen; 692 m_authenticateHandler = authen;
642 m_sceneGridService = sceneGridService; 693 m_sceneGridService = sceneGridService;
643 m_SimulationDataService = simDataService; 694 m_SimulationDataService = simDataService;
@@ -746,12 +797,24 @@ namespace OpenSim.Region.Framework.Scenes
746 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 797 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
747 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 798 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
748 799
749 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); 800 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
801 if (RegionInfo.NonphysPrimMin > 0)
802 {
803 m_minNonphys = RegionInfo.NonphysPrimMin;
804 }
805
806 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
750 if (RegionInfo.NonphysPrimMax > 0) 807 if (RegionInfo.NonphysPrimMax > 0)
751 { 808 {
752 m_maxNonphys = RegionInfo.NonphysPrimMax; 809 m_maxNonphys = RegionInfo.NonphysPrimMax;
753 } 810 }
754 811
812 m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
813 if (RegionInfo.PhysPrimMin > 0)
814 {
815 m_minPhys = RegionInfo.PhysPrimMin;
816 }
817
755 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); 818 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
756 819
757 if (RegionInfo.PhysPrimMax > 0) 820 if (RegionInfo.PhysPrimMax > 0)
@@ -759,6 +822,12 @@ namespace OpenSim.Region.Framework.Scenes
759 m_maxPhys = RegionInfo.PhysPrimMax; 822 m_maxPhys = RegionInfo.PhysPrimMax;
760 } 823 }
761 824
825 m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity);
826 if (RegionInfo.LinksetCapacity > 0)
827 {
828 m_linksetCapacity = RegionInfo.LinksetCapacity;
829 }
830
762 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); 831 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
763 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); 832 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
764 833
@@ -784,13 +853,6 @@ namespace OpenSim.Region.Framework.Scenes
784 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 853 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
785 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine); 854 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
786 855
787 IConfig packetConfig = m_config.Configs["PacketPool"];
788 if (packetConfig != null)
789 {
790 PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
791 PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
792 }
793
794 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 856 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
795 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion); 857 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
796 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false); 858 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
@@ -854,6 +916,8 @@ namespace OpenSim.Region.Framework.Scenes
854 } 916 }
855 917
856 // FIXME: Ultimately this should be in a module. 918 // FIXME: Ultimately this should be in a module.
919 SendPeriodicAppearanceUpdates = true;
920
857 IConfig appearanceConfig = m_config.Configs["Appearance"]; 921 IConfig appearanceConfig = m_config.Configs["Appearance"];
858 if (appearanceConfig != null) 922 if (appearanceConfig != null)
859 { 923 {
@@ -1103,15 +1167,9 @@ namespace OpenSim.Region.Framework.Scenes
1103 } 1167 }
1104 } 1168 }
1105 1169
1106 m_log.Error("[REGION]: Closing"); 1170 m_log.InfoFormat("[REGION]: Restarting region {0}", Name);
1107 Close();
1108 1171
1109 if (PhysicsScene != null) 1172 Close();
1110 {
1111 PhysicsScene.Dispose();
1112 }
1113
1114 m_log.Error("[REGION]: Firing Region Restart Message");
1115 1173
1116 base.Restart(); 1174 base.Restart();
1117 } 1175 }
@@ -1151,6 +1209,14 @@ namespace OpenSim.Region.Framework.Scenes
1151 1209
1152 public void SetSceneCoreDebug(Dictionary<string, string> options) 1210 public void SetSceneCoreDebug(Dictionary<string, string> options)
1153 { 1211 {
1212 if (options.ContainsKey("active"))
1213 {
1214 bool active;
1215
1216 if (bool.TryParse(options["active"], out active))
1217 Active = active;
1218 }
1219
1154 if (options.ContainsKey("scripting")) 1220 if (options.ContainsKey("scripting"))
1155 { 1221 {
1156 bool enableScripts = true; 1222 bool enableScripts = true;
@@ -1226,6 +1292,12 @@ namespace OpenSim.Region.Framework.Scenes
1226 // This is the method that shuts down the scene. 1292 // This is the method that shuts down the scene.
1227 public override void Close() 1293 public override void Close()
1228 { 1294 {
1295 if (m_shuttingDown)
1296 {
1297 m_log.WarnFormat("[SCENE]: Ignoring close request because already closing {0}", Name);
1298 return;
1299 }
1300
1229 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); 1301 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
1230 1302
1231 StatsReporter.Close(); 1303 StatsReporter.Close();
@@ -1272,6 +1344,14 @@ namespace OpenSim.Region.Framework.Scenes
1272 m_log.Debug("[SCENE]: Graph close"); 1344 m_log.Debug("[SCENE]: Graph close");
1273 m_sceneGraph.Close(); 1345 m_sceneGraph.Close();
1274 1346
1347 if (!GridService.DeregisterRegion(RegionInfo.RegionID))
1348 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
1349
1350 base.Close();
1351
1352 // XEngine currently listens to the EventManager.OnShutdown event to trigger script stop and persistence.
1353 // Therefore. we must dispose of the PhysicsScene after this to prevent a window where script code can
1354 // attempt to reference a null or disposed physics scene.
1275 if (PhysicsScene != null) 1355 if (PhysicsScene != null)
1276 { 1356 {
1277 m_log.Debug("[SCENE]: Dispose Physics"); 1357 m_log.Debug("[SCENE]: Dispose Physics");
@@ -1281,13 +1361,6 @@ namespace OpenSim.Region.Framework.Scenes
1281 phys.Dispose(); 1361 phys.Dispose();
1282 phys = null; 1362 phys = null;
1283 } 1363 }
1284
1285 if (!GridService.DeregisterRegion(RegionInfo.RegionID))
1286 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
1287
1288 // call the base class Close method.
1289 m_log.Debug("[SCENE]: Base close");
1290 base.Close();
1291 } 1364 }
1292 1365
1293 /// <summary> 1366 /// <summary>
@@ -1295,6 +1368,8 @@ namespace OpenSim.Region.Framework.Scenes
1295 /// </summary> 1368 /// </summary>
1296 public void Start() 1369 public void Start()
1297 { 1370 {
1371 m_active = true;
1372
1298// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1373// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1299 1374
1300 //m_heartbeatTimer.Enabled = true; 1375 //m_heartbeatTimer.Enabled = true;
@@ -1354,7 +1429,7 @@ namespace OpenSim.Region.Framework.Scenes
1354 #region Update Methods 1429 #region Update Methods
1355 1430
1356 /// <summary> 1431 /// <summary>
1357 /// Performs per-frame updates regularly 1432 /// Activate the various loops necessary to continually update the scene.
1358 /// </summary> 1433 /// </summary>
1359 private void Heartbeat() 1434 private void Heartbeat()
1360 { 1435 {
@@ -1411,7 +1486,7 @@ namespace OpenSim.Region.Framework.Scenes
1411 List<Vector3> coarseLocations; 1486 List<Vector3> coarseLocations;
1412 List<UUID> avatarUUIDs; 1487 List<UUID> avatarUUIDs;
1413 1488
1414 while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) 1489 while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun))
1415 { 1490 {
1416 runtc = Util.EnvironmentTickCount(); 1491 runtc = Util.EnvironmentTickCount();
1417 ++MaintenanceRun; 1492 ++MaintenanceRun;
@@ -1473,7 +1548,7 @@ namespace OpenSim.Region.Framework.Scenes
1473 int sleepMS; 1548 int sleepMS;
1474 int framestart; 1549 int framestart;
1475 1550
1476 while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) 1551 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1477 { 1552 {
1478 framestart = Util.EnvironmentTickCount(); 1553 framestart = Util.EnvironmentTickCount();
1479 ++Frame; 1554 ++Frame;
@@ -1672,15 +1747,19 @@ namespace OpenSim.Region.Framework.Scenes
1672 1747
1673 private void CheckAtTargets() 1748 private void CheckAtTargets()
1674 { 1749 {
1675 List<SceneObjectGroup> objs = new List<SceneObjectGroup>(); 1750 List<SceneObjectGroup> objs = null;
1751
1676 lock (m_groupsWithTargets) 1752 lock (m_groupsWithTargets)
1677 { 1753 {
1678 foreach (SceneObjectGroup grp in m_groupsWithTargets.Values) 1754 if (m_groupsWithTargets.Count != 0)
1679 objs.Add(grp); 1755 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1680 } 1756 }
1681 1757
1682 foreach (SceneObjectGroup entry in objs) 1758 if (objs != null)
1683 entry.checkAtTargets(); 1759 {
1760 foreach (SceneObjectGroup entry in objs)
1761 entry.checkAtTargets();
1762 }
1684 } 1763 }
1685 1764
1686 /// <summary> 1765 /// <summary>
@@ -2193,10 +2272,14 @@ namespace OpenSim.Region.Framework.Scenes
2193 public bool AddRestoredSceneObject( 2272 public bool AddRestoredSceneObject(
2194 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 2273 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
2195 { 2274 {
2196 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 2275 if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates))
2197 if (result) 2276 {
2198 sceneObject.IsDeleted = false; 2277 sceneObject.IsDeleted = false;
2199 return result; 2278 EventManager.TriggerObjectAddedToScene(sceneObject);
2279 return true;
2280 }
2281
2282 return false;
2200 } 2283 }
2201 2284
2202 /// <summary> 2285 /// <summary>
@@ -2837,77 +2920,89 @@ namespace OpenSim.Region.Framework.Scenes
2837 2920
2838 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2921 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
2839 { 2922 {
2923 ScenePresence sp;
2924 bool vialogin;
2925
2840 // Validation occurs in LLUDPServer 2926 // Validation occurs in LLUDPServer
2927 //
2928 // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with
2929 // each other. In practice, this does not currently occur in the code.
2841 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2930 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2842 2931
2843 bool vialogin 2932 // We lock here on AgentCircuitData to prevent a race condition between the thread adding a new connection
2844 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 2933 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point
2845 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2934 // whilst connecting).
2846 2935 //
2847 CheckHeartbeat(); 2936 // It would be easier to lock across all NewUserConnection(), AddNewClient() and
2848 2937 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
2849 ScenePresence sp = GetScenePresence(client.AgentId); 2938 // response in some module listening to AddNewClient()) from holding up unrelated agent calls.
2850 2939 //
2851 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2940 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all
2852 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause 2941 // AddNewClient() operations (though not other ops).
2853 // other problems, and possible the code calling AddNewClient() should ensure that no client is already 2942 // In the future this can be relieved once locking per agent (not necessarily on AgentCircuitData) is improved.
2854 // connected. 2943 lock (aCircuit)
2855 if (sp == null) 2944 {
2856 { 2945 vialogin
2857 m_log.DebugFormat( 2946 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2858 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 2947 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2859 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); 2948
2860 2949 CheckHeartbeat();
2861 m_clientManager.Add(client); 2950
2862 SubscribeToClientEvents(client); 2951 sp = GetScenePresence(client.AgentId);
2863
2864 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2865 m_eventManager.TriggerOnNewPresence(sp);
2866
2867 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2868 2952
2869 // The first agent upon login is a root agent by design. 2953 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
2870 // For this agent we will have to rez the attachments. 2954 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause
2871 // All other AddNewClient calls find aCircuit.child to be true. 2955 // other problems, and possible the code calling AddNewClient() should ensure that no client is already
2872 if (aCircuit.child == false) 2956 // connected.
2957 if (sp == null)
2873 { 2958 {
2874 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to 2959 m_log.DebugFormat(
2875 // start the scripts again (since this is done in RezAttachments()). 2960 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2876 // XXX: This is convoluted. 2961 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2877 sp.IsChildAgent = false; 2962
2878 2963 m_clientManager.Add(client);
2879 if (AttachmentsModule != null) 2964 SubscribeToClientEvents(client);
2880 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); 2965
2966 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2967 m_eventManager.TriggerOnNewPresence(sp);
2968
2969 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2970
2971 // The first agent upon login is a root agent by design.
2972 // For this agent we will have to rez the attachments.
2973 // All other AddNewClient calls find aCircuit.child to be true.
2974 if (aCircuit.child == false)
2975 {
2976 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to
2977 // start the scripts again (since this is done in RezAttachments()).
2978 // XXX: This is convoluted.
2979 sp.IsChildAgent = false;
2980
2981 if (AttachmentsModule != null)
2982 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
2983 }
2881 } 2984 }
2882 } 2985 else
2883 else 2986 {
2884 { 2987 m_log.WarnFormat(
2885 m_log.WarnFormat( 2988 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2886 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 2989 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2887 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2990 }
2888 } 2991
2992 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2993 // client is for a root or child agent.
2994 client.SceneAgent = sp;
2889 2995
2890 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 2996 // Cache the user's name
2891 // client is for a root or child agent. 2997 CacheUserName(sp, aCircuit);
2892 client.SceneAgent = sp; 2998
2999 EventManager.TriggerOnNewClient(client);
3000 if (vialogin)
3001 EventManager.TriggerOnClientLogin(client);
3002 }
2893 3003
2894 m_LastLogin = Util.EnvironmentTickCount(); 3004 m_LastLogin = Util.EnvironmentTickCount();
2895 3005
2896 // Cache the user's name
2897 CacheUserName(sp, aCircuit);
2898
2899 EventManager.TriggerOnNewClient(client);
2900 if (vialogin)
2901 {
2902 EventManager.TriggerOnClientLogin(client);
2903 // Send initial parcel data
2904/* this is done on TriggerOnNewClient by landmanegement respective event handler
2905 Vector3 pos = sp.AbsolutePosition;
2906 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2907 land.SendLandUpdateToClient(client);
2908*/
2909 }
2910
2911 return sp; 3006 return sp;
2912 } 3007 }
2913 3008
@@ -3447,110 +3542,132 @@ namespace OpenSim.Region.Framework.Scenes
3447 { 3542 {
3448// CheckHeartbeat(); 3543// CheckHeartbeat();
3449 bool isChildAgent = false; 3544 bool isChildAgent = false;
3450 ScenePresence avatar = GetScenePresence(agentID); 3545 AgentCircuitData acd;
3451
3452 if (avatar == null)
3453 {
3454 m_log.WarnFormat(
3455 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3456 3546
3457 return; 3547 lock (m_removeClientLock)
3458 }
3459
3460 try
3461 { 3548 {
3462 isChildAgent = avatar.IsChildAgent; 3549 acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3463 3550
3464 m_log.DebugFormat( 3551 if (acd == null)
3465 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3466 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3467
3468 // Don't do this to root agents, it's not nice for the viewer
3469 if (closeChildAgents && isChildAgent)
3470 { 3552 {
3471 // Tell a single agent to disconnect from the region. 3553 m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID);
3472 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3554 return;
3473 if (eq != null)
3474 {
3475 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3476 }
3477 else
3478 {
3479 avatar.ControllingClient.SendShutdownConnectionNotice();
3480 }
3481 } 3555 }
3482 3556 else
3483 // Only applies to root agents.
3484 if (avatar.ParentID != 0)
3485 { 3557 {
3486 avatar.StandUp(); 3558 // We remove the acd up here to avoid later race conditions if two RemoveClient() calls occurred
3559 // simultaneously.
3560 // We also need to remove by agent ID since NPCs will have no circuit code.
3561 m_authenticateHandler.RemoveCircuit(agentID);
3487 } 3562 }
3563 }
3488 3564
3489 m_sceneGraph.removeUserCount(!isChildAgent); 3565 lock (acd)
3490 3566 {
3491 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3567 ScenePresence avatar = GetScenePresence(agentID);
3492 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3568
3493 if (closeChildAgents && CapsModule != null) 3569 if (avatar == null)
3494 CapsModule.RemoveCaps(agentID);
3495
3496 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3497 // this method is doing is HORRIBLE!!!
3498 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3499
3500 if (closeChildAgents && !isChildAgent)
3501 { 3570 {
3502 List<ulong> regions = avatar.KnownRegionHandles; 3571 m_log.WarnFormat(
3503 regions.Remove(RegionInfo.RegionHandle); 3572 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3504 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3573
3574 return;
3505 } 3575 }
3506 3576
3507 m_eventManager.TriggerClientClosed(agentID, this); 3577 try
3508 m_eventManager.TriggerOnRemovePresence(agentID);
3509
3510 if (!isChildAgent)
3511 { 3578 {
3512 if (AttachmentsModule != null) 3579 isChildAgent = avatar.IsChildAgent;
3580
3581 m_log.DebugFormat(
3582 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3583 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3584
3585 // Don't do this to root agents, it's not nice for the viewer
3586 if (closeChildAgents && isChildAgent)
3513 { 3587 {
3514 AttachmentsModule.DeRezAttachments(avatar); 3588 // Tell a single agent to disconnect from the region.
3589 IEventQueue eq = RequestModuleInterface<IEventQueue>();
3590 if (eq != null)
3591 {
3592 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3593 }
3594 else
3595 {
3596 avatar.ControllingClient.SendShutdownConnectionNotice();
3597 }
3515 } 3598 }
3516 3599
3517 ForEachClient( 3600 // Only applies to root agents.
3518 delegate(IClientAPI client) 3601 if (avatar.ParentID != 0)
3602 {
3603 avatar.StandUp();
3604 }
3605
3606 m_sceneGraph.removeUserCount(!isChildAgent);
3607
3608 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3609 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3610 if (closeChildAgents && CapsModule != null)
3611 CapsModule.RemoveCaps(agentID);
3612
3613// // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3614// // this method is doing is HORRIBLE!!!
3615 // Commented pending deletion since this method no longer appears to do anything at all
3616// avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3617
3618 if (closeChildAgents && !isChildAgent)
3619 {
3620 List<ulong> regions = avatar.KnownRegionHandles;
3621 regions.Remove(RegionInfo.RegionHandle);
3622 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3623 }
3624
3625 m_eventManager.TriggerClientClosed(agentID, this);
3626 m_eventManager.TriggerOnRemovePresence(agentID);
3627
3628 if (!isChildAgent)
3629 {
3630 if (AttachmentsModule != null)
3519 { 3631 {
3520 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3632 AttachmentsModule.DeRezAttachments(avatar);
3521 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3633 }
3522 catch (NullReferenceException) { }
3523 });
3524 }
3525
3526 // It's possible for child agents to have transactions if changes are being made cross-border.
3527 if (AgentTransactionsModule != null)
3528 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3529 3634
3530 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3635 ForEachClient(
3531 m_log.Debug("[Scene] The avatar has left the building"); 3636 delegate(IClientAPI client)
3532 } 3637 {
3533 catch (Exception e) 3638 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3534 { 3639 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3535 m_log.Error( 3640 catch (NullReferenceException) { }
3536 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); 3641 });
3537 } 3642 }
3538 finally
3539 {
3540 try
3541 {
3542 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3543 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3544 // the same cleanup exception continually.
3545 m_sceneGraph.RemoveScenePresence(agentID);
3546 m_clientManager.Remove(agentID);
3547 3643
3548 avatar.Close(); 3644 // It's possible for child agents to have transactions if changes are being made cross-border.
3645 if (AgentTransactionsModule != null)
3646 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3647 m_log.Debug("[Scene] The avatar has left the building");
3549 } 3648 }
3550 catch (Exception e) 3649 catch (Exception e)
3551 { 3650 {
3552 m_log.Error( 3651 m_log.Error(
3553 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); 3652 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e);
3653 }
3654 finally
3655 {
3656 try
3657 {
3658 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3659 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3660 // the same cleanup exception continually.
3661 m_sceneGraph.RemoveScenePresence(agentID);
3662 m_clientManager.Remove(agentID);
3663
3664 avatar.Close();
3665 }
3666 catch (Exception e)
3667 {
3668 m_log.Error(
3669 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e);
3670 }
3554 } 3671 }
3555 } 3672 }
3556 3673
@@ -3609,11 +3726,9 @@ namespace OpenSim.Region.Framework.Scenes
3609 3726
3610 /// <summary> 3727 /// <summary>
3611 /// Do the work necessary to initiate a new user connection for a particular scene. 3728 /// Do the work necessary to initiate a new user connection for a particular scene.
3612 /// At the moment, this consists of setting up the caps infrastructure
3613 /// The return bool should allow for connections to be refused, but as not all calling paths
3614 /// take proper notice of it let, we allowed banned users in still.
3615 /// </summary> 3729 /// </summary>
3616 /// <param name="agent">CircuitData of the agent who is connecting</param> 3730 /// <param name="agent">CircuitData of the agent who is connecting</param>
3731 /// <param name="teleportFlags"></param>
3617 /// <param name="reason">Outputs the reason for the false response on this string</param> 3732 /// <param name="reason">Outputs the reason for the false response on this string</param>
3618 /// <returns>True if the region accepts this agent. False if it does not. False will 3733 /// <returns>True if the region accepts this agent. False if it does not. False will
3619 /// also return a reason.</returns> 3734 /// also return a reason.</returns>
@@ -3624,10 +3739,20 @@ namespace OpenSim.Region.Framework.Scenes
3624 3739
3625 /// <summary> 3740 /// <summary>
3626 /// Do the work necessary to initiate a new user connection for a particular scene. 3741 /// Do the work necessary to initiate a new user connection for a particular scene.
3627 /// At the moment, this consists of setting up the caps infrastructure 3742 /// </summary>
3743 /// <remarks>
3744 /// The return bool should allow for connections to be refused, but as not all calling paths
3745 /// take proper notice of it yet, we still allowed banned users in.
3746 ///
3747 /// At the moment this method consists of setting up the caps infrastructure
3628 /// The return bool should allow for connections to be refused, but as not all calling paths 3748 /// The return bool should allow for connections to be refused, but as not all calling paths
3629 /// take proper notice of it let, we allowed banned users in still. 3749 /// take proper notice of it let, we allowed banned users in still.
3630 /// </summary> 3750 ///
3751 /// This method is called by the login service (in the case of login) or another simulator (in the case of region
3752 /// cross or teleport) to initiate the connection. It is not triggered by the viewer itself - the connection
3753 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
3754 /// the LLUDP stack).
3755 /// </remarks>
3631 /// <param name="agent">CircuitData of the agent who is connecting</param> 3756 /// <param name="agent">CircuitData of the agent who is connecting</param>
3632 /// <param name="reason">Outputs the reason for the false response on this string</param> 3757 /// <param name="reason">Outputs the reason for the false response on this string</param>
3633 /// <param name="requirePresenceLookup">True for normal presence. False for NPC 3758 /// <param name="requirePresenceLookup">True for normal presence. False for NPC
@@ -3726,83 +3851,86 @@ namespace OpenSim.Region.Framework.Scenes
3726 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3851 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3727 sp.Name, sp.UUID, RegionInfo.RegionName); 3852 sp.Name, sp.UUID, RegionInfo.RegionName);
3728 3853
3729 sp.ControllingClient.Close(); 3854 sp.ControllingClient.Close(true, true);
3730 sp = null; 3855 sp = null;
3731 } 3856 }
3732 3857
3733 3858 lock (agent)
3734 //On login test land permisions
3735 if (vialogin)
3736 { 3859 {
3737 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); 3860 //On login test land permisions
3738 if (cache != null) 3861 if (vialogin)
3739 cache.Remove(agent.firstname + " " + agent.lastname);
3740 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3741 { 3862 {
3742 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); 3863 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3743 return false; 3864 if (cache != null)
3865 cache.Remove(agent.firstname + " " + agent.lastname);
3866 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3867 {
3868 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3869 return false;
3870 }
3744 } 3871 }
3745 }
3746 3872
3747 if (sp == null) // We don't have an [child] agent here already 3873 if (sp == null) // We don't have an [child] agent here already
3748 {
3749 if (requirePresenceLookup)
3750 { 3874 {
3751 try 3875 if (requirePresenceLookup)
3752 { 3876 {
3753 if (!VerifyUserPresence(agent, out reason)) 3877 try
3878 {
3879 if (!VerifyUserPresence(agent, out reason))
3880 return false;
3881 } catch (Exception e)
3882 {
3883 m_log.ErrorFormat(
3884 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3754 return false; 3885 return false;
3755 } catch (Exception e) 3886 }
3887 }
3888
3889 try
3890 {
3891 // Always check estate if this is a login. Always
3892 // check if banned regions are to be blacked out.
3893 if (vialogin || (!m_seeIntoBannedRegion))
3894 {
3895 if (!AuthorizeUser(agent, out reason))
3896 return false;
3897 }
3898 }
3899 catch (Exception e)
3756 { 3900 {
3757 m_log.ErrorFormat( 3901 m_log.ErrorFormat(
3758 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3902 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
3759 return false; 3903 return false;
3760 } 3904 }
3761 }
3762 3905
3763 try 3906 m_log.InfoFormat(
3764 { 3907 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3765 // Always check estate if this is a login. Always 3908 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3766 // check if banned regions are to be blacked out. 3909 agent.AgentID, agent.circuitcode);
3767 if (vialogin || (!m_seeIntoBannedRegion)) 3910
3911 if (CapsModule != null)
3768 { 3912 {
3769 if (!AuthorizeUser(agent, out reason)) 3913 CapsModule.SetAgentCapsSeeds(agent);
3770 return false; 3914 CapsModule.CreateCaps(agent.AgentID);
3771 } 3915 }
3772 } 3916 }
3773 catch (Exception e) 3917 else
3774 { 3918 {
3775 m_log.ErrorFormat( 3919 // Let the SP know how we got here. This has a lot of interesting
3776 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); 3920 // uses down the line.
3777 return false; 3921 sp.TeleportFlags = (TPFlags)teleportFlags;
3778 }
3779
3780 m_log.InfoFormat(
3781 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3782 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3783 agent.AgentID, agent.circuitcode);
3784 3922
3785 if (CapsModule != null) 3923 if (sp.IsChildAgent)
3786 { 3924 {
3787 CapsModule.SetAgentCapsSeeds(agent); 3925 m_log.DebugFormat(
3788 CapsModule.CreateCaps(agent.AgentID); 3926 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3789 } 3927 agent.AgentID, RegionInfo.RegionName);
3790 } else
3791 {
3792 // Let the SP know how we got here. This has a lot of interesting
3793 // uses down the line.
3794 sp.TeleportFlags = (TPFlags)teleportFlags;
3795 3928
3796 if (sp.IsChildAgent) 3929 sp.AdjustKnownSeeds();
3797 {
3798 m_log.DebugFormat(
3799 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3800 agent.AgentID, RegionInfo.RegionName);
3801 3930
3802 sp.AdjustKnownSeeds(); 3931 if (CapsModule != null)
3803 3932 CapsModule.SetAgentCapsSeeds(agent);
3804 if (CapsModule != null) 3933 }
3805 CapsModule.SetAgentCapsSeeds(agent);
3806 } 3934 }
3807 } 3935 }
3808 3936
@@ -4233,8 +4361,9 @@ namespace OpenSim.Region.Framework.Scenes
4233 return false; 4361 return false;
4234 } 4362 }
4235 4363
4236 // We have to wait until the viewer contacts this region after receiving EAC. 4364 // We have to wait until the viewer contacts this region
4237 // That calls AddNewClient, which finally creates the ScenePresence 4365 // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send
4366 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence.
4238 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4367 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
4239 4368
4240 if (childAgentUpdate != null) 4369 if (childAgentUpdate != null)
@@ -4329,15 +4458,18 @@ namespace OpenSim.Region.Framework.Scenes
4329 /// Tell a single agent to disconnect from the region. 4458 /// Tell a single agent to disconnect from the region.
4330 /// </summary> 4459 /// </summary>
4331 /// <param name="agentID"></param> 4460 /// <param name="agentID"></param>
4332 /// <param name="childOnly"></param> 4461 /// <param name="force">
4333 public bool IncomingCloseAgent(UUID agentID, bool childOnly) 4462 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4463 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4464 /// </param>
4465 public bool IncomingCloseAgent(UUID agentID, bool force)
4334 { 4466 {
4335 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4467 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
4336 4468
4337 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4469 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4338 if (presence != null) 4470 if (presence != null)
4339 { 4471 {
4340 presence.ControllingClient.Close(false); 4472 presence.ControllingClient.Close(force, force);
4341 return true; 4473 return true;
4342 } 4474 }
4343 4475
@@ -4543,6 +4675,16 @@ namespace OpenSim.Region.Framework.Scenes
4543 return LandChannel.GetLandObject(x, y).LandData; 4675 return LandChannel.GetLandObject(x, y).LandData;
4544 } 4676 }
4545 4677
4678 /// <summary>
4679 /// Get LandData by position.
4680 /// </summary>
4681 /// <param name="pos"></param>
4682 /// <returns></returns>
4683 public LandData GetLandData(Vector3 pos)
4684 {
4685 return GetLandData(pos.X, pos.Y);
4686 }
4687
4546 public LandData GetLandData(uint x, uint y) 4688 public LandData GetLandData(uint x, uint y)
4547 { 4689 {
4548 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); 4690 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
@@ -4773,13 +4915,24 @@ namespace OpenSim.Region.Framework.Scenes
4773 /// Get a group via its UUID 4915 /// Get a group via its UUID
4774 /// </summary> 4916 /// </summary>
4775 /// <param name="fullID"></param> 4917 /// <param name="fullID"></param>
4776 /// <returns>null if no group with that name exists</returns> 4918 /// <returns>null if no group with that id exists</returns>
4777 public SceneObjectGroup GetSceneObjectGroup(UUID fullID) 4919 public SceneObjectGroup GetSceneObjectGroup(UUID fullID)
4778 { 4920 {
4779 return m_sceneGraph.GetSceneObjectGroup(fullID); 4921 return m_sceneGraph.GetSceneObjectGroup(fullID);
4780 } 4922 }
4781 4923
4782 /// <summary> 4924 /// <summary>
4925 /// Get a group via its local ID
4926 /// </summary>
4927 /// <remarks>This will only return a group if the local ID matches a root part</remarks>
4928 /// <param name="localID"></param>
4929 /// <returns>null if no group with that id exists</returns>
4930 public SceneObjectGroup GetSceneObjectGroup(uint localID)
4931 {
4932 return m_sceneGraph.GetSceneObjectGroup(localID);
4933 }
4934
4935 /// <summary>
4783 /// Get a group by name from the scene (will return the first 4936 /// Get a group by name from the scene (will return the first
4784 /// found, if there are more than one prim with the same name) 4937 /// found, if there are more than one prim with the same name)
4785 /// </summary> 4938 /// </summary>
@@ -4791,6 +4944,18 @@ namespace OpenSim.Region.Framework.Scenes
4791 } 4944 }
4792 4945
4793 /// <summary> 4946 /// <summary>
4947 /// Attempt to get the SOG via its UUID
4948 /// </summary>
4949 /// <param name="fullID"></param>
4950 /// <param name="sog"></param>
4951 /// <returns></returns>
4952 public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog)
4953 {
4954 sog = GetSceneObjectGroup(fullID);
4955 return sog != null;
4956 }
4957
4958 /// <summary>
4794 /// Get a prim by name from the scene (will return the first 4959 /// Get a prim by name from the scene (will return the first
4795 /// found, if there are more than one prim with the same name) 4960 /// found, if there are more than one prim with the same name)
4796 /// </summary> 4961 /// </summary>
@@ -4822,6 +4987,18 @@ namespace OpenSim.Region.Framework.Scenes
4822 } 4987 }
4823 4988
4824 /// <summary> 4989 /// <summary>
4990 /// Attempt to get a prim via its UUID
4991 /// </summary>
4992 /// <param name="fullID"></param>
4993 /// <param name="sop"></param>
4994 /// <returns></returns>
4995 public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop)
4996 {
4997 sop = GetSceneObjectPart(fullID);
4998 return sop != null;
4999 }
5000
5001 /// <summary>
4825 /// Get a scene object group that contains the prim with the given local id 5002 /// Get a scene object group that contains the prim with the given local id
4826 /// </summary> 5003 /// </summary>
4827 /// <param name="localID"></param> 5004 /// <param name="localID"></param>
@@ -4915,14 +5092,15 @@ namespace OpenSim.Region.Framework.Scenes
4915 client.SendRegionHandle(regionID, handle); 5092 client.SendRegionHandle(regionID, handle);
4916 } 5093 }
4917 5094
4918 public bool NeedSceneCacheClear(UUID agentID) 5095// Commented pending deletion since this method no longer appears to do anything at all
4919 { 5096// public bool NeedSceneCacheClear(UUID agentID)
4920 IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>(); 5097// {
4921 if (inv == null) 5098// IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
4922 return true; 5099// if (inv == null)
4923 5100// return true;
4924 return inv.NeedSceneCacheClear(agentID, this); 5101//
4925 } 5102// return inv.NeedSceneCacheClear(agentID, this);
5103// }
4926 5104
4927 public void CleanTempObjects() 5105 public void CleanTempObjects()
4928 { 5106 {
@@ -5876,6 +6054,9 @@ Environment.Exit(1);
5876 6054
5877 public string GetExtraSetting(string name) 6055 public string GetExtraSetting(string name)
5878 { 6056 {
6057 if (m_extraSettings == null)
6058 return String.Empty;
6059
5879 string val; 6060 string val;
5880 6061
5881 if (!m_extraSettings.TryGetValue(name, out val)) 6062 if (!m_extraSettings.TryGetValue(name, out val))
@@ -5886,6 +6067,9 @@ Environment.Exit(1);
5886 6067
5887 public void StoreExtraSetting(string name, string val) 6068 public void StoreExtraSetting(string name, string val)
5888 { 6069 {
6070 if (m_extraSettings == null)
6071 return;
6072
5889 string oldVal; 6073 string oldVal;
5890 6074
5891 if (m_extraSettings.TryGetValue(name, out oldVal)) 6075 if (m_extraSettings.TryGetValue(name, out oldVal))
@@ -5903,6 +6087,9 @@ Environment.Exit(1);
5903 6087
5904 public void RemoveExtraSetting(string name) 6088 public void RemoveExtraSetting(string name)
5905 { 6089 {
6090 if (m_extraSettings == null)
6091 return;
6092
5906 if (!m_extraSettings.ContainsKey(name)) 6093 if (!m_extraSettings.ContainsKey(name))
5907 return; 6094 return;
5908 6095
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 7c8bd88..74c9582 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -67,12 +67,6 @@ namespace OpenSim.Region.Framework.Scenes
67 /// <value> 67 /// <value>
68 /// All the region modules attached to this scene. 68 /// All the region modules attached to this scene.
69 /// </value> 69 /// </value>
70 public Dictionary<string, IRegionModule> Modules
71 {
72 get { return m_modules; }
73 }
74 protected Dictionary<string, IRegionModule> m_modules = new Dictionary<string, IRegionModule>();
75
76 public Dictionary<string, IRegionModuleBase> RegionModules 70 public Dictionary<string, IRegionModuleBase> RegionModules
77 { 71 {
78 get { return m_regionModules; } 72 get { return m_regionModules; }
@@ -273,16 +267,6 @@ namespace OpenSim.Region.Framework.Scenes
273 /// </summary> 267 /// </summary>
274 public virtual void Close() 268 public virtual void Close()
275 { 269 {
276 // Shut down all non shared modules.
277 foreach (IRegionModule module in Modules.Values)
278 {
279 if (!module.IsSharedModule)
280 {
281 module.Close();
282 }
283 }
284 Modules.Clear();
285
286 try 270 try
287 { 271 {
288 EventManager.TriggerShutdown(); 272 EventManager.TriggerShutdown();
@@ -313,19 +297,6 @@ namespace OpenSim.Region.Framework.Scenes
313 #region Module Methods 297 #region Module Methods
314 298
315 /// <summary> 299 /// <summary>
316 /// Add a module to this scene.
317 /// </summary>
318 /// <param name="name"></param>
319 /// <param name="module"></param>
320 public void AddModule(string name, IRegionModule module)
321 {
322 if (!Modules.ContainsKey(name))
323 {
324 Modules.Add(name, module);
325 }
326 }
327
328 /// <summary>
329 /// Add a region-module to this scene. TODO: This will replace AddModule in the future. 300 /// Add a region-module to this scene. TODO: This will replace AddModule in the future.
330 /// </summary> 301 /// </summary>
331 /// <param name="name"></param> 302 /// <param name="name"></param>
@@ -509,9 +480,9 @@ namespace OpenSim.Region.Framework.Scenes
509 /// <param name="shorthelp"></param> 480 /// <param name="shorthelp"></param>
510 /// <param name="longhelp"></param> 481 /// <param name="longhelp"></param>
511 /// <param name="callback"></param> 482 /// <param name="callback"></param>
512 public void AddCommand(object mod, string command, string shorthelp, string longhelp, CommandDelegate callback) 483 public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback)
513 { 484 {
514 AddCommand(mod, command, shorthelp, longhelp, string.Empty, callback); 485 AddCommand(module, command, shorthelp, longhelp, string.Empty, callback);
515 } 486 }
516 487
517 /// <summary> 488 /// <summary>
@@ -529,9 +500,9 @@ namespace OpenSim.Region.Framework.Scenes
529 /// <param name="longhelp"></param> 500 /// <param name="longhelp"></param>
530 /// <param name="callback"></param> 501 /// <param name="callback"></param>
531 public void AddCommand( 502 public void AddCommand(
532 string category, object mod, string command, string shorthelp, string longhelp, CommandDelegate callback) 503 string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback)
533 { 504 {
534 AddCommand(category, mod, command, shorthelp, longhelp, string.Empty, callback); 505 AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback);
535 } 506 }
536 507
537 /// <summary> 508 /// <summary>
@@ -543,29 +514,14 @@ namespace OpenSim.Region.Framework.Scenes
543 /// <param name="longhelp"></param> 514 /// <param name="longhelp"></param>
544 /// <param name="descriptivehelp"></param> 515 /// <param name="descriptivehelp"></param>
545 /// <param name="callback"></param> 516 /// <param name="callback"></param>
546 public void AddCommand(object mod, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) 517 public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback)
547 { 518 {
548 string moduleName = ""; 519 string moduleName = "";
549 520
550 if (mod != null) 521 if (module != null)
551 { 522 moduleName = module.Name;
552 if (mod is IRegionModule)
553 {
554 IRegionModule module = (IRegionModule)mod;
555 moduleName = module.Name;
556 }
557 else if (mod is IRegionModuleBase)
558 {
559 IRegionModuleBase module = (IRegionModuleBase)mod;
560 moduleName = module.Name;
561 }
562 else
563 {
564 throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase");
565 }
566 }
567 523
568 AddCommand(moduleName, mod, command, shorthelp, longhelp, descriptivehelp, callback); 524 AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback);
569 } 525 }
570 526
571 /// <summary> 527 /// <summary>
@@ -581,7 +537,7 @@ namespace OpenSim.Region.Framework.Scenes
581 /// <param name="descriptivehelp"></param> 537 /// <param name="descriptivehelp"></param>
582 /// <param name="callback"></param> 538 /// <param name="callback"></param>
583 public void AddCommand( 539 public void AddCommand(
584 string category, object mod, string command, 540 string category, IRegionModuleBase module, string command,
585 string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) 541 string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback)
586 { 542 {
587 if (MainConsole.Instance == null) 543 if (MainConsole.Instance == null)
@@ -589,22 +545,8 @@ namespace OpenSim.Region.Framework.Scenes
589 545
590 bool shared = false; 546 bool shared = false;
591 547
592 if (mod != null) 548 if (module != null)
593 { 549 shared = module is ISharedRegionModule;
594 if (mod is IRegionModule)
595 {
596 IRegionModule module = (IRegionModule)mod;
597 shared = module.IsSharedModule;
598 }
599 else if (mod is IRegionModuleBase)
600 {
601 shared = mod is ISharedRegionModule;
602 }
603 else
604 {
605 throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase");
606 }
607 }
608 550
609 MainConsole.Instance.Commands.AddCommand( 551 MainConsole.Instance.Commands.AddCommand(
610 category, shared, command, shorthelp, longhelp, descriptivehelp, callback); 552 category, shared, command, shorthelp, longhelp, descriptivehelp, callback);
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index af13b46..e599e90 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -342,7 +342,7 @@ namespace OpenSim.Region.Framework.Scenes
342 public bool AddNewSceneObject( 342 public bool AddNewSceneObject(
343 SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel) 343 SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
344 { 344 {
345 AddNewSceneObject(sceneObject, true, false); 345 AddNewSceneObject(sceneObject, attachToBackup, false);
346 346
347 if (pos != null) 347 if (pos != null)
348 sceneObject.AbsolutePosition = (Vector3)pos; 348 sceneObject.AbsolutePosition = (Vector3)pos;
@@ -421,12 +421,9 @@ namespace OpenSim.Region.Framework.Scenes
421 { 421 {
422 Vector3 scale = part.Shape.Scale; 422 Vector3 scale = part.Shape.Scale;
423 423
424 if (scale.X > m_parentScene.m_maxNonphys) 424 scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X));
425 scale.X = m_parentScene.m_maxNonphys; 425 scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y));
426 if (scale.Y > m_parentScene.m_maxNonphys) 426 scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z));
427 scale.Y = m_parentScene.m_maxNonphys;
428 if (scale.Z > m_parentScene.m_maxNonphys)
429 scale.Z = m_parentScene.m_maxNonphys;
430 427
431 part.Shape.Scale = scale; 428 part.Shape.Scale = scale;
432 } 429 }
@@ -1066,6 +1063,30 @@ namespace OpenSim.Region.Framework.Scenes
1066 } 1063 }
1067 1064
1068 /// <summary> 1065 /// <summary>
1066 /// Get a group in the scene
1067 /// </summary>
1068 /// <remarks>
1069 /// This will only return a group if the local ID matches the root part, not other parts.
1070 /// </remarks>
1071 /// <param name="localID">Local id of the root part of the group</param>
1072 /// <returns>null if no such group was found</returns>
1073 protected internal SceneObjectGroup GetSceneObjectGroup(uint localID)
1074 {
1075 lock (SceneObjectGroupsByLocalPartID)
1076 {
1077 if (SceneObjectGroupsByLocalPartID.ContainsKey(localID))
1078 {
1079 SceneObjectGroup so = SceneObjectGroupsByLocalPartID[localID];
1080
1081 if (so.LocalId == localID)
1082 return so;
1083 }
1084 }
1085
1086 return null;
1087 }
1088
1089 /// <summary>
1069 /// Get a group by name from the scene (will return the first 1090 /// Get a group by name from the scene (will return the first
1070 /// found, if there are more than one prim with the same name) 1091 /// found, if there are more than one prim with the same name)
1071 /// </summary> 1092 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index f1b09ca..0e0b6c3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -92,7 +92,11 @@ namespace OpenSim.Region.Framework.Scenes
92 private static SceneManager m_instance = null; 92 private static SceneManager m_instance = null;
93 public static SceneManager Instance 93 public static SceneManager Instance
94 { 94 {
95 get { return m_instance; } 95 get {
96 if (m_instance == null)
97 m_instance = new SceneManager();
98 return m_instance;
99 }
96 } 100 }
97 101
98 private readonly DoubleDictionary<UUID, string, Scene> m_localScenes = new DoubleDictionary<UUID, string, Scene>(); 102 private readonly DoubleDictionary<UUID, string, Scene> m_localScenes = new DoubleDictionary<UUID, string, Scene>();
@@ -103,16 +107,19 @@ namespace OpenSim.Region.Framework.Scenes
103 get { return new List<Scene>(m_localScenes.FindAll(delegate(Scene s) { return true; })); } 107 get { return new List<Scene>(m_localScenes.FindAll(delegate(Scene s) { return true; })); }
104 } 108 }
105 109
106 public Scene CurrentScene 110 /// <summary>
107 { 111 /// Scene selected from the console.
108 get { return m_currentScene; } 112 /// </summary>
109 } 113 /// <value>
114 /// If null, then all scenes are considered selected (signalled as "Root" on the console).
115 /// </value>
116 public Scene CurrentScene { get; private set; }
110 117
111 public Scene CurrentOrFirstScene 118 public Scene CurrentOrFirstScene
112 { 119 {
113 get 120 get
114 { 121 {
115 if (m_currentScene == null) 122 if (CurrentScene == null)
116 { 123 {
117 List<Scene> sceneList = Scenes; 124 List<Scene> sceneList = Scenes;
118 if (sceneList.Count == 0) 125 if (sceneList.Count == 0)
@@ -121,7 +128,7 @@ namespace OpenSim.Region.Framework.Scenes
121 } 128 }
122 else 129 else
123 { 130 {
124 return m_currentScene; 131 return CurrentScene;
125 } 132 }
126 } 133 }
127 } 134 }
@@ -134,31 +141,17 @@ namespace OpenSim.Region.Framework.Scenes
134 141
135 public void Close() 142 public void Close()
136 { 143 {
137 // collect known shared modules in sharedModules 144 List<Scene> localScenes = null;
138 Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>();
139 145
140 List<Scene> sceneList = Scenes; 146 lock (m_localScenes)
141 for (int i = 0; i < sceneList.Count; i++)
142 { 147 {
143 // extract known shared modules from scene 148 localScenes = Scenes;
144 foreach (string k in sceneList[i].Modules.Keys)
145 {
146 if (sceneList[i].Modules[k].IsSharedModule &&
147 !sharedModules.ContainsKey(k))
148 sharedModules[k] = sceneList[i].Modules[k];
149 }
150 // close scene/region
151 sceneList[i].Close();
152 } 149 }
153 150
154 // all regions/scenes are now closed, we can now safely 151 for (int i = 0; i < localScenes.Count; i++)
155 // close all shared modules
156 foreach (IRegionModule mod in sharedModules.Values)
157 { 152 {
158 mod.Close(); 153 localScenes[i].Close();
159 } 154 }
160
161 m_localScenes.Clear();
162 } 155 }
163 156
164 public void Close(Scene cscene) 157 public void Close(Scene cscene)
@@ -179,11 +172,18 @@ namespace OpenSim.Region.Framework.Scenes
179 172
180 public void HandleRestart(RegionInfo rdata) 173 public void HandleRestart(RegionInfo rdata)
181 { 174 {
182 m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); 175 Scene restartedScene = null;
183 int RegionSceneElement = -1;
184 176
185 lock (m_localScenes) 177 lock (m_localScenes)
178 {
179 m_localScenes.TryGetValue(rdata.RegionID, out restartedScene);
186 m_localScenes.Remove(rdata.RegionID); 180 m_localScenes.Remove(rdata.RegionID);
181 }
182
183 // If the currently selected scene has been restarted, then we can't reselect here since we the scene
184 // hasn't yet been recreated. We will have to leave this to the caller.
185 if (CurrentScene == restartedScene)
186 CurrentScene = null;
187 187
188 // Send signal to main that we're restarting this sim. 188 // Send signal to main that we're restarting this sim.
189 OnRestartSim(rdata); 189 OnRestartSim(rdata);
@@ -323,14 +323,14 @@ namespace OpenSim.Region.Framework.Scenes
323 323
324 private void ForEachCurrentScene(Action<Scene> func) 324 private void ForEachCurrentScene(Action<Scene> func)
325 { 325 {
326 if (m_currentScene == null) 326 if (CurrentScene == null)
327 { 327 {
328 List<Scene> sceneList = Scenes; 328 List<Scene> sceneList = Scenes;
329 sceneList.ForEach(func); 329 sceneList.ForEach(func);
330 } 330 }
331 else 331 else
332 { 332 {
333 func(m_currentScene); 333 func(CurrentScene);
334 } 334 }
335 } 335 }
336 336
@@ -350,7 +350,7 @@ namespace OpenSim.Region.Framework.Scenes
350 || (String.Compare(regionName, "..") == 0) 350 || (String.Compare(regionName, "..") == 0)
351 || (String.Compare(regionName, "/") == 0)) 351 || (String.Compare(regionName, "/") == 0))
352 { 352 {
353 m_currentScene = null; 353 CurrentScene = null;
354 return true; 354 return true;
355 } 355 }
356 else 356 else
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index e94ecee..b9f9c86 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2752,6 +2752,25 @@ namespace OpenSim.Region.Framework.Scenes
2752 if (objectGroup == this) 2752 if (objectGroup == this)
2753 return; 2753 return;
2754 2754
2755 // If the configured linkset capacity is greater than zero,
2756 // and the new linkset would have a prim count higher than this
2757 // value, do not link it.
2758 if (m_scene.m_linksetCapacity > 0 &&
2759 (PrimCount + objectGroup.PrimCount) >
2760 m_scene.m_linksetCapacity)
2761 {
2762 m_log.DebugFormat(
2763 "[SCENE OBJECT GROUP]: Cannot link group with root" +
2764 " part {0}, {1} ({2} prims) to group with root part" +
2765 " {3}, {4} ({5} prims) because the new linkset" +
2766 " would exceed the configured maximum of {6}",
2767 objectGroup.RootPart.Name, objectGroup.RootPart.UUID,
2768 objectGroup.PrimCount, RootPart.Name, RootPart.UUID,
2769 PrimCount, m_scene.m_linksetCapacity);
2770
2771 return;
2772 }
2773
2755 // 'linkPart' == the root of the group being linked into this group 2774 // 'linkPart' == the root of the group being linked into this group
2756 SceneObjectPart linkPart = objectGroup.m_rootPart; 2775 SceneObjectPart linkPart = objectGroup.m_rootPart;
2757 2776
@@ -3497,27 +3516,33 @@ namespace OpenSim.Region.Framework.Scenes
3497 /// <param name="scale"></param> 3516 /// <param name="scale"></param>
3498 public void GroupResize(Vector3 scale) 3517 public void GroupResize(Vector3 scale)
3499 { 3518 {
3500 scale.X = Math.Min(scale.X, Scene.m_maxNonphys); 3519// m_log.DebugFormat(
3501 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); 3520// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
3502 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
3503 3521
3504 PhysicsActor pa = m_rootPart.PhysActor; 3522 PhysicsActor pa = m_rootPart.PhysActor;
3505 3523
3506 if (pa != null && pa.IsPhysical) 3524 if (Scene != null)
3507 { 3525 {
3508 scale.X = Math.Min(scale.X, Scene.m_maxPhys); 3526 scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X));
3509 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); 3527 scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y));
3510 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); 3528 scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z));
3529
3530 if (pa != null && pa.IsPhysical)
3531 {
3532 scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X));
3533 scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y));
3534 scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z));
3535 }
3511 } 3536 }
3512 3537
3513 float x = (scale.X / RootPart.Scale.X); 3538 float x = (scale.X / RootPart.Scale.X);
3514 float y = (scale.Y / RootPart.Scale.Y); 3539 float y = (scale.Y / RootPart.Scale.Y);
3515 float z = (scale.Z / RootPart.Scale.Z); 3540 float z = (scale.Z / RootPart.Scale.Z);
3516 3541
3517 SceneObjectPart[] parts; 3542 SceneObjectPart[] parts = m_parts.GetArray();
3518 if (x > 1.0f || y > 1.0f || z > 1.0f) 3543
3544 if (Scene != null & (x > 1.0f || y > 1.0f || z > 1.0f))
3519 { 3545 {
3520 parts = m_parts.GetArray();
3521 for (int i = 0; i < parts.Length; i++) 3546 for (int i = 0; i < parts.Length; i++)
3522 { 3547 {
3523 SceneObjectPart obPart = parts[i]; 3548 SceneObjectPart obPart = parts[i];
@@ -3530,7 +3555,7 @@ namespace OpenSim.Region.Framework.Scenes
3530 3555
3531 if (pa != null && pa.IsPhysical) 3556 if (pa != null && pa.IsPhysical)
3532 { 3557 {
3533 if (oldSize.X * x > m_scene.m_maxPhys) 3558 if (oldSize.X * x > Scene.m_maxPhys)
3534 { 3559 {
3535 f = m_scene.m_maxPhys / oldSize.X; 3560 f = m_scene.m_maxPhys / oldSize.X;
3536 a = f / x; 3561 a = f / x;
@@ -3538,8 +3563,16 @@ namespace OpenSim.Region.Framework.Scenes
3538 y *= a; 3563 y *= a;
3539 z *= a; 3564 z *= a;
3540 } 3565 }
3566 else if (oldSize.X * x < Scene.m_minPhys)
3567 {
3568 f = m_scene.m_minPhys / oldSize.X;
3569 a = f / x;
3570 x *= a;
3571 y *= a;
3572 z *= a;
3573 }
3541 3574
3542 if (oldSize.Y * y > m_scene.m_maxPhys) 3575 if (oldSize.Y * y > Scene.m_maxPhys)
3543 { 3576 {
3544 f = m_scene.m_maxPhys / oldSize.Y; 3577 f = m_scene.m_maxPhys / oldSize.Y;
3545 a = f / y; 3578 a = f / y;
@@ -3547,8 +3580,16 @@ namespace OpenSim.Region.Framework.Scenes
3547 y *= a; 3580 y *= a;
3548 z *= a; 3581 z *= a;
3549 } 3582 }
3583 else if (oldSize.Y * y < Scene.m_minPhys)
3584 {
3585 f = m_scene.m_minPhys / oldSize.Y;
3586 a = f / y;
3587 x *= a;
3588 y *= a;
3589 z *= a;
3590 }
3550 3591
3551 if (oldSize.Z * z > m_scene.m_maxPhys) 3592 if (oldSize.Z * z > Scene.m_maxPhys)
3552 { 3593 {
3553 f = m_scene.m_maxPhys / oldSize.Z; 3594 f = m_scene.m_maxPhys / oldSize.Z;
3554 a = f / z; 3595 a = f / z;
@@ -3556,10 +3597,18 @@ namespace OpenSim.Region.Framework.Scenes
3556 y *= a; 3597 y *= a;
3557 z *= a; 3598 z *= a;
3558 } 3599 }
3600 else if (oldSize.Z * z < Scene.m_minPhys)
3601 {
3602 f = m_scene.m_minPhys / oldSize.Z;
3603 a = f / z;
3604 x *= a;
3605 y *= a;
3606 z *= a;
3607 }
3559 } 3608 }
3560 else 3609 else
3561 { 3610 {
3562 if (oldSize.X * x > m_scene.m_maxNonphys) 3611 if (oldSize.X * x > Scene.m_maxNonphys)
3563 { 3612 {
3564 f = m_scene.m_maxNonphys / oldSize.X; 3613 f = m_scene.m_maxNonphys / oldSize.X;
3565 a = f / x; 3614 a = f / x;
@@ -3567,8 +3616,16 @@ namespace OpenSim.Region.Framework.Scenes
3567 y *= a; 3616 y *= a;
3568 z *= a; 3617 z *= a;
3569 } 3618 }
3619 else if (oldSize.X * x < Scene.m_minNonphys)
3620 {
3621 f = m_scene.m_minNonphys / oldSize.X;
3622 a = f / x;
3623 x *= a;
3624 y *= a;
3625 z *= a;
3626 }
3570 3627
3571 if (oldSize.Y * y > m_scene.m_maxNonphys) 3628 if (oldSize.Y * y > Scene.m_maxNonphys)
3572 { 3629 {
3573 f = m_scene.m_maxNonphys / oldSize.Y; 3630 f = m_scene.m_maxNonphys / oldSize.Y;
3574 a = f / y; 3631 a = f / y;
@@ -3576,8 +3633,16 @@ namespace OpenSim.Region.Framework.Scenes
3576 y *= a; 3633 y *= a;
3577 z *= a; 3634 z *= a;
3578 } 3635 }
3636 else if (oldSize.Y * y < Scene.m_minNonphys)
3637 {
3638 f = m_scene.m_minNonphys / oldSize.Y;
3639 a = f / y;
3640 x *= a;
3641 y *= a;
3642 z *= a;
3643 }
3579 3644
3580 if (oldSize.Z * z > m_scene.m_maxNonphys) 3645 if (oldSize.Z * z > Scene.m_maxNonphys)
3581 { 3646 {
3582 f = m_scene.m_maxNonphys / oldSize.Z; 3647 f = m_scene.m_maxNonphys / oldSize.Z;
3583 a = f / z; 3648 a = f / z;
@@ -3585,6 +3650,14 @@ namespace OpenSim.Region.Framework.Scenes
3585 y *= a; 3650 y *= a;
3586 z *= a; 3651 z *= a;
3587 } 3652 }
3653 else if (oldSize.Z * z < Scene.m_minNonphys)
3654 {
3655 f = m_scene.m_minNonphys / oldSize.Z;
3656 a = f / z;
3657 x *= a;
3658 y *= a;
3659 z *= a;
3660 }
3588 } 3661 }
3589 } 3662 }
3590 } 3663 }
@@ -3597,7 +3670,6 @@ namespace OpenSim.Region.Framework.Scenes
3597 3670
3598 RootPart.Resize(prevScale); 3671 RootPart.Resize(prevScale);
3599 3672
3600 parts = m_parts.GetArray();
3601 for (int i = 0; i < parts.Length; i++) 3673 for (int i = 0; i < parts.Length; i++)
3602 { 3674 {
3603 SceneObjectPart obPart = parts[i]; 3675 SceneObjectPart obPart = parts[i];
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 49b771f..2191cfa 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -790,7 +790,7 @@ namespace OpenSim.Region.Framework.Scenes
790 } 790 }
791 catch (Exception e) 791 catch (Exception e)
792 { 792 {
793 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 793 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
794 } 794 }
795 } 795 }
796 } 796 }
@@ -813,7 +813,7 @@ namespace OpenSim.Region.Framework.Scenes
813 actor.Orientation = GetWorldRotation(); 813 actor.Orientation = GetWorldRotation();
814 814
815 // Tell the physics engines that this prim changed. 815 // Tell the physics engines that this prim changed.
816 if (ParentGroup.Scene != null) 816 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
817 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 817 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
818 } 818 }
819 819
@@ -2864,6 +2864,35 @@ namespace OpenSim.Region.Framework.Scenes
2864 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2864 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2865 } 2865 }
2866 2866
2867 // The Collision sounds code calls this
2868 public void SendCollisionSound(UUID soundID, double volume, Vector3 position)
2869 {
2870 if (soundID == UUID.Zero)
2871 return;
2872
2873 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
2874 if (soundModule == null)
2875 return;
2876
2877 if (volume > 1)
2878 volume = 1;
2879 if (volume < 0)
2880 volume = 0;
2881
2882 int now = Util.EnvironmentTickCount();
2883 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
2884 return;
2885
2886 LastColSoundSentTime = now;
2887
2888 UUID ownerID = OwnerID;
2889 UUID objectID = ParentGroup.RootPart.UUID;
2890 UUID parentID = ParentGroup.UUID;
2891 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
2892
2893 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 );
2894 }
2895
2867 public void PhysicsOutOfBounds(Vector3 pos) 2896 public void PhysicsOutOfBounds(Vector3 pos)
2868 { 2897 {
2869 m_log.Error("[PHYSICS]: Physical Object went out of bounds."); 2898 m_log.Error("[PHYSICS]: Physical Object went out of bounds.");
@@ -2895,38 +2924,6 @@ namespace OpenSim.Region.Framework.Scenes
2895 ScheduleTerseUpdate(); 2924 ScheduleTerseUpdate();
2896 } 2925 }
2897 2926
2898 public void PreloadSound(string sound)
2899 {
2900 // UUID ownerID = OwnerID;
2901 UUID objectID = ParentGroup.RootPart.UUID;
2902 UUID soundID = UUID.Zero;
2903
2904 if (!UUID.TryParse(sound, out soundID))
2905 {
2906 //Trys to fetch sound id from prim's inventory.
2907 //Prim's inventory doesn't support non script items yet
2908
2909 TaskInventory.LockItemsForRead(true);
2910
2911 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2912 {
2913 if (item.Value.Name == sound)
2914 {
2915 soundID = item.Value.ItemID;
2916 break;
2917 }
2918 }
2919
2920 TaskInventory.LockItemsForRead(false);
2921 }
2922
2923 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp)
2924 {
2925 if (!(Util.GetDistanceTo(sp.AbsolutePosition, AbsolutePosition) >= 100))
2926 sp.ControllingClient.SendPreLoadSound(objectID, objectID, soundID);
2927 });
2928 }
2929
2930 public void RemFlag(PrimFlags flag) 2927 public void RemFlag(PrimFlags flag)
2931 { 2928 {
2932 // PrimFlags prevflag = Flags; 2929 // PrimFlags prevflag = Flags;
@@ -2979,17 +2976,20 @@ namespace OpenSim.Region.Framework.Scenes
2979 /// <param name="scale"></param> 2976 /// <param name="scale"></param>
2980 public void Resize(Vector3 scale) 2977 public void Resize(Vector3 scale)
2981 { 2978 {
2982 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys);
2983 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys);
2984 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys);
2985
2986 PhysicsActor pa = PhysActor; 2979 PhysicsActor pa = PhysActor;
2987 2980
2988 if (pa != null && pa.IsPhysical) 2981 if (ParentGroup.Scene != null)
2989 { 2982 {
2990 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); 2983 scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X));
2991 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); 2984 scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y));
2992 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); 2985 scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z));
2986
2987 if (pa != null && pa.IsPhysical)
2988 {
2989 scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X));
2990 scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y));
2991 scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z));
2992 }
2993 } 2993 }
2994 2994
2995// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); 2995// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
@@ -3086,7 +3086,7 @@ namespace OpenSim.Region.Framework.Scenes
3086 // UUID, Name, TimeStampFull); 3086 // UUID, Name, TimeStampFull);
3087 3087
3088 if (ParentGroup.Scene != null) 3088 if (ParentGroup.Scene != null)
3089 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this); 3089 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true);
3090 } 3090 }
3091 3091
3092 /// <summary> 3092 /// <summary>
@@ -3120,7 +3120,7 @@ namespace OpenSim.Region.Framework.Scenes
3120 } 3120 }
3121 3121
3122 if (ParentGroup.Scene != null) 3122 if (ParentGroup.Scene != null)
3123 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this); 3123 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false);
3124 } 3124 }
3125 3125
3126 public void ScriptSetPhysicsStatus(bool UsePhysics) 3126 public void ScriptSetPhysicsStatus(bool UsePhysics)
@@ -3295,126 +3295,6 @@ namespace OpenSim.Region.Framework.Scenes
3295 } 3295 }
3296 3296
3297 /// <summary> 3297 /// <summary>
3298 /// Trigger or play an attached sound in this part's inventory.
3299 /// </summary>
3300 /// <param name="sound"></param>
3301 /// <param name="volume"></param>
3302 /// <param name="triggered"></param>
3303 /// <param name="flags"></param>
3304 public void SendSound(string sound, double volume, bool triggered, byte flags, float radius, bool useMaster, bool isMaster)
3305 {
3306 if (volume > 1)
3307 volume = 1;
3308 if (volume < 0)
3309 volume = 0;
3310
3311 UUID ownerID = OwnerID;
3312 UUID objectID = ParentGroup.RootPart.UUID;
3313 UUID parentID = ParentGroup.UUID;
3314
3315 UUID soundID = UUID.Zero;
3316 Vector3 position = AbsolutePosition; // region local
3317 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
3318
3319 if (!UUID.TryParse(sound, out soundID))
3320 {
3321 // search sound file from inventory
3322 TaskInventory.LockItemsForRead(true);
3323 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
3324 {
3325 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
3326 {
3327 soundID = item.Value.ItemID;
3328 break;
3329 }
3330 }
3331 TaskInventory.LockItemsForRead(false);
3332 }
3333
3334 if (soundID == UUID.Zero)
3335 return;
3336
3337 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
3338 if (soundModule != null)
3339 {
3340 if (useMaster)
3341 {
3342 if (isMaster)
3343 {
3344 if (triggered)
3345 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, radius);
3346 else
3347 soundModule.PlayAttachedSound(soundID, ownerID, objectID, volume, position, flags, radius);
3348 ParentGroup.PlaySoundMasterPrim = this;
3349 ownerID = OwnerID;
3350 objectID = ParentGroup.RootPart.UUID;
3351 parentID = ParentGroup.UUID;
3352 position = AbsolutePosition; // region local
3353 regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
3354 if (triggered)
3355 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, radius);
3356 else
3357 soundModule.PlayAttachedSound(soundID, ownerID, objectID, volume, position, flags, radius);
3358 foreach (SceneObjectPart prim in ParentGroup.PlaySoundSlavePrims)
3359 {
3360 ownerID = prim.OwnerID;
3361 objectID = prim.ParentGroup.RootPart.UUID;
3362 parentID = prim.ParentGroup.UUID;
3363 position = prim.AbsolutePosition; // region local
3364 regionHandle = prim.ParentGroup.Scene.RegionInfo.RegionHandle;
3365 if (triggered)
3366 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, radius);
3367 else
3368 soundModule.PlayAttachedSound(soundID, ownerID, objectID, volume, position, flags, radius);
3369 }
3370 ParentGroup.PlaySoundSlavePrims.Clear();
3371 ParentGroup.PlaySoundMasterPrim = null;
3372 }
3373 else
3374 {
3375 ParentGroup.PlaySoundSlavePrims.Add(this);
3376 }
3377 }
3378 else
3379 {
3380 if (triggered)
3381 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, radius);
3382 else
3383 soundModule.PlayAttachedSound(soundID, ownerID, objectID, volume, position, flags, radius);
3384 }
3385 }
3386 }
3387
3388 public void SendCollisionSound(UUID soundID, double volume, Vector3 position)
3389 {
3390 if (soundID == UUID.Zero)
3391 return;
3392
3393 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
3394 if (soundModule == null)
3395 return;
3396
3397 if (volume > 1)
3398 volume = 1;
3399 if (volume < 0)
3400 volume = 0;
3401
3402 int now = Util.EnvironmentTickCount();
3403 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
3404 return;
3405
3406 LastColSoundSentTime = now;
3407
3408 UUID ownerID = OwnerID;
3409 UUID objectID = ParentGroup.RootPart.UUID;
3410 UUID parentID = ParentGroup.UUID;
3411 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
3412
3413 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 );
3414 }
3415
3416
3417 /// <summary>
3418 /// Send a terse update to all clients 3298 /// Send a terse update to all clients
3419 /// </summary> 3299 /// </summary>
3420 public void SendTerseUpdateToAllClients() 3300 public void SendTerseUpdateToAllClients()
@@ -3575,23 +3455,32 @@ namespace OpenSim.Region.Framework.Scenes
3575 } 3455 }
3576 3456
3577 /// <summary> 3457 /// <summary>
3578 /// Set the color of prim faces 3458 /// Set the color & alpha of prim faces
3579 /// </summary> 3459 /// </summary>
3580 /// <param name="color"></param>
3581 /// <param name="face"></param> 3460 /// <param name="face"></param>
3582 public void SetFaceColor(Vector3 color, int face) 3461 /// <param name="color"></param>
3462 /// <param name="alpha"></param>
3463 public void SetFaceColorAlpha(int face, Vector3 color, double ?alpha)
3583 { 3464 {
3465 Vector3 clippedColor = Util.Clip(color, 0.0f, 1.0f);
3466 float clippedAlpha = alpha.HasValue ?
3467 Util.Clip((float)alpha.Value, 0.0f, 1.0f) : 0;
3468
3584 // The only way to get a deep copy/ If we don't do this, we can 3469 // The only way to get a deep copy/ If we don't do this, we can
3585 // mever detect color changes further down. 3470 // never detect color changes further down.
3586 Byte[] buf = Shape.Textures.GetBytes(); 3471 Byte[] buf = Shape.Textures.GetBytes();
3587 Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); 3472 Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length);
3588 Color4 texcolor; 3473 Color4 texcolor;
3589 if (face >= 0 && face < GetNumberOfSides()) 3474 if (face >= 0 && face < GetNumberOfSides())
3590 { 3475 {
3591 texcolor = tex.CreateFace((uint)face).RGBA; 3476 texcolor = tex.CreateFace((uint)face).RGBA;
3592 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3477 texcolor.R = clippedColor.X;
3593 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3478 texcolor.G = clippedColor.Y;
3594 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3479 texcolor.B = clippedColor.Z;
3480 if (alpha.HasValue)
3481 {
3482 texcolor.A = clippedAlpha;
3483 }
3595 tex.FaceTextures[face].RGBA = texcolor; 3484 tex.FaceTextures[face].RGBA = texcolor;
3596 UpdateTextureEntry(tex.GetBytes()); 3485 UpdateTextureEntry(tex.GetBytes());
3597 return; 3486 return;
@@ -3603,15 +3492,23 @@ namespace OpenSim.Region.Framework.Scenes
3603 if (tex.FaceTextures[i] != null) 3492 if (tex.FaceTextures[i] != null)
3604 { 3493 {
3605 texcolor = tex.FaceTextures[i].RGBA; 3494 texcolor = tex.FaceTextures[i].RGBA;
3606 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3495 texcolor.R = clippedColor.X;
3607 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3496 texcolor.G = clippedColor.Y;
3608 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3497 texcolor.B = clippedColor.Z;
3498 if (alpha.HasValue)
3499 {
3500 texcolor.A = clippedAlpha;
3501 }
3609 tex.FaceTextures[i].RGBA = texcolor; 3502 tex.FaceTextures[i].RGBA = texcolor;
3610 } 3503 }
3611 texcolor = tex.DefaultTexture.RGBA; 3504 texcolor = tex.DefaultTexture.RGBA;
3612 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3505 texcolor.R = clippedColor.X;
3613 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3506 texcolor.G = clippedColor.Y;
3614 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3507 texcolor.B = clippedColor.Z;
3508 if (alpha.HasValue)
3509 {
3510 texcolor.A = clippedAlpha;
3511 }
3615 tex.DefaultTexture.RGBA = texcolor; 3512 tex.DefaultTexture.RGBA = texcolor;
3616 } 3513 }
3617 UpdateTextureEntry(tex.GetBytes()); 3514 UpdateTextureEntry(tex.GetBytes());
@@ -4899,6 +4796,57 @@ namespace OpenSim.Region.Framework.Scenes
4899 ScheduleFullUpdate(); 4796 ScheduleFullUpdate();
4900 } 4797 }
4901 4798
4799 public void UpdateSlice(float begin, float end)
4800 {
4801 if (end < begin)
4802 {
4803 float temp = begin;
4804 begin = end;
4805 end = temp;
4806 }
4807 end = Math.Min(1f, Math.Max(0f, end));
4808 begin = Math.Min(Math.Min(1f, Math.Max(0f, begin)), end - 0.02f);
4809 if (begin < 0.02f && end < 0.02f)
4810 {
4811 begin = 0f;
4812 end = 0.02f;
4813 }
4814
4815 ushort uBegin = (ushort)(50000.0 * begin);
4816 ushort uEnd = (ushort)(50000.0 * (1f - end));
4817 bool updatePossiblyNeeded = false;
4818 PrimType primType = GetPrimType();
4819 if (primType == PrimType.SPHERE || primType == PrimType.TORUS || primType == PrimType.TUBE || primType == PrimType.RING)
4820 {
4821 if (m_shape.ProfileBegin != uBegin || m_shape.ProfileEnd != uEnd)
4822 {
4823 m_shape.ProfileBegin = uBegin;
4824 m_shape.ProfileEnd = uEnd;
4825 updatePossiblyNeeded = true;
4826 }
4827 }
4828 else if (m_shape.PathBegin != uBegin || m_shape.PathEnd != uEnd)
4829 {
4830 m_shape.PathBegin = uBegin;
4831 m_shape.PathEnd = uEnd;
4832 updatePossiblyNeeded = true;
4833 }
4834
4835 if (updatePossiblyNeeded && ParentGroup != null)
4836 {
4837 ParentGroup.HasGroupChanged = true;
4838 }
4839 if (updatePossiblyNeeded && PhysActor != null)
4840 {
4841 PhysActor.Shape = m_shape;
4842 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
4843 }
4844 if (updatePossiblyNeeded)
4845 {
4846 ScheduleFullUpdate();
4847 }
4848 }
4849
4902 /// <summary> 4850 /// <summary>
4903 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics 4851 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
4904 /// engine can use it. 4852 /// engine can use it.
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index e010864..3a9a146 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -97,6 +97,15 @@ namespace OpenSim.Region.Framework.Scenes
97 QueryScriptStates(); 97 QueryScriptStates();
98 } 98 }
99 } 99 }
100
101 public int Count
102 {
103 get
104 {
105 lock (m_items)
106 return m_items.Count;
107 }
108 }
100 109
101 /// <summary> 110 /// <summary>
102 /// Constructor 111 /// Constructor
@@ -235,31 +244,52 @@ namespace OpenSim.Region.Framework.Scenes
235 if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null) 244 if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null)
236 return; 245 return;
237 246
238 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
239 if (engines == null) // No engine at all
240 return;
241
242 Items.LockItemsForRead(true); 247 Items.LockItemsForRead(true);
243 foreach (TaskInventoryItem item in Items.Values) 248 foreach (TaskInventoryItem item in Items.Values)
244 { 249 {
245 if (item.InvType == (int)InventoryType.LSL) 250 if (item.InvType == (int)InventoryType.LSL)
246 { 251 {
247 foreach (IScriptModule e in engines) 252 bool running;
248 { 253 if (TryGetScriptInstanceRunning(m_part.ParentGroup.Scene, item, out running))
249 bool running; 254 item.ScriptRunning = running;
250
251 if (e.HasScript(item.ItemID, out running))
252 {
253 item.ScriptRunning = running;
254 break;
255 }
256 }
257 } 255 }
258 } 256 }
259 257
260 Items.LockItemsForRead(false); 258 Items.LockItemsForRead(false);
261 } 259 }
262 260
261 public bool TryGetScriptInstanceRunning(UUID itemId, out bool running)
262 {
263 running = false;
264
265 TaskInventoryItem item = GetInventoryItem(itemId);
266
267 if (item == null)
268 return false;
269
270 return TryGetScriptInstanceRunning(m_part.ParentGroup.Scene, item, out running);
271 }
272
273 public static bool TryGetScriptInstanceRunning(Scene scene, TaskInventoryItem item, out bool running)
274 {
275 running = false;
276
277 if (item.InvType != (int)InventoryType.LSL)
278 return false;
279
280 IScriptModule[] engines = scene.RequestModuleInterfaces<IScriptModule>();
281 if (engines == null) // No engine at all
282 return false;
283
284 foreach (IScriptModule e in engines)
285 {
286 if (e.HasScript(item.ItemID, out running))
287 return true;
288 }
289
290 return false;
291 }
292
263 public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 293 public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
264 { 294 {
265 int scriptsValidForStarting = 0; 295 int scriptsValidForStarting = 0;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index a8aa551..bacc9c9 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -69,14 +69,15 @@ namespace OpenSim.Region.Framework.Scenes
69 public ScriptControlled eventControls; 69 public ScriptControlled eventControls;
70 } 70 }
71 71
72 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs); 72 public delegate void SendCoarseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs);
73 73
74 public class ScenePresence : EntityBase, IScenePresence 74 public class ScenePresence : EntityBase, IScenePresence
75 { 75 {
76// ~ScenePresence() 76// ~ScenePresence()
77// { 77// {
78// m_log.Debug("[SCENE PRESENCE] Destructor called"); 78// m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name);
79// } 79// }
80
80 private void TriggerScenePresenceUpdated() 81 private void TriggerScenePresenceUpdated()
81 { 82 {
82 if (m_scene != null) 83 if (m_scene != null)
@@ -188,7 +189,7 @@ namespace OpenSim.Region.Framework.Scenes
188 /// </summary> 189 /// </summary>
189 public bool SitGround { get; private set; } 190 public bool SitGround { get; private set; }
190 191
191 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 192 private SendCoarseLocationsMethod m_sendCoarseLocationsMethod;
192 193
193 //private Vector3 m_requestedSitOffset = new Vector3(); 194 //private Vector3 m_requestedSitOffset = new Vector3();
194 195
@@ -546,7 +547,7 @@ namespace OpenSim.Region.Framework.Scenes
546 { 547 {
547 try 548 try
548 { 549 {
549 PhysicsActor.Velocity = value; 550 PhysicsActor.TargetVelocity = value;
550 } 551 }
551 catch (Exception e) 552 catch (Exception e)
552 { 553 {
@@ -570,7 +571,18 @@ namespace OpenSim.Region.Framework.Scenes
570 set 571 set
571 { 572 {
572 m_bodyRot = value; 573 m_bodyRot = value;
573// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 574 // m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
575 if (PhysicsActor != null)
576 {
577 try
578 {
579 PhysicsActor.Orientation = value;
580 }
581 catch (Exception e)
582 {
583 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
584 }
585 }
574 } 586 }
575 } 587 }
576 588
@@ -711,7 +723,7 @@ namespace OpenSim.Region.Framework.Scenes
711 AttachmentsSyncLock = new Object(); 723 AttachmentsSyncLock = new Object();
712 AllowMovement = true; 724 AllowMovement = true;
713 IsChildAgent = true; 725 IsChildAgent = true;
714 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 726 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
715 Animator = new ScenePresenceAnimator(this); 727 Animator = new ScenePresenceAnimator(this);
716 PresenceType = type; 728 PresenceType = type;
717 DrawDistance = world.DefaultDrawDistance; 729 DrawDistance = world.DefaultDrawDistance;
@@ -793,6 +805,7 @@ namespace OpenSim.Region.Framework.Scenes
793 ControllingClient.OnChangeAnim += avnHandleChangeAnim; 805 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
794 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 806 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
795 ControllingClient.OnAutoPilotGo += MoveToTarget; 807 ControllingClient.OnAutoPilotGo += MoveToTarget;
808 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
796 809
797 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 810 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
798 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 811 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -974,7 +987,9 @@ namespace OpenSim.Region.Framework.Scenes
974 { 987 {
975 if (wasChild && HasAttachments()) 988 if (wasChild && HasAttachments())
976 { 989 {
977 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); 990 m_log.DebugFormat(
991 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
992
978 // Resume scripts 993 // Resume scripts
979 Util.FireAndForget(delegate(object x) { 994 Util.FireAndForget(delegate(object x) {
980 foreach (SceneObjectGroup sog in m_attachments) 995 foreach (SceneObjectGroup sog in m_attachments)
@@ -1530,17 +1545,22 @@ namespace OpenSim.Region.Framework.Scenes
1530 bool DCFlagKeyPressed = false; 1545 bool DCFlagKeyPressed = false;
1531 Vector3 agent_control_v3 = Vector3.Zero; 1546 Vector3 agent_control_v3 = Vector3.Zero;
1532 1547
1533 bool oldflying = Flying; 1548 bool newFlying = actor.Flying;
1534 1549
1535 if (ForceFly) 1550 if (ForceFly)
1536 actor.Flying = true; 1551 newFlying = true;
1537 else if (FlyDisabled) 1552 else if (FlyDisabled)
1538 actor.Flying = false; 1553 newFlying = false;
1539 else 1554 else
1540 actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1555 newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1541 1556
1542 if (actor.Flying != oldflying) 1557 if (actor.Flying != newFlying)
1558 {
1559 // Note: ScenePresence.Flying is actually fetched from the physical actor
1560 // so setting PhysActor.Flying here also sets the ScenePresence's value.
1561 actor.Flying = newFlying;
1543 update_movementflag = true; 1562 update_movementflag = true;
1563 }
1544 1564
1545 if (ParentID == 0) 1565 if (ParentID == 0)
1546 { 1566 {
@@ -1835,8 +1855,16 @@ namespace OpenSim.Region.Framework.Scenes
1835// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", 1855// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1836// Name, pos, m_scene.RegionInfo.RegionName); 1856// Name, pos, m_scene.RegionInfo.RegionName);
1837 1857
1838 if (pos.X < 0 || pos.X >= Constants.RegionSize 1858 // Allow move to another sub-region within a megaregion
1839 || pos.Y < 0 || pos.Y >= Constants.RegionSize 1859 Vector2 regionSize;
1860 IRegionCombinerModule regionCombinerModule = m_scene.RequestModuleInterface<IRegionCombinerModule>();
1861 if (regionCombinerModule != null)
1862 regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
1863 else
1864 regionSize = new Vector2(Constants.RegionSize);
1865
1866 if (pos.X < 0 || pos.X >= regionSize.X
1867 || pos.Y < 0 || pos.Y >= regionSize.Y
1840 || pos.Z < 0) 1868 || pos.Z < 0)
1841 return; 1869 return;
1842 1870
@@ -1850,7 +1878,16 @@ namespace OpenSim.Region.Framework.Scenes
1850// pos.Z = AbsolutePosition.Z; 1878// pos.Z = AbsolutePosition.Z;
1851// } 1879// }
1852 1880
1853 float terrainHeight = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1881 // Get terrain height for sub-region in a megaregion if necessary
1882 int X = (int)((m_scene.RegionInfo.RegionLocX * Constants.RegionSize) + pos.X);
1883 int Y = (int)((m_scene.RegionInfo.RegionLocY * Constants.RegionSize) + pos.Y);
1884 UUID target_regionID = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y).RegionID;
1885 Scene targetScene = m_scene;
1886
1887 if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene))
1888 targetScene = m_scene;
1889
1890 float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % Constants.RegionSize), (int)(pos.Y % Constants.RegionSize)];
1854 pos.Z = Math.Max(terrainHeight, pos.Z); 1891 pos.Z = Math.Max(terrainHeight, pos.Z);
1855 1892
1856 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is 1893 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is
@@ -2622,17 +2659,17 @@ namespace OpenSim.Region.Framework.Scenes
2622 2659
2623 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2660 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
2624 { 2661 {
2625 SendCourseLocationsMethod d = m_sendCourseLocationsMethod; 2662 SendCoarseLocationsMethod d = m_sendCoarseLocationsMethod;
2626 if (d != null) 2663 if (d != null)
2627 { 2664 {
2628 d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs); 2665 d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs);
2629 } 2666 }
2630 } 2667 }
2631 2668
2632 public void SetSendCourseLocationMethod(SendCourseLocationsMethod d) 2669 public void SetSendCoarseLocationMethod(SendCoarseLocationsMethod d)
2633 { 2670 {
2634 if (d != null) 2671 if (d != null)
2635 m_sendCourseLocationsMethod = d; 2672 m_sendCoarseLocationsMethod = d;
2636 } 2673 }
2637 2674
2638 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2675 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
@@ -2836,7 +2873,7 @@ namespace OpenSim.Region.Framework.Scenes
2836 #region Significant Movement Method 2873 #region Significant Movement Method
2837 2874
2838 /// <summary> 2875 /// <summary>
2839 /// This checks for a significant movement and sends a courselocationchange update 2876 /// This checks for a significant movement and sends a coarselocationchange update
2840 /// </summary> 2877 /// </summary>
2841 protected void CheckForSignificantMovement() 2878 protected void CheckForSignificantMovement()
2842 { 2879 {
@@ -3166,6 +3203,10 @@ namespace OpenSim.Region.Framework.Scenes
3166 } 3203 }
3167 3204
3168 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3205 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3206 private void RaiseUpdateThrottles()
3207 {
3208 m_scene.EventManager.TriggerThrottleUpdate(this);
3209 }
3169 /// <summary> 3210 /// <summary>
3170 /// This updates important decision making data about a child agent 3211 /// This updates important decision making data about a child agent
3171 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3212 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3269,6 +3310,7 @@ namespace OpenSim.Region.Framework.Scenes
3269 } 3310 }
3270 catch { } 3311 catch { }
3271 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; 3312 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation;
3313 cAgent.AnimState = Animator.Animations.ImplicitDefaultAnimation;
3272 3314
3273 if (Scene.AttachmentsModule != null) 3315 if (Scene.AttachmentsModule != null)
3274 Scene.AttachmentsModule.CopyAttachments(this, cAgent); 3316 Scene.AttachmentsModule.CopyAttachments(this, cAgent);
@@ -3345,6 +3387,8 @@ namespace OpenSim.Region.Framework.Scenes
3345 Animator.Animations.FromArray(cAgent.Anims); 3387 Animator.Animations.FromArray(cAgent.Anims);
3346 if (cAgent.DefaultAnim != null) 3388 if (cAgent.DefaultAnim != null)
3347 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); 3389 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
3390 if (cAgent.AnimState != null)
3391 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
3348 3392
3349 if (Scene.AttachmentsModule != null) 3393 if (Scene.AttachmentsModule != null)
3350 Scene.AttachmentsModule.CopyAttachments(cAgent, this); 3394 Scene.AttachmentsModule.CopyAttachments(cAgent, this);
@@ -3402,7 +3446,7 @@ namespace OpenSim.Region.Framework.Scenes
3402 3446
3403 PhysicsActor = scene.AddAvatar( 3447 PhysicsActor = scene.AddAvatar(
3404 LocalId, Firstname + "." + Lastname, pVec, 3448 LocalId, Firstname + "." + Lastname, pVec,
3405 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3449 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3406 3450
3407 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3451 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3408 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3452 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3627,13 +3671,16 @@ namespace OpenSim.Region.Framework.Scenes
3627 public List<SceneObjectGroup> GetAttachments(uint attachmentPoint) 3671 public List<SceneObjectGroup> GetAttachments(uint attachmentPoint)
3628 { 3672 {
3629 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(); 3673 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
3630 3674
3631 lock (m_attachments) 3675 if (attachmentPoint >= 0)
3632 { 3676 {
3633 foreach (SceneObjectGroup so in m_attachments) 3677 lock (m_attachments)
3634 { 3678 {
3635 if (attachmentPoint == so.AttachmentPoint) 3679 foreach (SceneObjectGroup so in m_attachments)
3636 attachments.Add(so); 3680 {
3681 if (attachmentPoint == so.AttachmentPoint)
3682 attachments.Add(so);
3683 }
3637 } 3684 }
3638 } 3685 }
3639 3686
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 756b1f4..5398ab9 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -47,6 +47,7 @@ namespace OpenSim.Region.Framework.Scenes
47 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 47 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates"; 49 public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates";
50 public const string SlowFramesStatName = "SlowFrames";
50 51
51 public delegate void SendStatResult(SimStats stats); 52 public delegate void SendStatResult(SimStats stats);
52 53
@@ -129,6 +130,16 @@ namespace OpenSim.Region.Framework.Scenes
129 } 130 }
130 131
131 /// <summary> 132 /// <summary>
133 /// Number of frames that have taken longer to process than Scene.MIN_FRAME_TIME
134 /// </summary>
135 public Stat SlowFramesStat { get; private set; }
136
137 /// <summary>
138 /// The threshold at which we log a slow frame.
139 /// </summary>
140 public int SlowFramesStatReportThreshold { get; private set; }
141
142 /// <summary>
132 /// Extra sim statistics that are used by monitors but not sent to the client. 143 /// Extra sim statistics that are used by monitors but not sent to the client.
133 /// </summary> 144 /// </summary>
134 /// <value> 145 /// <value>
@@ -226,6 +237,24 @@ namespace OpenSim.Region.Framework.Scenes
226 237
227 if (StatsManager.SimExtraStats != null) 238 if (StatsManager.SimExtraStats != null)
228 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket; 239 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket;
240
241 /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
242 /// longer than ideal (which in itself is a concern).
243 SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.MinFrameTime * 1000 * 1.2);
244
245 SlowFramesStat
246 = new Stat(
247 "SlowFrames",
248 "Slow Frames",
249 "Number of frames where frame time has been significantly longer than the desired frame time.",
250 " frames",
251 "scene",
252 m_scene.Name,
253 StatType.Push,
254 null,
255 StatVerbosity.Info);
256
257 StatsManager.RegisterStat(SlowFramesStat);
229 } 258 }
230 259
231 public void Close() 260 public void Close()
@@ -443,6 +472,7 @@ namespace OpenSim.Region.Framework.Scenes
443 lock (m_lastReportedExtraSimStats) 472 lock (m_lastReportedExtraSimStats)
444 { 473 {
445 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor; 474 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor;
475 m_lastReportedExtraSimStats[SlowFramesStat.ShortName] = (float)SlowFramesStat.Value;
446 476
447 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats(); 477 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
448 478
@@ -563,6 +593,11 @@ namespace OpenSim.Region.Framework.Scenes
563 public void addFrameMS(int ms) 593 public void addFrameMS(int ms)
564 { 594 {
565 m_frameMS += ms; 595 m_frameMS += ms;
596
597 // At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
598 // longer than ideal due to the inaccuracy of the Sleep in Scene.Update() (which in itself is a concern).
599 if (ms > SlowFramesStatReportThreshold)
600 SlowFramesStat.Value++;
566 } 601 }
567 602
568 public void addNetMS(int ms) 603 public void addNetMS(int ms)
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs
new file mode 100644
index 0000000..ab56f4e
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Threading;
32using NUnit.Framework;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces;
38using OpenSim.Tests.Common;
39using OpenSim.Tests.Common.Mock;
40
41namespace OpenSim.Region.Framework.Scenes.Tests
42{
43 [TestFixture]
44 public class SceneManagerTests
45 {
46 [Test]
47 public void TestClose()
48 {
49 TestHelpers.InMethod();
50
51 SceneHelpers sh = new SceneHelpers();
52 Scene scene = sh.SetupScene();
53
54 sh.SceneManager.Close();
55 Assert.That(scene.ShuttingDown, Is.True);
56 }
57 }
58} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
index 3398a53..5b334c6 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using System.Threading; 31using System.Threading;
31using NUnit.Framework; 32using NUnit.Framework;
@@ -33,6 +34,7 @@ using OpenMetaverse;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Communications; 35using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces;
36using OpenSim.Tests.Common; 38using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock; 39using OpenSim.Tests.Common.Mock;
38 40
@@ -42,7 +44,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
42 /// Basic scene object tests (create, read and delete but not update). 44 /// Basic scene object tests (create, read and delete but not update).
43 /// </summary> 45 /// </summary>
44 [TestFixture] 46 [TestFixture]
45 public class SceneObjectBasicTests 47 public class SceneObjectBasicTests : OpenSimTestCase
46 { 48 {
47// [TearDown] 49// [TearDown]
48// public void TearDown() 50// public void TearDown()
@@ -237,38 +239,60 @@ namespace OpenSim.Region.Framework.Scenes.Tests
237 /// <summary> 239 /// <summary>
238 /// Test deleting an object asynchronously to user inventory. 240 /// Test deleting an object asynchronously to user inventory.
239 /// </summary> 241 /// </summary>
240 //[Test] 242// [Test]
241 //public void TestDeleteSceneObjectAsyncToUserInventory() 243 public void TestDeleteSceneObjectAsyncToUserInventory()
242 //{ 244 {
243 // TestHelper.InMethod(); 245 TestHelpers.InMethod();
244 // //log4net.Config.XmlConfigurator.Configure(); 246 TestHelpers.EnableLogging();
245 247
246 // UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); 248 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001");
247 // string myObjectName = "Fred"; 249 string myObjectName = "Fred";
248 250
249 // TestScene scene = SceneSetupHelpers.SetupScene(); 251 TestScene scene = new SceneHelpers().SetupScene();
250 // SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene, myObjectName); 252
251 253 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
252 // Assert.That( 254 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
253 // scene.CommsManager.UserAdminService.AddUser( 255 sogd.Enabled = false;
254 // "Bob", "Hoskins", "test", "test@test.com", 1000, 1000, agentId), 256
255 // Is.EqualTo(agentId)); 257 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, myObjectName, agentId);
256 258
257 // IClientAPI client = SceneSetupHelpers.AddRootAgent(scene, agentId); 259// Assert.That(
258 260// scene.CommsManager.UserAdminService.AddUser(
259 // CachedUserInfo userInfo = scene.CommsManager.UserProfileCacheService.GetUserDetails(agentId); 261// "Bob", "Hoskins", "test", "test@test.com", 1000, 1000, agentId),
260 // Assert.That(userInfo, Is.Not.Null); 262// Is.EqualTo(agentId));
261 // Assert.That(userInfo.RootFolder, Is.Not.Null); 263
262 264 UserAccount ua = UserAccountHelpers.CreateUserWithInventory(scene, agentId);
263 // SceneSetupHelpers.DeleteSceneObjectAsync(scene, part, DeRezAction.Take, userInfo.RootFolder.ID, client); 265 InventoryFolderBase folder1
264 266 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, ua.PrincipalID, "folder1");
265 // // Check that we now have the taken part in our inventory 267
266 // Assert.That(myObjectName, Is.EqualTo(userInfo.RootFolder.FindItemByPath(myObjectName).Name)); 268 IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient;
267 269 scene.DeRezObjects(client, new List<uint>() { so.LocalId }, UUID.Zero, DeRezAction.Take, folder1.ID);
268 // // Check that the taken part has actually disappeared 270
269 // SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); 271 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId);
270 // Assert.That(retrievedPart, Is.Null); 272
271 //} 273 Assert.That(retrievedPart, Is.Not.Null);
274 Assert.That(so.IsDeleted, Is.False);
275
276 sogd.InventoryDeQueueAndDelete();
277
278 Assert.That(so.IsDeleted, Is.True);
279
280 SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId);
281 Assert.That(retrievedPart2, Is.Null);
282
283// SceneSetupHelpers.DeleteSceneObjectAsync(scene, part, DeRezAction.Take, userInfo.RootFolder.ID, client);
284
285 InventoryItemBase retrievedItem
286 = UserInventoryHelpers.GetInventoryItem(
287 scene.InventoryService, ua.PrincipalID, "folder1/" + myObjectName);
288
289 // Check that we now have the taken part in our inventory
290 Assert.That(retrievedItem, Is.Not.Null);
291
292 // Check that the taken part has actually disappeared
293// SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
294// Assert.That(retrievedPart, Is.Null);
295 }
272 296
273 /// <summary> 297 /// <summary>
274 /// Changing a scene object uuid changes the root part uuid. This is a valid operation if the object is not 298 /// Changing a scene object uuid changes the root part uuid. This is a valid operation if the object is not
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index 5758869..5faf131 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -141,7 +141,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
141 TestScene scene = new SceneHelpers().SetupScene(); 141 TestScene scene = new SceneHelpers().SetupScene();
142 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 142 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
143 143
144 scene.IncomingCloseAgent(sp.UUID); 144 scene.IncomingCloseAgent(sp.UUID, false);
145 145
146 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); 146 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
147 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); 147 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index d722a09..ac3da1e 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -65,5 +65,22 @@ namespace OpenSim.Region.Framework.Scenes.Tests
65 65
66 Assert.That(scene.Frame, Is.EqualTo(1)); 66 Assert.That(scene.Frame, Is.EqualTo(1));
67 } 67 }
68
69 [Test]
70 public void TestShutdownScene()
71 {
72 TestHelpers.InMethod();
73
74 Scene scene = new SceneHelpers().SetupScene();
75 scene.Close();
76
77 Assert.That(scene.ShuttingDown, Is.True);
78 Assert.That(scene.Active, Is.False);
79
80 // Trying to update a shutdown scene should result in no update
81 scene.Update(1);
82
83 Assert.That(scene.Frame, Is.EqualTo(0));
84 }
68 } 85 }
69} \ No newline at end of file 86} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index 44d2d45..9457ebb 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -50,9 +50,41 @@ using OpenSim.Tests.Common.Mock;
50namespace OpenSim.Region.Framework.Tests 50namespace OpenSim.Region.Framework.Tests
51{ 51{
52 [TestFixture] 52 [TestFixture]
53 public class UserInventoryTests 53 public class UserInventoryTests : OpenSimTestCase
54 { 54 {
55 [Test] 55 [Test]
56 public void TestCreateInventoryFolders()
57 {
58 TestHelpers.InMethod();
59// TestHelpers.EnableLogging();
60
61 // For this test both folders will have the same name which is legal in SL user inventories.
62 string foldersName = "f1";
63
64 Scene scene = new SceneHelpers().SetupScene();
65 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
66
67 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
68
69 List<InventoryFolderBase> oneFolder
70 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
71
72 Assert.That(oneFolder.Count, Is.EqualTo(1));
73 InventoryFolderBase firstRetrievedFolder = oneFolder[0];
74 Assert.That(firstRetrievedFolder.Name, Is.EqualTo(foldersName));
75
76 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
77
78 List<InventoryFolderBase> twoFolders
79 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
80
81 Assert.That(twoFolders.Count, Is.EqualTo(2));
82 Assert.That(twoFolders[0].Name, Is.EqualTo(foldersName));
83 Assert.That(twoFolders[1].Name, Is.EqualTo(foldersName));
84 Assert.That(twoFolders[0].ID, Is.Not.EqualTo(twoFolders[1].ID));
85 }
86
87 [Test]
56 public void TestGiveInventoryItem() 88 public void TestGiveInventoryItem()
57 { 89 {
58 TestHelpers.InMethod(); 90 TestHelpers.InMethod();
@@ -83,7 +115,7 @@ namespace OpenSim.Region.Framework.Tests
83 public void TestGiveInventoryFolder() 115 public void TestGiveInventoryFolder()
84 { 116 {
85 TestHelpers.InMethod(); 117 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure(); 118// TestHelpers.EnableLogging();
87 119
88 Scene scene = new SceneHelpers().SetupScene(); 120 Scene scene = new SceneHelpers().SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); 121 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index 411e421..2279e62 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -52,26 +52,23 @@ namespace OpenSim.Region.Framework.Scenes
52 public class UuidGatherer 52 public class UuidGatherer
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 /// <summary>
57 /// Asset cache used for gathering assets
58 /// </summary>
59 protected IAssetService m_assetCache;
60
61 /// <summary>
62 /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate
63 /// asset was found by the asset service.
64 /// </summary>
65 private AssetBase m_requestedObjectAsset;
66 55
67 /// <summary> 56 protected IAssetService m_assetService;
68 /// Signal whether we are currently waiting for the asset service to deliver an asset. 57
69 /// </summary> 58// /// <summary>
70 private bool m_waitingForObjectAsset; 59// /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate
60// /// asset was found by the asset service.
61// /// </summary>
62// private AssetBase m_requestedObjectAsset;
63//
64// /// <summary>
65// /// Signal whether we are currently waiting for the asset service to deliver an asset.
66// /// </summary>
67// private bool m_waitingForObjectAsset;
71 68
72 public UuidGatherer(IAssetService assetCache) 69 public UuidGatherer(IAssetService assetService)
73 { 70 {
74 m_assetCache = assetCache; 71 m_assetService = assetService;
75 } 72 }
76 73
77 /// <summary> 74 /// <summary>
@@ -191,18 +188,18 @@ namespace OpenSim.Region.Framework.Scenes
191 } 188 }
192 } 189 }
193 190
194 /// <summary> 191// /// <summary>
195 /// The callback made when we request the asset for an object from the asset service. 192// /// The callback made when we request the asset for an object from the asset service.
196 /// </summary> 193// /// </summary>
197 private void AssetReceived(string id, Object sender, AssetBase asset) 194// private void AssetReceived(string id, Object sender, AssetBase asset)
198 { 195// {
199 lock (this) 196// lock (this)
200 { 197// {
201 m_requestedObjectAsset = asset; 198// m_requestedObjectAsset = asset;
202 m_waitingForObjectAsset = false; 199// m_waitingForObjectAsset = false;
203 Monitor.Pulse(this); 200// Monitor.Pulse(this);
204 } 201// }
205 } 202// }
206 203
207 /// <summary> 204 /// <summary>
208 /// Get an asset synchronously, potentially using an asynchronous callback. If the 205 /// Get an asset synchronously, potentially using an asynchronous callback. If the
@@ -212,25 +209,29 @@ namespace OpenSim.Region.Framework.Scenes
212 /// <returns></returns> 209 /// <returns></returns>
213 protected virtual AssetBase GetAsset(UUID uuid) 210 protected virtual AssetBase GetAsset(UUID uuid)
214 { 211 {
215 m_waitingForObjectAsset = true; 212 return m_assetService.Get(uuid.ToString());
216 m_assetCache.Get(uuid.ToString(), this, AssetReceived);
217
218 // The asset cache callback can either
219 //
220 // 1. Complete on the same thread (if the asset is already in the cache) or
221 // 2. Come in via a different thread (if we need to go fetch it).
222 //
223 // The code below handles both these alternatives.
224 lock (this)
225 {
226 if (m_waitingForObjectAsset)
227 {
228 Monitor.Wait(this);
229 m_waitingForObjectAsset = false;
230 }
231 }
232 213
233 return m_requestedObjectAsset; 214 // XXX: Switching to do this synchronously where the call was async before but we always waited for it
215 // to complete anyway!
216// m_waitingForObjectAsset = true;
217// m_assetCache.Get(uuid.ToString(), this, AssetReceived);
218//
219// // The asset cache callback can either
220// //
221// // 1. Complete on the same thread (if the asset is already in the cache) or
222// // 2. Come in via a different thread (if we need to go fetch it).
223// //
224// // The code below handles both these alternatives.
225// lock (this)
226// {
227// if (m_waitingForObjectAsset)
228// {
229// Monitor.Wait(this);
230// m_waitingForObjectAsset = false;
231// }
232// }
233//
234// return m_requestedObjectAsset;
234 } 235 }
235 236
236 /// <summary> 237 /// <summary>
@@ -361,4 +362,47 @@ namespace OpenSim.Region.Framework.Scenes
361 } 362 }
362 } 363 }
363 } 364 }
365
366 public class HGUuidGatherer : UuidGatherer
367 {
368 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
369
370 protected string m_assetServerURL;
371
372 public HGUuidGatherer(IAssetService assetService, string assetServerURL)
373 : base(assetService)
374 {
375 m_assetServerURL = assetServerURL;
376 if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("="))
377 m_assetServerURL = m_assetServerURL + "/";
378 }
379
380 protected override AssetBase GetAsset(UUID uuid)
381 {
382 if (string.Empty == m_assetServerURL)
383 return base.GetAsset(uuid);
384 else
385 return FetchAsset(uuid);
386 }
387
388 public AssetBase FetchAsset(UUID assetID)
389 {
390
391 // Test if it's already here
392 AssetBase asset = m_assetService.Get(assetID.ToString());
393 if (asset == null)
394 {
395 // It's not, so fetch it from abroad
396 asset = m_assetService.Get(m_assetServerURL + assetID.ToString());
397 if (asset != null)
398 m_log.DebugFormat("[HGUUIDGatherer]: Copied asset {0} from {1} to local asset server", assetID, m_assetServerURL);
399 else
400 m_log.DebugFormat("[HGUUIDGatherer]: Failed to fetch asset {0} from {1}", assetID, m_assetServerURL);
401 }
402 //else
403 // m_log.DebugFormat("[HGUUIDGatherer]: Asset {0} from {1} was already here", assetID, m_assetServerURL);
404
405 return asset;
406 }
407 }
364} 408}