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.cs521
-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.cs689
-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.cs31
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs106
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs300
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs58
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs56
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs35
-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
18 files changed, 1568 insertions, 685 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 4a19c3b..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,6 +799,20 @@ 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
@@ -436,7 +876,7 @@ namespace OpenSim.Region.Framework.Scenes
436 /// the scripts may not have started yet 876 /// the scripts may not have started yet
437 /// 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
438 /// </summary> 878 /// </summary>
439 public delegate void OarFileLoaded(Guid guid, string message); 879 public delegate void OarFileLoaded(Guid guid, List<UUID> loadedScenes, string message);
440 public event OarFileLoaded OnOarFileLoaded; 880 public event OarFileLoaded OnOarFileLoaded;
441 881
442 /// <summary> 882 /// <summary>
@@ -489,10 +929,13 @@ namespace OpenSim.Region.Framework.Scenes
489 /// <param name="copy"></param> 929 /// <param name="copy"></param>
490 /// <param name="original"></param> 930 /// <param name="original"></param>
491 /// <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>
492 public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy; 935 public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy;
493 public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed); 936 public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed);
494 937
495 public delegate void SceneObjectPartUpdated(SceneObjectPart sop); 938 public delegate void SceneObjectPartUpdated(SceneObjectPart sop, bool full);
496 public event SceneObjectPartUpdated OnSceneObjectPartUpdated; 939 public event SceneObjectPartUpdated OnSceneObjectPartUpdated;
497 940
498 public delegate void ScenePresenceUpdated(ScenePresence sp); 941 public delegate void ScenePresenceUpdated(ScenePresence sp);
@@ -530,9 +973,28 @@ namespace OpenSim.Region.Framework.Scenes
530 public event PrimsLoaded OnPrimsLoaded; 973 public event PrimsLoaded OnPrimsLoaded;
531 974
532 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>
533 public event TeleportStart OnTeleportStart; 986 public event TeleportStart OnTeleportStart;
534 987
535 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>
536 public event TeleportFail OnTeleportFail; 998 public event TeleportFail OnTeleportFail;
537 999
538 public class MoneyTransferArgs : EventArgs 1000 public class MoneyTransferArgs : EventArgs
@@ -540,7 +1002,9 @@ namespace OpenSim.Region.Framework.Scenes
540 public UUID sender; 1002 public UUID sender;
541 public UUID receiver; 1003 public UUID receiver;
542 1004
543 // Always false. The SL protocol sucks. 1005 /// <summary>
1006 /// Always false. The SL protocol sucks.
1007 /// </summary>
544 public bool authenticated = false; 1008 public bool authenticated = false;
545 1009
546 public int amount; 1010 public int amount;
@@ -597,8 +1061,29 @@ namespace OpenSim.Region.Framework.Scenes
597 1061
598 public delegate void LandBuy(Object sender, LandBuyArgs e); 1062 public delegate void LandBuy(Object sender, LandBuyArgs e);
599 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>
600 public event MoneyTransferEvent OnMoneyTransfer; 1073 public event MoneyTransferEvent OnMoneyTransfer;
1074
1075 /// <summary>
1076 /// Triggered after after <see cref="OnValidateLandBuy"/>
1077 /// </summary>
601 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>
602 public event LandBuy OnValidateLandBuy; 1087 public event LandBuy OnValidateLandBuy;
603 1088
604 public void TriggerOnAttach(uint localID, UUID itemID, UUID avatarID) 1089 public void TriggerOnAttach(uint localID, UUID itemID, UUID avatarID)
@@ -2035,7 +2520,11 @@ namespace OpenSim.Region.Framework.Scenes
2035 } 2520 }
2036 } 2521 }
2037 2522
2038 // 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>
2039 public void TriggerTimerEvent(uint objLocalID, double Interval) 2528 public void TriggerTimerEvent(uint objLocalID, double Interval)
2040 { 2529 {
2041 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");
@@ -2097,7 +2586,7 @@ namespace OpenSim.Region.Framework.Scenes
2097 return 6; 2586 return 6;
2098 } 2587 }
2099 2588
2100 public void TriggerOarFileLoaded(Guid requestId, string message) 2589 public void TriggerOarFileLoaded(Guid requestId, List<UUID> loadedScenes, string message)
2101 { 2590 {
2102 OarFileLoaded handlerOarFileLoaded = OnOarFileLoaded; 2591 OarFileLoaded handlerOarFileLoaded = OnOarFileLoaded;
2103 if (handlerOarFileLoaded != null) 2592 if (handlerOarFileLoaded != null)
@@ -2106,7 +2595,7 @@ namespace OpenSim.Region.Framework.Scenes
2106 { 2595 {
2107 try 2596 try
2108 { 2597 {
2109 d(requestId, message); 2598 d(requestId, loadedScenes, message);
2110 } 2599 }
2111 catch (Exception e) 2600 catch (Exception e)
2112 { 2601 {
@@ -2391,7 +2880,7 @@ namespace OpenSim.Region.Framework.Scenes
2391 } 2880 }
2392 } 2881 }
2393 2882
2394 public void TriggerSceneObjectPartUpdated(SceneObjectPart sop) 2883 public void TriggerSceneObjectPartUpdated(SceneObjectPart sop, bool full)
2395 { 2884 {
2396 SceneObjectPartUpdated handler = OnSceneObjectPartUpdated; 2885 SceneObjectPartUpdated handler = OnSceneObjectPartUpdated;
2397 if (handler != null) 2886 if (handler != null)
@@ -2400,7 +2889,7 @@ namespace OpenSim.Region.Framework.Scenes
2400 { 2889 {
2401 try 2890 try
2402 { 2891 {
2403 d(sop); 2892 d(sop, full);
2404 } 2893 }
2405 catch (Exception e) 2894 catch (Exception e)
2406 { 2895 {
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..80d9f6e 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 {
@@ -1151,6 +1215,14 @@ namespace OpenSim.Region.Framework.Scenes
1151 1215
1152 public void SetSceneCoreDebug(Dictionary<string, string> options) 1216 public void SetSceneCoreDebug(Dictionary<string, string> options)
1153 { 1217 {
1218 if (options.ContainsKey("active"))
1219 {
1220 bool active;
1221
1222 if (bool.TryParse(options["active"], out active))
1223 Active = active;
1224 }
1225
1154 if (options.ContainsKey("scripting")) 1226 if (options.ContainsKey("scripting"))
1155 { 1227 {
1156 bool enableScripts = true; 1228 bool enableScripts = true;
@@ -1226,6 +1298,12 @@ namespace OpenSim.Region.Framework.Scenes
1226 // This is the method that shuts down the scene. 1298 // This is the method that shuts down the scene.
1227 public override void Close() 1299 public override void Close()
1228 { 1300 {
1301 if (m_shuttingDown)
1302 {
1303 m_log.WarnFormat("[SCENE]: Ignoring close request because already closing {0}", Name);
1304 return;
1305 }
1306
1229 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); 1307 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
1230 1308
1231 StatsReporter.Close(); 1309 StatsReporter.Close();
@@ -1272,6 +1350,14 @@ namespace OpenSim.Region.Framework.Scenes
1272 m_log.Debug("[SCENE]: Graph close"); 1350 m_log.Debug("[SCENE]: Graph close");
1273 m_sceneGraph.Close(); 1351 m_sceneGraph.Close();
1274 1352
1353 if (!GridService.DeregisterRegion(RegionInfo.RegionID))
1354 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
1355
1356 base.Close();
1357
1358 // XEngine currently listens to the EventManager.OnShutdown event to trigger script stop and persistence.
1359 // Therefore. we must dispose of the PhysicsScene after this to prevent a window where script code can
1360 // attempt to reference a null or disposed physics scene.
1275 if (PhysicsScene != null) 1361 if (PhysicsScene != null)
1276 { 1362 {
1277 m_log.Debug("[SCENE]: Dispose Physics"); 1363 m_log.Debug("[SCENE]: Dispose Physics");
@@ -1281,13 +1367,6 @@ namespace OpenSim.Region.Framework.Scenes
1281 phys.Dispose(); 1367 phys.Dispose();
1282 phys = null; 1368 phys = null;
1283 } 1369 }
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 } 1370 }
1292 1371
1293 /// <summary> 1372 /// <summary>
@@ -1295,6 +1374,8 @@ namespace OpenSim.Region.Framework.Scenes
1295 /// </summary> 1374 /// </summary>
1296 public void Start() 1375 public void Start()
1297 { 1376 {
1377 m_active = true;
1378
1298// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1379// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1299 1380
1300 //m_heartbeatTimer.Enabled = true; 1381 //m_heartbeatTimer.Enabled = true;
@@ -1354,7 +1435,7 @@ namespace OpenSim.Region.Framework.Scenes
1354 #region Update Methods 1435 #region Update Methods
1355 1436
1356 /// <summary> 1437 /// <summary>
1357 /// Performs per-frame updates regularly 1438 /// Activate the various loops necessary to continually update the scene.
1358 /// </summary> 1439 /// </summary>
1359 private void Heartbeat() 1440 private void Heartbeat()
1360 { 1441 {
@@ -1411,7 +1492,7 @@ namespace OpenSim.Region.Framework.Scenes
1411 List<Vector3> coarseLocations; 1492 List<Vector3> coarseLocations;
1412 List<UUID> avatarUUIDs; 1493 List<UUID> avatarUUIDs;
1413 1494
1414 while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) 1495 while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun))
1415 { 1496 {
1416 runtc = Util.EnvironmentTickCount(); 1497 runtc = Util.EnvironmentTickCount();
1417 ++MaintenanceRun; 1498 ++MaintenanceRun;
@@ -1473,7 +1554,7 @@ namespace OpenSim.Region.Framework.Scenes
1473 int sleepMS; 1554 int sleepMS;
1474 int framestart; 1555 int framestart;
1475 1556
1476 while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) 1557 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1477 { 1558 {
1478 framestart = Util.EnvironmentTickCount(); 1559 framestart = Util.EnvironmentTickCount();
1479 ++Frame; 1560 ++Frame;
@@ -1672,15 +1753,19 @@ namespace OpenSim.Region.Framework.Scenes
1672 1753
1673 private void CheckAtTargets() 1754 private void CheckAtTargets()
1674 { 1755 {
1675 List<SceneObjectGroup> objs = new List<SceneObjectGroup>(); 1756 List<SceneObjectGroup> objs = null;
1757
1676 lock (m_groupsWithTargets) 1758 lock (m_groupsWithTargets)
1677 { 1759 {
1678 foreach (SceneObjectGroup grp in m_groupsWithTargets.Values) 1760 if (m_groupsWithTargets.Count != 0)
1679 objs.Add(grp); 1761 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1680 } 1762 }
1681 1763
1682 foreach (SceneObjectGroup entry in objs) 1764 if (objs != null)
1683 entry.checkAtTargets(); 1765 {
1766 foreach (SceneObjectGroup entry in objs)
1767 entry.checkAtTargets();
1768 }
1684 } 1769 }
1685 1770
1686 /// <summary> 1771 /// <summary>
@@ -2193,10 +2278,14 @@ namespace OpenSim.Region.Framework.Scenes
2193 public bool AddRestoredSceneObject( 2278 public bool AddRestoredSceneObject(
2194 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 2279 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
2195 { 2280 {
2196 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 2281 if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates))
2197 if (result) 2282 {
2198 sceneObject.IsDeleted = false; 2283 sceneObject.IsDeleted = false;
2199 return result; 2284 EventManager.TriggerObjectAddedToScene(sceneObject);
2285 return true;
2286 }
2287
2288 return false;
2200 } 2289 }
2201 2290
2202 /// <summary> 2291 /// <summary>
@@ -2837,77 +2926,89 @@ namespace OpenSim.Region.Framework.Scenes
2837 2926
2838 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2927 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
2839 { 2928 {
2929 ScenePresence sp;
2930 bool vialogin;
2931
2840 // Validation occurs in LLUDPServer 2932 // Validation occurs in LLUDPServer
2933 //
2934 // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with
2935 // each other. In practice, this does not currently occur in the code.
2841 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2936 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2842 2937
2843 bool vialogin 2938 // 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 2939 // 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; 2940 // whilst connecting).
2846 2941 //
2847 CheckHeartbeat(); 2942 // It would be easier to lock across all NewUserConnection(), AddNewClient() and
2848 2943 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
2849 ScenePresence sp = GetScenePresence(client.AgentId); 2944 // response in some module listening to AddNewClient()) from holding up unrelated agent calls.
2850 2945 //
2851 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2946 // 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 2947 // AddNewClient() operations (though not other ops).
2853 // other problems, and possible the code calling AddNewClient() should ensure that no client is already 2948 // In the future this can be relieved once locking per agent (not necessarily on AgentCircuitData) is improved.
2854 // connected. 2949 lock (aCircuit)
2855 if (sp == null) 2950 {
2856 { 2951 vialogin
2857 m_log.DebugFormat( 2952 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2858 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 2953 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2859 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); 2954
2860 2955 CheckHeartbeat();
2861 m_clientManager.Add(client); 2956
2862 SubscribeToClientEvents(client); 2957 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 2958
2869 // The first agent upon login is a root agent by design. 2959 // 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. 2960 // 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. 2961 // other problems, and possible the code calling AddNewClient() should ensure that no client is already
2872 if (aCircuit.child == false) 2962 // connected.
2963 if (sp == null)
2873 { 2964 {
2874 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to 2965 m_log.DebugFormat(
2875 // start the scripts again (since this is done in RezAttachments()). 2966 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2876 // XXX: This is convoluted. 2967 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2877 sp.IsChildAgent = false; 2968
2878 2969 m_clientManager.Add(client);
2879 if (AttachmentsModule != null) 2970 SubscribeToClientEvents(client);
2880 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); 2971
2972 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2973 m_eventManager.TriggerOnNewPresence(sp);
2974
2975 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2976
2977 // The first agent upon login is a root agent by design.
2978 // For this agent we will have to rez the attachments.
2979 // All other AddNewClient calls find aCircuit.child to be true.
2980 if (aCircuit.child == false)
2981 {
2982 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to
2983 // start the scripts again (since this is done in RezAttachments()).
2984 // XXX: This is convoluted.
2985 sp.IsChildAgent = false;
2986
2987 if (AttachmentsModule != null)
2988 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
2989 }
2881 } 2990 }
2882 } 2991 else
2883 else 2992 {
2884 { 2993 m_log.WarnFormat(
2885 m_log.WarnFormat( 2994 "[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", 2995 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2887 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2996 }
2888 } 2997
2998 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2999 // client is for a root or child agent.
3000 client.SceneAgent = sp;
2889 3001
2890 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 3002 // Cache the user's name
2891 // client is for a root or child agent. 3003 CacheUserName(sp, aCircuit);
2892 client.SceneAgent = sp; 3004
3005 EventManager.TriggerOnNewClient(client);
3006 if (vialogin)
3007 EventManager.TriggerOnClientLogin(client);
3008 }
2893 3009
2894 m_LastLogin = Util.EnvironmentTickCount(); 3010 m_LastLogin = Util.EnvironmentTickCount();
2895 3011
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; 3012 return sp;
2912 } 3013 }
2913 3014
@@ -3447,110 +3548,132 @@ namespace OpenSim.Region.Framework.Scenes
3447 { 3548 {
3448// CheckHeartbeat(); 3549// CheckHeartbeat();
3449 bool isChildAgent = false; 3550 bool isChildAgent = false;
3450 ScenePresence avatar = GetScenePresence(agentID); 3551 AgentCircuitData acd;
3451 3552
3452 if (avatar == null) 3553 lock (m_removeClientLock)
3453 { 3554 {
3454 m_log.WarnFormat( 3555 acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3455 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3456
3457 return;
3458 }
3459
3460 try
3461 {
3462 isChildAgent = avatar.IsChildAgent;
3463
3464 m_log.DebugFormat(
3465 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3466 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3467 3556
3468 // Don't do this to root agents, it's not nice for the viewer 3557 if (acd == null)
3469 if (closeChildAgents && isChildAgent)
3470 { 3558 {
3471 // Tell a single agent to disconnect from the region. 3559 m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID);
3472 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3560 return;
3473 if (eq != null)
3474 {
3475 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3476 }
3477 else
3478 {
3479 avatar.ControllingClient.SendShutdownConnectionNotice();
3480 }
3481 } 3561 }
3482 3562 else
3483 // Only applies to root agents.
3484 if (avatar.ParentID != 0)
3485 { 3563 {
3486 avatar.StandUp(); 3564 // We remove the acd up here to avoid later race conditions if two RemoveClient() calls occurred
3565 // simultaneously.
3566 // We also need to remove by agent ID since NPCs will have no circuit code.
3567 m_authenticateHandler.RemoveCircuit(agentID);
3487 } 3568 }
3569 }
3488 3570
3489 m_sceneGraph.removeUserCount(!isChildAgent); 3571 lock (acd)
3490 3572 {
3491 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3573 ScenePresence avatar = GetScenePresence(agentID);
3492 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3574
3493 if (closeChildAgents && CapsModule != null) 3575 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 { 3576 {
3502 List<ulong> regions = avatar.KnownRegionHandles; 3577 m_log.WarnFormat(
3503 regions.Remove(RegionInfo.RegionHandle); 3578 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3504 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3579
3580 return;
3505 } 3581 }
3506 3582
3507 m_eventManager.TriggerClientClosed(agentID, this); 3583 try
3508 m_eventManager.TriggerOnRemovePresence(agentID);
3509
3510 if (!isChildAgent)
3511 { 3584 {
3512 if (AttachmentsModule != null) 3585 isChildAgent = avatar.IsChildAgent;
3586
3587 m_log.DebugFormat(
3588 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3589 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3590
3591 // Don't do this to root agents, it's not nice for the viewer
3592 if (closeChildAgents && isChildAgent)
3513 { 3593 {
3514 AttachmentsModule.DeRezAttachments(avatar); 3594 // Tell a single agent to disconnect from the region.
3595 IEventQueue eq = RequestModuleInterface<IEventQueue>();
3596 if (eq != null)
3597 {
3598 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3599 }
3600 else
3601 {
3602 avatar.ControllingClient.SendShutdownConnectionNotice();
3603 }
3515 } 3604 }
3516 3605
3517 ForEachClient( 3606 // Only applies to root agents.
3518 delegate(IClientAPI client) 3607 if (avatar.ParentID != 0)
3608 {
3609 avatar.StandUp();
3610 }
3611
3612 m_sceneGraph.removeUserCount(!isChildAgent);
3613
3614 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3615 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3616 if (closeChildAgents && CapsModule != null)
3617 CapsModule.RemoveCaps(agentID);
3618
3619// // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3620// // this method is doing is HORRIBLE!!!
3621 // Commented pending deletion since this method no longer appears to do anything at all
3622// avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3623
3624 if (closeChildAgents && !isChildAgent)
3625 {
3626 List<ulong> regions = avatar.KnownRegionHandles;
3627 regions.Remove(RegionInfo.RegionHandle);
3628 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3629 }
3630
3631 m_eventManager.TriggerClientClosed(agentID, this);
3632 m_eventManager.TriggerOnRemovePresence(agentID);
3633
3634 if (!isChildAgent)
3635 {
3636 if (AttachmentsModule != null)
3519 { 3637 {
3520 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3638 AttachmentsModule.DeRezAttachments(avatar);
3521 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3639 }
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 3640
3530 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3641 ForEachClient(
3531 m_log.Debug("[Scene] The avatar has left the building"); 3642 delegate(IClientAPI client)
3532 } 3643 {
3533 catch (Exception e) 3644 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3534 { 3645 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3535 m_log.Error( 3646 catch (NullReferenceException) { }
3536 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); 3647 });
3537 } 3648 }
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 3649
3548 avatar.Close(); 3650 // It's possible for child agents to have transactions if changes are being made cross-border.
3651 if (AgentTransactionsModule != null)
3652 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3653 m_log.Debug("[Scene] The avatar has left the building");
3549 } 3654 }
3550 catch (Exception e) 3655 catch (Exception e)
3551 { 3656 {
3552 m_log.Error( 3657 m_log.Error(
3553 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); 3658 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e);
3659 }
3660 finally
3661 {
3662 try
3663 {
3664 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3665 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3666 // the same cleanup exception continually.
3667 m_sceneGraph.RemoveScenePresence(agentID);
3668 m_clientManager.Remove(agentID);
3669
3670 avatar.Close();
3671 }
3672 catch (Exception e)
3673 {
3674 m_log.Error(
3675 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e);
3676 }
3554 } 3677 }
3555 } 3678 }
3556 3679
@@ -3609,11 +3732,9 @@ namespace OpenSim.Region.Framework.Scenes
3609 3732
3610 /// <summary> 3733 /// <summary>
3611 /// Do the work necessary to initiate a new user connection for a particular scene. 3734 /// 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> 3735 /// </summary>
3616 /// <param name="agent">CircuitData of the agent who is connecting</param> 3736 /// <param name="agent">CircuitData of the agent who is connecting</param>
3737 /// <param name="teleportFlags"></param>
3617 /// <param name="reason">Outputs the reason for the false response on this string</param> 3738 /// <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 3739 /// <returns>True if the region accepts this agent. False if it does not. False will
3619 /// also return a reason.</returns> 3740 /// also return a reason.</returns>
@@ -3624,10 +3745,20 @@ namespace OpenSim.Region.Framework.Scenes
3624 3745
3625 /// <summary> 3746 /// <summary>
3626 /// Do the work necessary to initiate a new user connection for a particular scene. 3747 /// 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 3748 /// </summary>
3749 /// <remarks>
3750 /// The return bool should allow for connections to be refused, but as not all calling paths
3751 /// take proper notice of it yet, we still allowed banned users in.
3752 ///
3753 /// 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 3754 /// 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. 3755 /// take proper notice of it let, we allowed banned users in still.
3630 /// </summary> 3756 ///
3757 /// This method is called by the login service (in the case of login) or another simulator (in the case of region
3758 /// cross or teleport) to initiate the connection. It is not triggered by the viewer itself - the connection
3759 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
3760 /// the LLUDP stack).
3761 /// </remarks>
3631 /// <param name="agent">CircuitData of the agent who is connecting</param> 3762 /// <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> 3763 /// <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 3764 /// <param name="requirePresenceLookup">True for normal presence. False for NPC
@@ -3726,83 +3857,86 @@ namespace OpenSim.Region.Framework.Scenes
3726 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3857 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3727 sp.Name, sp.UUID, RegionInfo.RegionName); 3858 sp.Name, sp.UUID, RegionInfo.RegionName);
3728 3859
3729 sp.ControllingClient.Close(); 3860 sp.ControllingClient.Close(true, true);
3730 sp = null; 3861 sp = null;
3731 } 3862 }
3732 3863
3733 3864 lock (agent)
3734 //On login test land permisions
3735 if (vialogin)
3736 { 3865 {
3737 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); 3866 //On login test land permisions
3738 if (cache != null) 3867 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 { 3868 {
3742 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); 3869 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3743 return false; 3870 if (cache != null)
3871 cache.Remove(agent.firstname + " " + agent.lastname);
3872 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3873 {
3874 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3875 return false;
3876 }
3744 } 3877 }
3745 }
3746 3878
3747 if (sp == null) // We don't have an [child] agent here already 3879 if (sp == null) // We don't have an [child] agent here already
3748 {
3749 if (requirePresenceLookup)
3750 { 3880 {
3751 try 3881 if (requirePresenceLookup)
3752 { 3882 {
3753 if (!VerifyUserPresence(agent, out reason)) 3883 try
3884 {
3885 if (!VerifyUserPresence(agent, out reason))
3886 return false;
3887 } catch (Exception e)
3888 {
3889 m_log.ErrorFormat(
3890 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3754 return false; 3891 return false;
3755 } catch (Exception e) 3892 }
3893 }
3894
3895 try
3896 {
3897 // Always check estate if this is a login. Always
3898 // check if banned regions are to be blacked out.
3899 if (vialogin || (!m_seeIntoBannedRegion))
3900 {
3901 if (!AuthorizeUser(agent, out reason))
3902 return false;
3903 }
3904 }
3905 catch (Exception e)
3756 { 3906 {
3757 m_log.ErrorFormat( 3907 m_log.ErrorFormat(
3758 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3908 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
3759 return false; 3909 return false;
3760 } 3910 }
3761 }
3762 3911
3763 try 3912 m_log.InfoFormat(
3764 { 3913 "[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 3914 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3766 // check if banned regions are to be blacked out. 3915 agent.AgentID, agent.circuitcode);
3767 if (vialogin || (!m_seeIntoBannedRegion)) 3916
3917 if (CapsModule != null)
3768 { 3918 {
3769 if (!AuthorizeUser(agent, out reason)) 3919 CapsModule.SetAgentCapsSeeds(agent);
3770 return false; 3920 CapsModule.CreateCaps(agent.AgentID);
3771 } 3921 }
3772 } 3922 }
3773 catch (Exception e) 3923 else
3774 { 3924 {
3775 m_log.ErrorFormat( 3925 // 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); 3926 // uses down the line.
3777 return false; 3927 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 3928
3785 if (CapsModule != null) 3929 if (sp.IsChildAgent)
3786 { 3930 {
3787 CapsModule.SetAgentCapsSeeds(agent); 3931 m_log.DebugFormat(
3788 CapsModule.CreateCaps(agent.AgentID); 3932 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3789 } 3933 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 3934
3796 if (sp.IsChildAgent) 3935 sp.AdjustKnownSeeds();
3797 {
3798 m_log.DebugFormat(
3799 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3800 agent.AgentID, RegionInfo.RegionName);
3801 3936
3802 sp.AdjustKnownSeeds(); 3937 if (CapsModule != null)
3803 3938 CapsModule.SetAgentCapsSeeds(agent);
3804 if (CapsModule != null) 3939 }
3805 CapsModule.SetAgentCapsSeeds(agent);
3806 } 3940 }
3807 } 3941 }
3808 3942
@@ -4233,8 +4367,9 @@ namespace OpenSim.Region.Framework.Scenes
4233 return false; 4367 return false;
4234 } 4368 }
4235 4369
4236 // We have to wait until the viewer contacts this region after receiving EAC. 4370 // We have to wait until the viewer contacts this region
4237 // That calls AddNewClient, which finally creates the ScenePresence 4371 // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send
4372 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence.
4238 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4373 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
4239 4374
4240 if (childAgentUpdate != null) 4375 if (childAgentUpdate != null)
@@ -4329,15 +4464,18 @@ namespace OpenSim.Region.Framework.Scenes
4329 /// Tell a single agent to disconnect from the region. 4464 /// Tell a single agent to disconnect from the region.
4330 /// </summary> 4465 /// </summary>
4331 /// <param name="agentID"></param> 4466 /// <param name="agentID"></param>
4332 /// <param name="childOnly"></param> 4467 /// <param name="force">
4333 public bool IncomingCloseAgent(UUID agentID, bool childOnly) 4468 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4469 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4470 /// </param>
4471 public bool IncomingCloseAgent(UUID agentID, bool force)
4334 { 4472 {
4335 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4473 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
4336 4474
4337 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4475 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4338 if (presence != null) 4476 if (presence != null)
4339 { 4477 {
4340 presence.ControllingClient.Close(false); 4478 presence.ControllingClient.Close(force, force);
4341 return true; 4479 return true;
4342 } 4480 }
4343 4481
@@ -4543,6 +4681,16 @@ namespace OpenSim.Region.Framework.Scenes
4543 return LandChannel.GetLandObject(x, y).LandData; 4681 return LandChannel.GetLandObject(x, y).LandData;
4544 } 4682 }
4545 4683
4684 /// <summary>
4685 /// Get LandData by position.
4686 /// </summary>
4687 /// <param name="pos"></param>
4688 /// <returns></returns>
4689 public LandData GetLandData(Vector3 pos)
4690 {
4691 return GetLandData(pos.X, pos.Y);
4692 }
4693
4546 public LandData GetLandData(uint x, uint y) 4694 public LandData GetLandData(uint x, uint y)
4547 { 4695 {
4548 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); 4696 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
@@ -4773,13 +4921,24 @@ namespace OpenSim.Region.Framework.Scenes
4773 /// Get a group via its UUID 4921 /// Get a group via its UUID
4774 /// </summary> 4922 /// </summary>
4775 /// <param name="fullID"></param> 4923 /// <param name="fullID"></param>
4776 /// <returns>null if no group with that name exists</returns> 4924 /// <returns>null if no group with that id exists</returns>
4777 public SceneObjectGroup GetSceneObjectGroup(UUID fullID) 4925 public SceneObjectGroup GetSceneObjectGroup(UUID fullID)
4778 { 4926 {
4779 return m_sceneGraph.GetSceneObjectGroup(fullID); 4927 return m_sceneGraph.GetSceneObjectGroup(fullID);
4780 } 4928 }
4781 4929
4782 /// <summary> 4930 /// <summary>
4931 /// Get a group via its local ID
4932 /// </summary>
4933 /// <remarks>This will only return a group if the local ID matches a root part</remarks>
4934 /// <param name="localID"></param>
4935 /// <returns>null if no group with that id exists</returns>
4936 public SceneObjectGroup GetSceneObjectGroup(uint localID)
4937 {
4938 return m_sceneGraph.GetSceneObjectGroup(localID);
4939 }
4940
4941 /// <summary>
4783 /// Get a group by name from the scene (will return the first 4942 /// 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) 4943 /// found, if there are more than one prim with the same name)
4785 /// </summary> 4944 /// </summary>
@@ -4791,6 +4950,18 @@ namespace OpenSim.Region.Framework.Scenes
4791 } 4950 }
4792 4951
4793 /// <summary> 4952 /// <summary>
4953 /// Attempt to get the SOG via its UUID
4954 /// </summary>
4955 /// <param name="fullID"></param>
4956 /// <param name="sog"></param>
4957 /// <returns></returns>
4958 public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog)
4959 {
4960 sog = GetSceneObjectGroup(fullID);
4961 return sog != null;
4962 }
4963
4964 /// <summary>
4794 /// Get a prim by name from the scene (will return the first 4965 /// 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) 4966 /// found, if there are more than one prim with the same name)
4796 /// </summary> 4967 /// </summary>
@@ -4822,6 +4993,18 @@ namespace OpenSim.Region.Framework.Scenes
4822 } 4993 }
4823 4994
4824 /// <summary> 4995 /// <summary>
4996 /// Attempt to get a prim via its UUID
4997 /// </summary>
4998 /// <param name="fullID"></param>
4999 /// <param name="sop"></param>
5000 /// <returns></returns>
5001 public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop)
5002 {
5003 sop = GetSceneObjectPart(fullID);
5004 return sop != null;
5005 }
5006
5007 /// <summary>
4825 /// Get a scene object group that contains the prim with the given local id 5008 /// Get a scene object group that contains the prim with the given local id
4826 /// </summary> 5009 /// </summary>
4827 /// <param name="localID"></param> 5010 /// <param name="localID"></param>
@@ -4915,14 +5098,15 @@ namespace OpenSim.Region.Framework.Scenes
4915 client.SendRegionHandle(regionID, handle); 5098 client.SendRegionHandle(regionID, handle);
4916 } 5099 }
4917 5100
4918 public bool NeedSceneCacheClear(UUID agentID) 5101// Commented pending deletion since this method no longer appears to do anything at all
4919 { 5102// public bool NeedSceneCacheClear(UUID agentID)
4920 IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>(); 5103// {
4921 if (inv == null) 5104// IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
4922 return true; 5105// if (inv == null)
4923 5106// return true;
4924 return inv.NeedSceneCacheClear(agentID, this); 5107//
4925 } 5108// return inv.NeedSceneCacheClear(agentID, this);
5109// }
4926 5110
4927 public void CleanTempObjects() 5111 public void CleanTempObjects()
4928 { 5112 {
@@ -5876,6 +6060,9 @@ Environment.Exit(1);
5876 6060
5877 public string GetExtraSetting(string name) 6061 public string GetExtraSetting(string name)
5878 { 6062 {
6063 if (m_extraSettings == null)
6064 return String.Empty;
6065
5879 string val; 6066 string val;
5880 6067
5881 if (!m_extraSettings.TryGetValue(name, out val)) 6068 if (!m_extraSettings.TryGetValue(name, out val))
@@ -5886,6 +6073,9 @@ Environment.Exit(1);
5886 6073
5887 public void StoreExtraSetting(string name, string val) 6074 public void StoreExtraSetting(string name, string val)
5888 { 6075 {
6076 if (m_extraSettings == null)
6077 return;
6078
5889 string oldVal; 6079 string oldVal;
5890 6080
5891 if (m_extraSettings.TryGetValue(name, out oldVal)) 6081 if (m_extraSettings.TryGetValue(name, out oldVal))
@@ -5903,6 +6093,9 @@ Environment.Exit(1);
5903 6093
5904 public void RemoveExtraSetting(string name) 6094 public void RemoveExtraSetting(string name)
5905 { 6095 {
6096 if (m_extraSettings == null)
6097 return;
6098
5906 if (!m_extraSettings.ContainsKey(name)) 6099 if (!m_extraSettings.ContainsKey(name))
5907 return; 6100 return;
5908 6101
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..89e3ac5 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>();
@@ -134,31 +138,6 @@ namespace OpenSim.Region.Framework.Scenes
134 138
135 public void Close() 139 public void Close()
136 { 140 {
137 // collect known shared modules in sharedModules
138 Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>();
139
140 List<Scene> sceneList = Scenes;
141 for (int i = 0; i < sceneList.Count; i++)
142 {
143 // extract known shared modules from scene
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 }
153
154 // all regions/scenes are now closed, we can now safely
155 // close all shared modules
156 foreach (IRegionModule mod in sharedModules.Values)
157 {
158 mod.Close();
159 }
160
161 m_localScenes.Clear();
162 } 141 }
163 142
164 public void Close(Scene cscene) 143 public void Close(Scene cscene)
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 165dd85..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 }
@@ -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 2b9665c..25a53b4 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 {
@@ -711,7 +712,7 @@ namespace OpenSim.Region.Framework.Scenes
711 AttachmentsSyncLock = new Object(); 712 AttachmentsSyncLock = new Object();
712 AllowMovement = true; 713 AllowMovement = true;
713 IsChildAgent = true; 714 IsChildAgent = true;
714 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 715 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
715 Animator = new ScenePresenceAnimator(this); 716 Animator = new ScenePresenceAnimator(this);
716 PresenceType = type; 717 PresenceType = type;
717 DrawDistance = world.DefaultDrawDistance; 718 DrawDistance = world.DefaultDrawDistance;
@@ -975,7 +976,9 @@ namespace OpenSim.Region.Framework.Scenes
975 { 976 {
976 if (wasChild && HasAttachments()) 977 if (wasChild && HasAttachments())
977 { 978 {
978 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); 979 m_log.DebugFormat(
980 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
981
979 // Resume scripts 982 // Resume scripts
980 Util.FireAndForget(delegate(object x) { 983 Util.FireAndForget(delegate(object x) {
981 foreach (SceneObjectGroup sog in m_attachments) 984 foreach (SceneObjectGroup sog in m_attachments)
@@ -1531,17 +1534,22 @@ namespace OpenSim.Region.Framework.Scenes
1531 bool DCFlagKeyPressed = false; 1534 bool DCFlagKeyPressed = false;
1532 Vector3 agent_control_v3 = Vector3.Zero; 1535 Vector3 agent_control_v3 = Vector3.Zero;
1533 1536
1534 bool oldflying = Flying; 1537 bool newFlying = actor.Flying;
1535 1538
1536 if (ForceFly) 1539 if (ForceFly)
1537 actor.Flying = true; 1540 newFlying = true;
1538 else if (FlyDisabled) 1541 else if (FlyDisabled)
1539 actor.Flying = false; 1542 newFlying = false;
1540 else 1543 else
1541 actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1544 newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1542 1545
1543 if (actor.Flying != oldflying) 1546 if (actor.Flying != newFlying)
1547 {
1548 // Note: ScenePresence.Flying is actually fetched from the physical actor
1549 // so setting PhysActor.Flying here also sets the ScenePresence's value.
1550 actor.Flying = newFlying;
1544 update_movementflag = true; 1551 update_movementflag = true;
1552 }
1545 1553
1546 if (ParentID == 0) 1554 if (ParentID == 0)
1547 { 1555 {
@@ -2623,17 +2631,17 @@ namespace OpenSim.Region.Framework.Scenes
2623 2631
2624 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2632 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
2625 { 2633 {
2626 SendCourseLocationsMethod d = m_sendCourseLocationsMethod; 2634 SendCoarseLocationsMethod d = m_sendCoarseLocationsMethod;
2627 if (d != null) 2635 if (d != null)
2628 { 2636 {
2629 d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs); 2637 d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs);
2630 } 2638 }
2631 } 2639 }
2632 2640
2633 public void SetSendCourseLocationMethod(SendCourseLocationsMethod d) 2641 public void SetSendCoarseLocationMethod(SendCoarseLocationsMethod d)
2634 { 2642 {
2635 if (d != null) 2643 if (d != null)
2636 m_sendCourseLocationsMethod = d; 2644 m_sendCoarseLocationsMethod = d;
2637 } 2645 }
2638 2646
2639 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2647 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
@@ -2837,7 +2845,7 @@ namespace OpenSim.Region.Framework.Scenes
2837 #region Significant Movement Method 2845 #region Significant Movement Method
2838 2846
2839 /// <summary> 2847 /// <summary>
2840 /// This checks for a significant movement and sends a courselocationchange update 2848 /// This checks for a significant movement and sends a coarselocationchange update
2841 /// </summary> 2849 /// </summary>
2842 protected void CheckForSignificantMovement() 2850 protected void CheckForSignificantMovement()
2843 { 2851 {
@@ -3274,6 +3282,7 @@ namespace OpenSim.Region.Framework.Scenes
3274 } 3282 }
3275 catch { } 3283 catch { }
3276 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; 3284 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation;
3285 cAgent.AnimState = Animator.Animations.ImplicitDefaultAnimation;
3277 3286
3278 if (Scene.AttachmentsModule != null) 3287 if (Scene.AttachmentsModule != null)
3279 Scene.AttachmentsModule.CopyAttachments(this, cAgent); 3288 Scene.AttachmentsModule.CopyAttachments(this, cAgent);
@@ -3350,6 +3359,8 @@ namespace OpenSim.Region.Framework.Scenes
3350 Animator.Animations.FromArray(cAgent.Anims); 3359 Animator.Animations.FromArray(cAgent.Anims);
3351 if (cAgent.DefaultAnim != null) 3360 if (cAgent.DefaultAnim != null)
3352 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); 3361 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
3362 if (cAgent.AnimState != null)
3363 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
3353 3364
3354 if (Scene.AttachmentsModule != null) 3365 if (Scene.AttachmentsModule != null)
3355 Scene.AttachmentsModule.CopyAttachments(cAgent, this); 3366 Scene.AttachmentsModule.CopyAttachments(cAgent, this);
@@ -3632,13 +3643,16 @@ namespace OpenSim.Region.Framework.Scenes
3632 public List<SceneObjectGroup> GetAttachments(uint attachmentPoint) 3643 public List<SceneObjectGroup> GetAttachments(uint attachmentPoint)
3633 { 3644 {
3634 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(); 3645 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
3635 3646
3636 lock (m_attachments) 3647 if (attachmentPoint >= 0)
3637 { 3648 {
3638 foreach (SceneObjectGroup so in m_attachments) 3649 lock (m_attachments)
3639 { 3650 {
3640 if (attachmentPoint == so.AttachmentPoint) 3651 foreach (SceneObjectGroup so in m_attachments)
3641 attachments.Add(so); 3652 {
3653 if (attachmentPoint == so.AttachmentPoint)
3654 attachments.Add(so);
3655 }
3642 } 3656 }
3643 } 3657 }
3644 3658
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/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}