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.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs521
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs669
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs35
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs106
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs119
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs48
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs35
-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
16 files changed, 1397 insertions, 381 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
index ad421ee..3d8e8be 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
@@ -41,12 +41,13 @@ 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
47 public OpenSim.Framework.Animation DefaultAnimation 48 public OpenSim.Framework.Animation ImplicitDefaultAnimation
48 { 49 {
49 get { return m_defaultAnimation; } 50 get { return m_implicitDefaultAnimation; }
50 } 51 }
51 52
52 public AnimationSet() 53 public AnimationSet()
@@ -119,6 +120,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
119 if (m_defaultAnimation.AnimID != animID) 120 if (m_defaultAnimation.AnimID != animID)
120 { 121 {
121 m_defaultAnimation = new OpenSim.Framework.Animation(animID, sequenceNum, objectID); 122 m_defaultAnimation = new OpenSim.Framework.Animation(animID, sequenceNum, objectID);
123 m_implicitDefaultAnimation = m_defaultAnimation;
122 return true; 124 return true;
123 } 125 }
124 return false; 126 return false;
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index eee5960..e2414eb 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
@@ -432,7 +872,7 @@ namespace OpenSim.Region.Framework.Scenes
432 /// the scripts may not have started yet 872 /// the scripts may not have started yet
433 /// Message is non empty string if there were problems loading the oar file 873 /// Message is non empty string if there were problems loading the oar file
434 /// </summary> 874 /// </summary>
435 public delegate void OarFileLoaded(Guid guid, string message); 875 public delegate void OarFileLoaded(Guid guid, List<UUID> loadedScenes, string message);
436 public event OarFileLoaded OnOarFileLoaded; 876 public event OarFileLoaded OnOarFileLoaded;
437 877
438 /// <summary> 878 /// <summary>
@@ -485,10 +925,13 @@ namespace OpenSim.Region.Framework.Scenes
485 /// <param name="copy"></param> 925 /// <param name="copy"></param>
486 /// <param name="original"></param> 926 /// <param name="original"></param>
487 /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param> 927 /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
928 /// <remarks>
929 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.SceneObjectPart.Copy"/>
930 /// </remarks>
488 public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy; 931 public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy;
489 public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed); 932 public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed);
490 933
491 public delegate void SceneObjectPartUpdated(SceneObjectPart sop); 934 public delegate void SceneObjectPartUpdated(SceneObjectPart sop, bool full);
492 public event SceneObjectPartUpdated OnSceneObjectPartUpdated; 935 public event SceneObjectPartUpdated OnSceneObjectPartUpdated;
493 936
494 public delegate void ScenePresenceUpdated(ScenePresence sp); 937 public delegate void ScenePresenceUpdated(ScenePresence sp);
@@ -526,9 +969,28 @@ namespace OpenSim.Region.Framework.Scenes
526 public event PrimsLoaded OnPrimsLoaded; 969 public event PrimsLoaded OnPrimsLoaded;
527 970
528 public delegate void TeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout); 971 public delegate void TeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout);
972
973 /// <summary>
974 /// Triggered when a teleport starts
975 /// </summary>
976 /// <remarks>
977 /// Triggered by <see cref="TriggerTeleportStart"/>
978 /// in <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.CreateAgent"/>
979 /// and <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule.CreateAgent"/>
980 /// via <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.DoTeleport"/>
981 /// </remarks>
529 public event TeleportStart OnTeleportStart; 982 public event TeleportStart OnTeleportStart;
530 983
531 public delegate void TeleportFail(IClientAPI client, bool gridLogout); 984 public delegate void TeleportFail(IClientAPI client, bool gridLogout);
985
986 /// <summary>
987 /// Trigered when a teleport fails.
988 /// </summary>
989 /// <remarks>
990 /// Triggered by <see cref="TriggerTeleportFail"/>
991 /// in <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.Fail"/>
992 /// via <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.DoTeleport"/>
993 /// </remarks>
532 public event TeleportFail OnTeleportFail; 994 public event TeleportFail OnTeleportFail;
533 995
534 public class MoneyTransferArgs : EventArgs 996 public class MoneyTransferArgs : EventArgs
@@ -536,7 +998,9 @@ namespace OpenSim.Region.Framework.Scenes
536 public UUID sender; 998 public UUID sender;
537 public UUID receiver; 999 public UUID receiver;
538 1000
539 // Always false. The SL protocol sucks. 1001 /// <summary>
1002 /// Always false. The SL protocol sucks.
1003 /// </summary>
540 public bool authenticated = false; 1004 public bool authenticated = false;
541 1005
542 public int amount; 1006 public int amount;
@@ -593,8 +1057,29 @@ namespace OpenSim.Region.Framework.Scenes
593 1057
594 public delegate void LandBuy(Object sender, LandBuyArgs e); 1058 public delegate void LandBuy(Object sender, LandBuyArgs e);
595 1059
1060 /// <summary>
1061 /// Triggered when an attempt to transfer grid currency occurs
1062 /// </summary>
1063 /// <remarks>
1064 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.ProcessMoneyTransferRequest"/>
1065 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientGridEvents"/>
1066 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientEvents"/>
1067 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/>
1068 /// </remarks>
596 public event MoneyTransferEvent OnMoneyTransfer; 1069 public event MoneyTransferEvent OnMoneyTransfer;
1070
1071 /// <summary>
1072 /// Triggered after after <see cref="OnValidateLandBuy"/>
1073 /// </summary>
597 public event LandBuy OnLandBuy; 1074 public event LandBuy OnLandBuy;
1075
1076 /// <summary>
1077 /// Triggered to allow or prevent a real estate transaction
1078 /// </summary>
1079 /// <remarks>
1080 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.ProcessParcelBuy"/>
1081 /// <seealso cref="OpenSim.Region.OptionalModules.World.MoneyModule.SampleMoneyModule.ValidateLandBuy"/>
1082 /// </remarks>
598 public event LandBuy OnValidateLandBuy; 1083 public event LandBuy OnValidateLandBuy;
599 1084
600 public void TriggerOnAttach(uint localID, UUID itemID, UUID avatarID) 1085 public void TriggerOnAttach(uint localID, UUID itemID, UUID avatarID)
@@ -2031,7 +2516,11 @@ namespace OpenSim.Region.Framework.Scenes
2031 } 2516 }
2032 } 2517 }
2033 2518
2034 // this lets us keep track of nasty script events like timer, etc. 2519 /// <summary>
2520 /// this lets us keep track of nasty script events like timer, etc.
2521 /// </summary>
2522 /// <param name="objLocalID"></param>
2523 /// <param name="Interval"></param>
2035 public void TriggerTimerEvent(uint objLocalID, double Interval) 2524 public void TriggerTimerEvent(uint objLocalID, double Interval)
2036 { 2525 {
2037 throw new NotImplementedException("TriggerTimerEvent was thought to be not used anymore and the registration for the event from scene object part has been commented out due to a memory leak"); 2526 throw new NotImplementedException("TriggerTimerEvent was thought to be not used anymore and the registration for the event from scene object part has been commented out due to a memory leak");
@@ -2093,7 +2582,7 @@ namespace OpenSim.Region.Framework.Scenes
2093 return 6; 2582 return 6;
2094 } 2583 }
2095 2584
2096 public void TriggerOarFileLoaded(Guid requestId, string message) 2585 public void TriggerOarFileLoaded(Guid requestId, List<UUID> loadedScenes, string message)
2097 { 2586 {
2098 OarFileLoaded handlerOarFileLoaded = OnOarFileLoaded; 2587 OarFileLoaded handlerOarFileLoaded = OnOarFileLoaded;
2099 if (handlerOarFileLoaded != null) 2588 if (handlerOarFileLoaded != null)
@@ -2102,7 +2591,7 @@ namespace OpenSim.Region.Framework.Scenes
2102 { 2591 {
2103 try 2592 try
2104 { 2593 {
2105 d(requestId, message); 2594 d(requestId, loadedScenes, message);
2106 } 2595 }
2107 catch (Exception e) 2596 catch (Exception e)
2108 { 2597 {
@@ -2387,7 +2876,7 @@ namespace OpenSim.Region.Framework.Scenes
2387 } 2876 }
2388 } 2877 }
2389 2878
2390 public void TriggerSceneObjectPartUpdated(SceneObjectPart sop) 2879 public void TriggerSceneObjectPartUpdated(SceneObjectPart sop, bool full)
2391 { 2880 {
2392 SceneObjectPartUpdated handler = OnSceneObjectPartUpdated; 2881 SceneObjectPartUpdated handler = OnSceneObjectPartUpdated;
2393 if (handler != null) 2882 if (handler != null)
@@ -2396,7 +2885,7 @@ namespace OpenSim.Region.Framework.Scenes
2396 { 2885 {
2397 try 2886 try
2398 { 2887 {
2399 d(sop); 2888 d(sop, full);
2400 } 2889 }
2401 catch (Exception e) 2890 catch (Exception e)
2402 { 2891 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index ff8589a..deb57ce 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;
@@ -1997,6 +1997,9 @@ namespace OpenSim.Region.Framework.Scenes
1997 // If child prims have invalid perms, fix them 1997 // If child prims have invalid perms, fix them
1998 grp.AdjustChildPrimPermissions(); 1998 grp.AdjustChildPrimPermissions();
1999 1999
2000 // If child prims have invalid perms, fix them
2001 grp.AdjustChildPrimPermissions();
2002
2000 if (remoteClient == null) 2003 if (remoteClient == null)
2001 { 2004 {
2002 // Autoreturn has a null client. Nothing else does. So 2005 // 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 05ce00a..9f87e1e 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;
@@ -285,6 +313,31 @@ namespace OpenSim.Region.Framework.Scenes
285 } 313 }
286 private volatile bool m_shuttingDown; 314 private volatile bool m_shuttingDown;
287 315
316 /// <summary>
317 /// Is the scene active?
318 /// </summary>
319 /// <remarks>
320 /// If false, maintenance and update loops are not being run. Updates can still be triggered manually if
321 /// the scene is not active.
322 /// </remarks>
323 public bool Active
324 {
325 get { return m_active; }
326 set
327 {
328 if (value)
329 {
330 if (!m_active)
331 Start();
332 }
333 else
334 {
335 m_active = false;
336 }
337 }
338 }
339 private volatile bool m_active;
340
288// private int m_lastUpdate; 341// private int m_lastUpdate;
289 private bool m_firstHeartbeat = true; 342 private bool m_firstHeartbeat = true;
290 343
@@ -746,12 +799,24 @@ namespace OpenSim.Region.Framework.Scenes
746 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 799 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
747 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 800 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
748 801
749 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); 802 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
803 if (RegionInfo.NonphysPrimMin > 0)
804 {
805 m_minNonphys = RegionInfo.NonphysPrimMin;
806 }
807
808 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
750 if (RegionInfo.NonphysPrimMax > 0) 809 if (RegionInfo.NonphysPrimMax > 0)
751 { 810 {
752 m_maxNonphys = RegionInfo.NonphysPrimMax; 811 m_maxNonphys = RegionInfo.NonphysPrimMax;
753 } 812 }
754 813
814 m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
815 if (RegionInfo.PhysPrimMin > 0)
816 {
817 m_minPhys = RegionInfo.PhysPrimMin;
818 }
819
755 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); 820 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
756 821
757 if (RegionInfo.PhysPrimMax > 0) 822 if (RegionInfo.PhysPrimMax > 0)
@@ -759,6 +824,12 @@ namespace OpenSim.Region.Framework.Scenes
759 m_maxPhys = RegionInfo.PhysPrimMax; 824 m_maxPhys = RegionInfo.PhysPrimMax;
760 } 825 }
761 826
827 m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity);
828 if (RegionInfo.LinksetCapacity > 0)
829 {
830 m_linksetCapacity = RegionInfo.LinksetCapacity;
831 }
832
762 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); 833 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
763 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); 834 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
764 835
@@ -784,13 +855,6 @@ namespace OpenSim.Region.Framework.Scenes
784 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 855 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
785 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine); 856 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
786 857
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); 858 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
795 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion); 859 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
796 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false); 860 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
@@ -854,6 +918,8 @@ namespace OpenSim.Region.Framework.Scenes
854 } 918 }
855 919
856 // FIXME: Ultimately this should be in a module. 920 // FIXME: Ultimately this should be in a module.
921 SendPeriodicAppearanceUpdates = true;
922
857 IConfig appearanceConfig = m_config.Configs["Appearance"]; 923 IConfig appearanceConfig = m_config.Configs["Appearance"];
858 if (appearanceConfig != null) 924 if (appearanceConfig != null)
859 { 925 {
@@ -1151,6 +1217,14 @@ namespace OpenSim.Region.Framework.Scenes
1151 1217
1152 public void SetSceneCoreDebug(Dictionary<string, string> options) 1218 public void SetSceneCoreDebug(Dictionary<string, string> options)
1153 { 1219 {
1220 if (options.ContainsKey("active"))
1221 {
1222 bool active;
1223
1224 if (bool.TryParse(options["active"], out active))
1225 Active = active;
1226 }
1227
1154 if (options.ContainsKey("scripting")) 1228 if (options.ContainsKey("scripting"))
1155 { 1229 {
1156 bool enableScripts = true; 1230 bool enableScripts = true;
@@ -1226,6 +1300,12 @@ namespace OpenSim.Region.Framework.Scenes
1226 // This is the method that shuts down the scene. 1300 // This is the method that shuts down the scene.
1227 public override void Close() 1301 public override void Close()
1228 { 1302 {
1303 if (m_shuttingDown)
1304 {
1305 m_log.WarnFormat("[SCENE]: Ignoring close request because already closing {0}", Name);
1306 return;
1307 }
1308
1229 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); 1309 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
1230 1310
1231 StatsReporter.Close(); 1311 StatsReporter.Close();
@@ -1269,6 +1349,14 @@ namespace OpenSim.Region.Framework.Scenes
1269 1349
1270 m_sceneGraph.Close(); 1350 m_sceneGraph.Close();
1271 1351
1352 if (!GridService.DeregisterRegion(RegionInfo.RegionID))
1353 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
1354
1355 base.Close();
1356
1357 // XEngine currently listens to the EventManager.OnShutdown event to trigger script stop and persistence.
1358 // Therefore. we must dispose of the PhysicsScene after this to prevent a window where script code can
1359 // attempt to reference a null or disposed physics scene.
1272 if (PhysicsScene != null) 1360 if (PhysicsScene != null)
1273 { 1361 {
1274 PhysicsScene phys = PhysicsScene; 1362 PhysicsScene phys = PhysicsScene;
@@ -1277,12 +1365,6 @@ namespace OpenSim.Region.Framework.Scenes
1277 phys.Dispose(); 1365 phys.Dispose();
1278 phys = null; 1366 phys = null;
1279 } 1367 }
1280
1281 if (!GridService.DeregisterRegion(RegionInfo.RegionID))
1282 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
1283
1284 // call the base class Close method.
1285 base.Close();
1286 } 1368 }
1287 1369
1288 /// <summary> 1370 /// <summary>
@@ -1290,6 +1372,8 @@ namespace OpenSim.Region.Framework.Scenes
1290 /// </summary> 1372 /// </summary>
1291 public void Start() 1373 public void Start()
1292 { 1374 {
1375 m_active = true;
1376
1293// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1377// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1294 1378
1295 //m_heartbeatTimer.Enabled = true; 1379 //m_heartbeatTimer.Enabled = true;
@@ -1346,7 +1430,7 @@ namespace OpenSim.Region.Framework.Scenes
1346 #region Update Methods 1430 #region Update Methods
1347 1431
1348 /// <summary> 1432 /// <summary>
1349 /// Performs per-frame updates regularly 1433 /// Activate the various loops necessary to continually update the scene.
1350 /// </summary> 1434 /// </summary>
1351 private void Heartbeat() 1435 private void Heartbeat()
1352 { 1436 {
@@ -1403,7 +1487,7 @@ namespace OpenSim.Region.Framework.Scenes
1403 List<Vector3> coarseLocations; 1487 List<Vector3> coarseLocations;
1404 List<UUID> avatarUUIDs; 1488 List<UUID> avatarUUIDs;
1405 1489
1406 while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) 1490 while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun))
1407 { 1491 {
1408 runtc = Util.EnvironmentTickCount(); 1492 runtc = Util.EnvironmentTickCount();
1409 ++MaintenanceRun; 1493 ++MaintenanceRun;
@@ -1465,7 +1549,7 @@ namespace OpenSim.Region.Framework.Scenes
1465 int sleepMS; 1549 int sleepMS;
1466 int framestart; 1550 int framestart;
1467 1551
1468 while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) 1552 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1469 { 1553 {
1470 framestart = Util.EnvironmentTickCount(); 1554 framestart = Util.EnvironmentTickCount();
1471 ++Frame; 1555 ++Frame;
@@ -2185,10 +2269,14 @@ namespace OpenSim.Region.Framework.Scenes
2185 public bool AddRestoredSceneObject( 2269 public bool AddRestoredSceneObject(
2186 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 2270 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
2187 { 2271 {
2188 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 2272 if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates))
2189 if (result) 2273 {
2190 sceneObject.IsDeleted = false; 2274 sceneObject.IsDeleted = false;
2191 return result; 2275 EventManager.TriggerObjectAddedToScene(sceneObject);
2276 return true;
2277 }
2278
2279 return false;
2192 } 2280 }
2193 2281
2194 /// <summary> 2282 /// <summary>
@@ -2829,77 +2917,89 @@ namespace OpenSim.Region.Framework.Scenes
2829 2917
2830 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2918 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
2831 { 2919 {
2920 ScenePresence sp;
2921 bool vialogin;
2922
2832 // Validation occurs in LLUDPServer 2923 // Validation occurs in LLUDPServer
2924 //
2925 // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with
2926 // each other. In practice, this does not currently occur in the code.
2833 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2927 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2834 2928
2835 bool vialogin 2929 // We lock here on AgentCircuitData to prevent a race condition between the thread adding a new connection
2836 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 2930 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point
2837 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2931 // whilst connecting).
2838 2932 //
2839 CheckHeartbeat(); 2933 // It would be easier to lock across all NewUserConnection(), AddNewClient() and
2840 2934 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
2841 ScenePresence sp = GetScenePresence(client.AgentId); 2935 // response in some module listening to AddNewClient()) from holding up unrelated agent calls.
2842 2936 //
2843 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2937 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all
2844 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause 2938 // AddNewClient() operations (though not other ops).
2845 // other problems, and possible the code calling AddNewClient() should ensure that no client is already 2939 // In the future this can be relieved once locking per agent (not necessarily on AgentCircuitData) is improved.
2846 // connected. 2940 lock (aCircuit)
2847 if (sp == null) 2941 {
2848 { 2942 vialogin
2849 m_log.DebugFormat( 2943 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2850 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 2944 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2851 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); 2945
2852 2946 CheckHeartbeat();
2853 m_clientManager.Add(client); 2947
2854 SubscribeToClientEvents(client); 2948 sp = GetScenePresence(client.AgentId);
2855
2856 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2857 m_eventManager.TriggerOnNewPresence(sp);
2858
2859 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2860 2949
2861 // The first agent upon login is a root agent by design. 2950 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
2862 // For this agent we will have to rez the attachments. 2951 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause
2863 // All other AddNewClient calls find aCircuit.child to be true. 2952 // other problems, and possible the code calling AddNewClient() should ensure that no client is already
2864 if (aCircuit.child == false) 2953 // connected.
2954 if (sp == null)
2865 { 2955 {
2866 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to 2956 m_log.DebugFormat(
2867 // start the scripts again (since this is done in RezAttachments()). 2957 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2868 // XXX: This is convoluted. 2958 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2869 sp.IsChildAgent = false; 2959
2870 2960 m_clientManager.Add(client);
2871 if (AttachmentsModule != null) 2961 SubscribeToClientEvents(client);
2872 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); 2962
2963 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2964 m_eventManager.TriggerOnNewPresence(sp);
2965
2966 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2967
2968 // The first agent upon login is a root agent by design.
2969 // For this agent we will have to rez the attachments.
2970 // All other AddNewClient calls find aCircuit.child to be true.
2971 if (aCircuit.child == false)
2972 {
2973 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to
2974 // start the scripts again (since this is done in RezAttachments()).
2975 // XXX: This is convoluted.
2976 sp.IsChildAgent = false;
2977
2978 if (AttachmentsModule != null)
2979 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
2980 }
2873 } 2981 }
2874 } 2982 else
2875 else 2983 {
2876 { 2984 m_log.WarnFormat(
2877 m_log.WarnFormat( 2985 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2878 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 2986 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2879 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2987 }
2880 } 2988
2989 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2990 // client is for a root or child agent.
2991 client.SceneAgent = sp;
2881 2992
2882 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 2993 // Cache the user's name
2883 // client is for a root or child agent. 2994 CacheUserName(sp, aCircuit);
2884 client.SceneAgent = sp; 2995
2996 EventManager.TriggerOnNewClient(client);
2997 if (vialogin)
2998 EventManager.TriggerOnClientLogin(client);
2999 }
2885 3000
2886 m_LastLogin = Util.EnvironmentTickCount(); 3001 m_LastLogin = Util.EnvironmentTickCount();
2887 3002
2888 // Cache the user's name
2889 CacheUserName(sp, aCircuit);
2890
2891 EventManager.TriggerOnNewClient(client);
2892 if (vialogin)
2893 {
2894 EventManager.TriggerOnClientLogin(client);
2895 // Send initial parcel data
2896/* this is done on TriggerOnNewClient by landmanegement respective event handler
2897 Vector3 pos = sp.AbsolutePosition;
2898 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2899 land.SendLandUpdateToClient(client);
2900*/
2901 }
2902
2903 return sp; 3003 return sp;
2904 } 3004 }
2905 3005
@@ -3439,110 +3539,131 @@ namespace OpenSim.Region.Framework.Scenes
3439 { 3539 {
3440// CheckHeartbeat(); 3540// CheckHeartbeat();
3441 bool isChildAgent = false; 3541 bool isChildAgent = false;
3442 ScenePresence avatar = GetScenePresence(agentID); 3542 AgentCircuitData acd;
3443
3444 if (avatar == null)
3445 {
3446 m_log.WarnFormat(
3447 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3448 3543
3449 return; 3544 lock (m_removeClientLock)
3450 }
3451
3452 try
3453 { 3545 {
3454 isChildAgent = avatar.IsChildAgent; 3546 acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3455 3547
3456 m_log.DebugFormat( 3548 if (acd == null)
3457 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3458 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3459
3460 // Don't do this to root agents, it's not nice for the viewer
3461 if (closeChildAgents && isChildAgent)
3462 { 3549 {
3463 // Tell a single agent to disconnect from the region. 3550 m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID);
3464 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3551 return;
3465 if (eq != null)
3466 {
3467 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3468 }
3469 else
3470 {
3471 avatar.ControllingClient.SendShutdownConnectionNotice();
3472 }
3473 } 3552 }
3474 3553 else
3475 // Only applies to root agents.
3476 if (avatar.ParentID != 0)
3477 { 3554 {
3478 avatar.StandUp(); 3555 // We remove the acd up here to avoid later raec conditions if two RemoveClient() calls occurred
3556 // simultaneously.
3557 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3479 } 3558 }
3559 }
3480 3560
3481 m_sceneGraph.removeUserCount(!isChildAgent); 3561 lock (acd)
3482 3562 {
3483 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3563 ScenePresence avatar = GetScenePresence(agentID);
3484 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3564
3485 if (closeChildAgents && CapsModule != null) 3565 if (avatar == null)
3486 CapsModule.RemoveCaps(agentID);
3487
3488 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3489 // this method is doing is HORRIBLE!!!
3490 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3491
3492 if (closeChildAgents && !isChildAgent)
3493 { 3566 {
3494 List<ulong> regions = avatar.KnownRegionHandles; 3567 m_log.WarnFormat(
3495 regions.Remove(RegionInfo.RegionHandle); 3568 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3496 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3569
3570 return;
3497 } 3571 }
3498 3572
3499 m_eventManager.TriggerClientClosed(agentID, this); 3573 try
3500 m_eventManager.TriggerOnRemovePresence(agentID);
3501
3502 if (!isChildAgent)
3503 { 3574 {
3504 if (AttachmentsModule != null) 3575 isChildAgent = avatar.IsChildAgent;
3576
3577 m_log.DebugFormat(
3578 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3579 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3580
3581 // Don't do this to root agents, it's not nice for the viewer
3582 if (closeChildAgents && isChildAgent)
3583 {
3584 // Tell a single agent to disconnect from the region.
3585 IEventQueue eq = RequestModuleInterface<IEventQueue>();
3586 if (eq != null)
3587 {
3588 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3589 }
3590 else
3591 {
3592 avatar.ControllingClient.SendShutdownConnectionNotice();
3593 }
3594 }
3595
3596 // Only applies to root agents.
3597 if (avatar.ParentID != 0)
3505 { 3598 {
3506 AttachmentsModule.DeRezAttachments(avatar); 3599 avatar.StandUp();
3507 } 3600 }
3508 3601
3509 ForEachClient( 3602 m_sceneGraph.removeUserCount(!isChildAgent);
3510 delegate(IClientAPI client) 3603
3604 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3605 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3606 if (closeChildAgents && CapsModule != null)
3607 CapsModule.RemoveCaps(agentID);
3608
3609// // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3610// // this method is doing is HORRIBLE!!!
3611 // Commented pending deletion since this method no longer appears to do anything at all
3612// avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3613
3614 if (closeChildAgents && !isChildAgent)
3615 {
3616 List<ulong> regions = avatar.KnownRegionHandles;
3617 regions.Remove(RegionInfo.RegionHandle);
3618 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3619 }
3620
3621 m_eventManager.TriggerClientClosed(agentID, this);
3622 m_eventManager.TriggerOnRemovePresence(agentID);
3623
3624 if (!isChildAgent)
3625 {
3626 if (AttachmentsModule != null)
3511 { 3627 {
3512 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3628 AttachmentsModule.DeRezAttachments(avatar);
3513 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3629 }
3514 catch (NullReferenceException) { }
3515 });
3516 }
3517
3518 // It's possible for child agents to have transactions if changes are being made cross-border.
3519 if (AgentTransactionsModule != null)
3520 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3521 3630
3522 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3631 ForEachClient(
3523 m_log.Debug("[Scene] The avatar has left the building"); 3632 delegate(IClientAPI client)
3524 } 3633 {
3525 catch (Exception e) 3634 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3526 { 3635 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3527 m_log.Error( 3636 catch (NullReferenceException) { }
3528 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); 3637 });
3529 } 3638 }
3530 finally
3531 {
3532 try
3533 {
3534 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3535 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3536 // the same cleanup exception continually.
3537 m_sceneGraph.RemoveScenePresence(agentID);
3538 m_clientManager.Remove(agentID);
3539 3639
3540 avatar.Close(); 3640 // It's possible for child agents to have transactions if changes are being made cross-border.
3641 if (AgentTransactionsModule != null)
3642 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3643 m_log.Debug("[Scene] The avatar has left the building");
3541 } 3644 }
3542 catch (Exception e) 3645 catch (Exception e)
3543 { 3646 {
3544 m_log.Error( 3647 m_log.Error(
3545 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); 3648 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e);
3649 }
3650 finally
3651 {
3652 try
3653 {
3654 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3655 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3656 // the same cleanup exception continually.
3657 m_sceneGraph.RemoveScenePresence(agentID);
3658 m_clientManager.Remove(agentID);
3659
3660 avatar.Close();
3661 }
3662 catch (Exception e)
3663 {
3664 m_log.Error(
3665 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e);
3666 }
3546 } 3667 }
3547 } 3668 }
3548 3669
@@ -3601,11 +3722,9 @@ namespace OpenSim.Region.Framework.Scenes
3601 3722
3602 /// <summary> 3723 /// <summary>
3603 /// Do the work necessary to initiate a new user connection for a particular scene. 3724 /// Do the work necessary to initiate a new user connection for a particular scene.
3604 /// At the moment, this consists of setting up the caps infrastructure
3605 /// The return bool should allow for connections to be refused, but as not all calling paths
3606 /// take proper notice of it let, we allowed banned users in still.
3607 /// </summary> 3725 /// </summary>
3608 /// <param name="agent">CircuitData of the agent who is connecting</param> 3726 /// <param name="agent">CircuitData of the agent who is connecting</param>
3727 /// <param name="teleportFlags"></param>
3609 /// <param name="reason">Outputs the reason for the false response on this string</param> 3728 /// <param name="reason">Outputs the reason for the false response on this string</param>
3610 /// <returns>True if the region accepts this agent. False if it does not. False will 3729 /// <returns>True if the region accepts this agent. False if it does not. False will
3611 /// also return a reason.</returns> 3730 /// also return a reason.</returns>
@@ -3616,10 +3735,20 @@ namespace OpenSim.Region.Framework.Scenes
3616 3735
3617 /// <summary> 3736 /// <summary>
3618 /// Do the work necessary to initiate a new user connection for a particular scene. 3737 /// Do the work necessary to initiate a new user connection for a particular scene.
3619 /// At the moment, this consists of setting up the caps infrastructure 3738 /// </summary>
3739 /// <remarks>
3740 /// The return bool should allow for connections to be refused, but as not all calling paths
3741 /// take proper notice of it yet, we still allowed banned users in.
3742 ///
3743 /// At the moment this method consists of setting up the caps infrastructure
3620 /// The return bool should allow for connections to be refused, but as not all calling paths 3744 /// The return bool should allow for connections to be refused, but as not all calling paths
3621 /// take proper notice of it let, we allowed banned users in still. 3745 /// take proper notice of it let, we allowed banned users in still.
3622 /// </summary> 3746 ///
3747 /// This method is called by the login service (in the case of login) or another simulator (in the case of region
3748 /// cross or teleport) to initiate the connection. It is not triggered by the viewer itself - the connection
3749 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
3750 /// the LLUDP stack).
3751 /// </remarks>
3623 /// <param name="agent">CircuitData of the agent who is connecting</param> 3752 /// <param name="agent">CircuitData of the agent who is connecting</param>
3624 /// <param name="reason">Outputs the reason for the false response on this string</param> 3753 /// <param name="reason">Outputs the reason for the false response on this string</param>
3625 /// <param name="requirePresenceLookup">True for normal presence. False for NPC 3754 /// <param name="requirePresenceLookup">True for normal presence. False for NPC
@@ -3718,83 +3847,86 @@ namespace OpenSim.Region.Framework.Scenes
3718 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3847 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3719 sp.Name, sp.UUID, RegionInfo.RegionName); 3848 sp.Name, sp.UUID, RegionInfo.RegionName);
3720 3849
3721 sp.ControllingClient.Close(); 3850 sp.ControllingClient.Close(true, true);
3722 sp = null; 3851 sp = null;
3723 } 3852 }
3724 3853
3725 3854 lock (agent)
3726 //On login test land permisions
3727 if (vialogin)
3728 { 3855 {
3729 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); 3856 //On login test land permisions
3730 if (cache != null) 3857 if (vialogin)
3731 cache.Remove(agent.firstname + " " + agent.lastname);
3732 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3733 { 3858 {
3734 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); 3859 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3735 return false; 3860 if (cache != null)
3861 cache.Remove(agent.firstname + " " + agent.lastname);
3862 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3863 {
3864 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3865 return false;
3866 }
3736 } 3867 }
3737 }
3738 3868
3739 if (sp == null) // We don't have an [child] agent here already 3869 if (sp == null) // We don't have an [child] agent here already
3740 {
3741 if (requirePresenceLookup)
3742 { 3870 {
3743 try 3871 if (requirePresenceLookup)
3744 { 3872 {
3745 if (!VerifyUserPresence(agent, out reason)) 3873 try
3874 {
3875 if (!VerifyUserPresence(agent, out reason))
3876 return false;
3877 } catch (Exception e)
3878 {
3879 m_log.ErrorFormat(
3880 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3746 return false; 3881 return false;
3747 } catch (Exception e) 3882 }
3883 }
3884
3885 try
3886 {
3887 // Always check estate if this is a login. Always
3888 // check if banned regions are to be blacked out.
3889 if (vialogin || (!m_seeIntoBannedRegion))
3890 {
3891 if (!AuthorizeUser(agent, out reason))
3892 return false;
3893 }
3894 }
3895 catch (Exception e)
3748 { 3896 {
3749 m_log.ErrorFormat( 3897 m_log.ErrorFormat(
3750 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3898 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
3751 return false; 3899 return false;
3752 } 3900 }
3753 }
3754 3901
3755 try 3902 m_log.InfoFormat(
3756 { 3903 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3757 // Always check estate if this is a login. Always 3904 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3758 // check if banned regions are to be blacked out. 3905 agent.AgentID, agent.circuitcode);
3759 if (vialogin || (!m_seeIntoBannedRegion)) 3906
3907 if (CapsModule != null)
3760 { 3908 {
3761 if (!AuthorizeUser(agent, out reason)) 3909 CapsModule.SetAgentCapsSeeds(agent);
3762 return false; 3910 CapsModule.CreateCaps(agent.AgentID);
3763 } 3911 }
3764 } 3912 }
3765 catch (Exception e) 3913 else
3766 { 3914 {
3767 m_log.ErrorFormat( 3915 // Let the SP know how we got here. This has a lot of interesting
3768 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); 3916 // uses down the line.
3769 return false; 3917 sp.TeleportFlags = (TPFlags)teleportFlags;
3770 }
3771 3918
3772 m_log.InfoFormat( 3919 if (sp.IsChildAgent)
3773 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", 3920 {
3774 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, 3921 m_log.DebugFormat(
3775 agent.AgentID, agent.circuitcode); 3922 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3776 3923 agent.AgentID, RegionInfo.RegionName);
3777 if (CapsModule != null)
3778 {
3779 CapsModule.SetAgentCapsSeeds(agent);
3780 CapsModule.CreateCaps(agent.AgentID);
3781 }
3782 } else
3783 {
3784 // Let the SP know how we got here. This has a lot of interesting
3785 // uses down the line.
3786 sp.TeleportFlags = (TPFlags)teleportFlags;
3787 3924
3788 if (sp.IsChildAgent) 3925 sp.AdjustKnownSeeds();
3789 {
3790 m_log.DebugFormat(
3791 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3792 agent.AgentID, RegionInfo.RegionName);
3793 3926
3794 sp.AdjustKnownSeeds(); 3927 if (CapsModule != null)
3795 3928 CapsModule.SetAgentCapsSeeds(agent);
3796 if (CapsModule != null) 3929 }
3797 CapsModule.SetAgentCapsSeeds(agent);
3798 } 3930 }
3799 } 3931 }
3800 3932
@@ -4225,8 +4357,9 @@ namespace OpenSim.Region.Framework.Scenes
4225 return false; 4357 return false;
4226 } 4358 }
4227 4359
4228 // We have to wait until the viewer contacts this region after receiving EAC. 4360 // We have to wait until the viewer contacts this region
4229 // That calls AddNewClient, which finally creates the ScenePresence 4361 // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send
4362 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence.
4230 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4363 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
4231 4364
4232 if (childAgentUpdate != null) 4365 if (childAgentUpdate != null)
@@ -4321,15 +4454,18 @@ namespace OpenSim.Region.Framework.Scenes
4321 /// Tell a single agent to disconnect from the region. 4454 /// Tell a single agent to disconnect from the region.
4322 /// </summary> 4455 /// </summary>
4323 /// <param name="agentID"></param> 4456 /// <param name="agentID"></param>
4324 /// <param name="childOnly"></param> 4457 /// <param name="force">
4325 public bool IncomingCloseAgent(UUID agentID, bool childOnly) 4458 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4459 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4460 /// </param>
4461 public bool IncomingCloseAgent(UUID agentID, bool force)
4326 { 4462 {
4327 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4463 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
4328 4464
4329 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4465 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4330 if (presence != null) 4466 if (presence != null)
4331 { 4467 {
4332 presence.ControllingClient.Close(false); 4468 presence.ControllingClient.Close(force, force);
4333 return true; 4469 return true;
4334 } 4470 }
4335 4471
@@ -4535,6 +4671,16 @@ namespace OpenSim.Region.Framework.Scenes
4535 return LandChannel.GetLandObject(x, y).LandData; 4671 return LandChannel.GetLandObject(x, y).LandData;
4536 } 4672 }
4537 4673
4674 /// <summary>
4675 /// Get LandData by position.
4676 /// </summary>
4677 /// <param name="pos"></param>
4678 /// <returns></returns>
4679 public LandData GetLandData(Vector3 pos)
4680 {
4681 return GetLandData(pos.X, pos.Y);
4682 }
4683
4538 public LandData GetLandData(uint x, uint y) 4684 public LandData GetLandData(uint x, uint y)
4539 { 4685 {
4540 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); 4686 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
@@ -4765,13 +4911,24 @@ namespace OpenSim.Region.Framework.Scenes
4765 /// Get a group via its UUID 4911 /// Get a group via its UUID
4766 /// </summary> 4912 /// </summary>
4767 /// <param name="fullID"></param> 4913 /// <param name="fullID"></param>
4768 /// <returns>null if no group with that name exists</returns> 4914 /// <returns>null if no group with that id exists</returns>
4769 public SceneObjectGroup GetSceneObjectGroup(UUID fullID) 4915 public SceneObjectGroup GetSceneObjectGroup(UUID fullID)
4770 { 4916 {
4771 return m_sceneGraph.GetSceneObjectGroup(fullID); 4917 return m_sceneGraph.GetSceneObjectGroup(fullID);
4772 } 4918 }
4773 4919
4774 /// <summary> 4920 /// <summary>
4921 /// Get a group via its local ID
4922 /// </summary>
4923 /// <remarks>This will only return a group if the local ID matches a root part</remarks>
4924 /// <param name="localID"></param>
4925 /// <returns>null if no group with that id exists</returns>
4926 public SceneObjectGroup GetSceneObjectGroup(uint localID)
4927 {
4928 return m_sceneGraph.GetSceneObjectGroup(localID);
4929 }
4930
4931 /// <summary>
4775 /// Get a group by name from the scene (will return the first 4932 /// Get a group by name from the scene (will return the first
4776 /// found, if there are more than one prim with the same name) 4933 /// found, if there are more than one prim with the same name)
4777 /// </summary> 4934 /// </summary>
@@ -4783,6 +4940,18 @@ namespace OpenSim.Region.Framework.Scenes
4783 } 4940 }
4784 4941
4785 /// <summary> 4942 /// <summary>
4943 /// Attempt to get the SOG via its UUID
4944 /// </summary>
4945 /// <param name="fullID"></param>
4946 /// <param name="sog"></param>
4947 /// <returns></returns>
4948 public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog)
4949 {
4950 sog = GetSceneObjectGroup(fullID);
4951 return sog != null;
4952 }
4953
4954 /// <summary>
4786 /// Get a prim by name from the scene (will return the first 4955 /// Get a prim by name from the scene (will return the first
4787 /// found, if there are more than one prim with the same name) 4956 /// found, if there are more than one prim with the same name)
4788 /// </summary> 4957 /// </summary>
@@ -4814,6 +4983,18 @@ namespace OpenSim.Region.Framework.Scenes
4814 } 4983 }
4815 4984
4816 /// <summary> 4985 /// <summary>
4986 /// Attempt to get a prim via its UUID
4987 /// </summary>
4988 /// <param name="fullID"></param>
4989 /// <param name="sop"></param>
4990 /// <returns></returns>
4991 public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop)
4992 {
4993 sop = GetSceneObjectPart(fullID);
4994 return sop != null;
4995 }
4996
4997 /// <summary>
4817 /// Get a scene object group that contains the prim with the given local id 4998 /// Get a scene object group that contains the prim with the given local id
4818 /// </summary> 4999 /// </summary>
4819 /// <param name="localID"></param> 5000 /// <param name="localID"></param>
@@ -4907,14 +5088,15 @@ namespace OpenSim.Region.Framework.Scenes
4907 client.SendRegionHandle(regionID, handle); 5088 client.SendRegionHandle(regionID, handle);
4908 } 5089 }
4909 5090
4910 public bool NeedSceneCacheClear(UUID agentID) 5091// Commented pending deletion since this method no longer appears to do anything at all
4911 { 5092// public bool NeedSceneCacheClear(UUID agentID)
4912 IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>(); 5093// {
4913 if (inv == null) 5094// IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
4914 return true; 5095// if (inv == null)
4915 5096// return true;
4916 return inv.NeedSceneCacheClear(agentID, this); 5097//
4917 } 5098// return inv.NeedSceneCacheClear(agentID, this);
5099// }
4918 5100
4919 public void CleanTempObjects() 5101 public void CleanTempObjects()
4920 { 5102 {
@@ -5868,6 +6050,9 @@ Environment.Exit(1);
5868 6050
5869 public string GetExtraSetting(string name) 6051 public string GetExtraSetting(string name)
5870 { 6052 {
6053 if (m_extraSettings == null)
6054 return String.Empty;
6055
5871 string val; 6056 string val;
5872 6057
5873 if (!m_extraSettings.TryGetValue(name, out val)) 6058 if (!m_extraSettings.TryGetValue(name, out val))
@@ -5878,6 +6063,9 @@ Environment.Exit(1);
5878 6063
5879 public void StoreExtraSetting(string name, string val) 6064 public void StoreExtraSetting(string name, string val)
5880 { 6065 {
6066 if (m_extraSettings == null)
6067 return;
6068
5881 string oldVal; 6069 string oldVal;
5882 6070
5883 if (m_extraSettings.TryGetValue(name, out oldVal)) 6071 if (m_extraSettings.TryGetValue(name, out oldVal))
@@ -5895,6 +6083,9 @@ Environment.Exit(1);
5895 6083
5896 public void RemoveExtraSetting(string name) 6084 public void RemoveExtraSetting(string name)
5897 { 6085 {
6086 if (m_extraSettings == null)
6087 return;
6088
5898 if (!m_extraSettings.ContainsKey(name)) 6089 if (!m_extraSettings.ContainsKey(name))
5899 return; 6090 return;
5900 6091
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..dba3a61 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>();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index ee61de6..74d2629 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2747,6 +2747,25 @@ namespace OpenSim.Region.Framework.Scenes
2747 if (objectGroup == this) 2747 if (objectGroup == this)
2748 return; 2748 return;
2749 2749
2750 // If the configured linkset capacity is greater than zero,
2751 // and the new linkset would have a prim count higher than this
2752 // value, do not link it.
2753 if (m_scene.m_linksetCapacity > 0 &&
2754 (PrimCount + objectGroup.PrimCount) >
2755 m_scene.m_linksetCapacity)
2756 {
2757 m_log.DebugFormat(
2758 "[SCENE OBJECT GROUP]: Cannot link group with root" +
2759 " part {0}, {1} ({2} prims) to group with root part" +
2760 " {3}, {4} ({5} prims) because the new linkset" +
2761 " would exceed the configured maximum of {6}",
2762 objectGroup.RootPart.Name, objectGroup.RootPart.UUID,
2763 objectGroup.PrimCount, RootPart.Name, RootPart.UUID,
2764 PrimCount, m_scene.m_linksetCapacity);
2765
2766 return;
2767 }
2768
2750 // 'linkPart' == the root of the group being linked into this group 2769 // 'linkPart' == the root of the group being linked into this group
2751 SceneObjectPart linkPart = objectGroup.m_rootPart; 2770 SceneObjectPart linkPart = objectGroup.m_rootPart;
2752 2771
@@ -3492,27 +3511,33 @@ namespace OpenSim.Region.Framework.Scenes
3492 /// <param name="scale"></param> 3511 /// <param name="scale"></param>
3493 public void GroupResize(Vector3 scale) 3512 public void GroupResize(Vector3 scale)
3494 { 3513 {
3495 scale.X = Math.Min(scale.X, Scene.m_maxNonphys); 3514// m_log.DebugFormat(
3496 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); 3515// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
3497 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
3498 3516
3499 PhysicsActor pa = m_rootPart.PhysActor; 3517 PhysicsActor pa = m_rootPart.PhysActor;
3500 3518
3501 if (pa != null && pa.IsPhysical) 3519 if (Scene != null)
3502 { 3520 {
3503 scale.X = Math.Min(scale.X, Scene.m_maxPhys); 3521 scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X));
3504 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); 3522 scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y));
3505 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); 3523 scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z));
3524
3525 if (pa != null && pa.IsPhysical)
3526 {
3527 scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X));
3528 scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y));
3529 scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z));
3530 }
3506 } 3531 }
3507 3532
3508 float x = (scale.X / RootPart.Scale.X); 3533 float x = (scale.X / RootPart.Scale.X);
3509 float y = (scale.Y / RootPart.Scale.Y); 3534 float y = (scale.Y / RootPart.Scale.Y);
3510 float z = (scale.Z / RootPart.Scale.Z); 3535 float z = (scale.Z / RootPart.Scale.Z);
3511 3536
3512 SceneObjectPart[] parts; 3537 SceneObjectPart[] parts = m_parts.GetArray();
3513 if (x > 1.0f || y > 1.0f || z > 1.0f) 3538
3539 if (Scene != null & (x > 1.0f || y > 1.0f || z > 1.0f))
3514 { 3540 {
3515 parts = m_parts.GetArray();
3516 for (int i = 0; i < parts.Length; i++) 3541 for (int i = 0; i < parts.Length; i++)
3517 { 3542 {
3518 SceneObjectPart obPart = parts[i]; 3543 SceneObjectPart obPart = parts[i];
@@ -3525,7 +3550,7 @@ namespace OpenSim.Region.Framework.Scenes
3525 3550
3526 if (pa != null && pa.IsPhysical) 3551 if (pa != null && pa.IsPhysical)
3527 { 3552 {
3528 if (oldSize.X * x > m_scene.m_maxPhys) 3553 if (oldSize.X * x > Scene.m_maxPhys)
3529 { 3554 {
3530 f = m_scene.m_maxPhys / oldSize.X; 3555 f = m_scene.m_maxPhys / oldSize.X;
3531 a = f / x; 3556 a = f / x;
@@ -3533,8 +3558,16 @@ namespace OpenSim.Region.Framework.Scenes
3533 y *= a; 3558 y *= a;
3534 z *= a; 3559 z *= a;
3535 } 3560 }
3561 else if (oldSize.X * x < Scene.m_minPhys)
3562 {
3563 f = m_scene.m_minPhys / oldSize.X;
3564 a = f / x;
3565 x *= a;
3566 y *= a;
3567 z *= a;
3568 }
3536 3569
3537 if (oldSize.Y * y > m_scene.m_maxPhys) 3570 if (oldSize.Y * y > Scene.m_maxPhys)
3538 { 3571 {
3539 f = m_scene.m_maxPhys / oldSize.Y; 3572 f = m_scene.m_maxPhys / oldSize.Y;
3540 a = f / y; 3573 a = f / y;
@@ -3542,8 +3575,16 @@ namespace OpenSim.Region.Framework.Scenes
3542 y *= a; 3575 y *= a;
3543 z *= a; 3576 z *= a;
3544 } 3577 }
3578 else if (oldSize.Y * y < Scene.m_minPhys)
3579 {
3580 f = m_scene.m_minPhys / oldSize.Y;
3581 a = f / y;
3582 x *= a;
3583 y *= a;
3584 z *= a;
3585 }
3545 3586
3546 if (oldSize.Z * z > m_scene.m_maxPhys) 3587 if (oldSize.Z * z > Scene.m_maxPhys)
3547 { 3588 {
3548 f = m_scene.m_maxPhys / oldSize.Z; 3589 f = m_scene.m_maxPhys / oldSize.Z;
3549 a = f / z; 3590 a = f / z;
@@ -3551,10 +3592,18 @@ namespace OpenSim.Region.Framework.Scenes
3551 y *= a; 3592 y *= a;
3552 z *= a; 3593 z *= a;
3553 } 3594 }
3595 else if (oldSize.Z * z < Scene.m_minPhys)
3596 {
3597 f = m_scene.m_minPhys / oldSize.Z;
3598 a = f / z;
3599 x *= a;
3600 y *= a;
3601 z *= a;
3602 }
3554 } 3603 }
3555 else 3604 else
3556 { 3605 {
3557 if (oldSize.X * x > m_scene.m_maxNonphys) 3606 if (oldSize.X * x > Scene.m_maxNonphys)
3558 { 3607 {
3559 f = m_scene.m_maxNonphys / oldSize.X; 3608 f = m_scene.m_maxNonphys / oldSize.X;
3560 a = f / x; 3609 a = f / x;
@@ -3562,8 +3611,16 @@ namespace OpenSim.Region.Framework.Scenes
3562 y *= a; 3611 y *= a;
3563 z *= a; 3612 z *= a;
3564 } 3613 }
3614 else if (oldSize.X * x < Scene.m_minNonphys)
3615 {
3616 f = m_scene.m_minNonphys / oldSize.X;
3617 a = f / x;
3618 x *= a;
3619 y *= a;
3620 z *= a;
3621 }
3565 3622
3566 if (oldSize.Y * y > m_scene.m_maxNonphys) 3623 if (oldSize.Y * y > Scene.m_maxNonphys)
3567 { 3624 {
3568 f = m_scene.m_maxNonphys / oldSize.Y; 3625 f = m_scene.m_maxNonphys / oldSize.Y;
3569 a = f / y; 3626 a = f / y;
@@ -3571,8 +3628,16 @@ namespace OpenSim.Region.Framework.Scenes
3571 y *= a; 3628 y *= a;
3572 z *= a; 3629 z *= a;
3573 } 3630 }
3631 else if (oldSize.Y * y < Scene.m_minNonphys)
3632 {
3633 f = m_scene.m_minNonphys / oldSize.Y;
3634 a = f / y;
3635 x *= a;
3636 y *= a;
3637 z *= a;
3638 }
3574 3639
3575 if (oldSize.Z * z > m_scene.m_maxNonphys) 3640 if (oldSize.Z * z > Scene.m_maxNonphys)
3576 { 3641 {
3577 f = m_scene.m_maxNonphys / oldSize.Z; 3642 f = m_scene.m_maxNonphys / oldSize.Z;
3578 a = f / z; 3643 a = f / z;
@@ -3580,6 +3645,14 @@ namespace OpenSim.Region.Framework.Scenes
3580 y *= a; 3645 y *= a;
3581 z *= a; 3646 z *= a;
3582 } 3647 }
3648 else if (oldSize.Z * z < Scene.m_minNonphys)
3649 {
3650 f = m_scene.m_minNonphys / oldSize.Z;
3651 a = f / z;
3652 x *= a;
3653 y *= a;
3654 z *= a;
3655 }
3583 } 3656 }
3584 } 3657 }
3585 } 3658 }
@@ -3592,7 +3665,6 @@ namespace OpenSim.Region.Framework.Scenes
3592 3665
3593 RootPart.Resize(prevScale); 3666 RootPart.Resize(prevScale);
3594 3667
3595 parts = m_parts.GetArray();
3596 for (int i = 0; i < parts.Length; i++) 3668 for (int i = 0; i < parts.Length; i++)
3597 { 3669 {
3598 SceneObjectPart obPart = parts[i]; 3670 SceneObjectPart obPart = parts[i];
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 49b771f..248679b 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 }
@@ -2979,17 +2979,20 @@ namespace OpenSim.Region.Framework.Scenes
2979 /// <param name="scale"></param> 2979 /// <param name="scale"></param>
2980 public void Resize(Vector3 scale) 2980 public void Resize(Vector3 scale)
2981 { 2981 {
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; 2982 PhysicsActor pa = PhysActor;
2987 2983
2988 if (pa != null && pa.IsPhysical) 2984 if (ParentGroup.Scene != null)
2989 { 2985 {
2990 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); 2986 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); 2987 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); 2988 scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z));
2989
2990 if (pa != null && pa.IsPhysical)
2991 {
2992 scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X));
2993 scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y));
2994 scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z));
2995 }
2993 } 2996 }
2994 2997
2995// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); 2998// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
@@ -3086,7 +3089,7 @@ namespace OpenSim.Region.Framework.Scenes
3086 // UUID, Name, TimeStampFull); 3089 // UUID, Name, TimeStampFull);
3087 3090
3088 if (ParentGroup.Scene != null) 3091 if (ParentGroup.Scene != null)
3089 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this); 3092 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true);
3090 } 3093 }
3091 3094
3092 /// <summary> 3095 /// <summary>
@@ -3120,7 +3123,7 @@ namespace OpenSim.Region.Framework.Scenes
3120 } 3123 }
3121 3124
3122 if (ParentGroup.Scene != null) 3125 if (ParentGroup.Scene != null)
3123 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this); 3126 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false);
3124 } 3127 }
3125 3128
3126 public void ScriptSetPhysicsStatus(bool UsePhysics) 3129 public void ScriptSetPhysicsStatus(bool UsePhysics)
@@ -3575,23 +3578,32 @@ namespace OpenSim.Region.Framework.Scenes
3575 } 3578 }
3576 3579
3577 /// <summary> 3580 /// <summary>
3578 /// Set the color of prim faces 3581 /// Set the color & alpha of prim faces
3579 /// </summary> 3582 /// </summary>
3580 /// <param name="color"></param>
3581 /// <param name="face"></param> 3583 /// <param name="face"></param>
3582 public void SetFaceColor(Vector3 color, int face) 3584 /// <param name="color"></param>
3585 /// <param name="alpha"></param>
3586 public void SetFaceColorAlpha(int face, Vector3 color, double ?alpha)
3583 { 3587 {
3588 Vector3 clippedColor = Util.Clip(color, 0.0f, 1.0f);
3589 float clippedAlpha = alpha.HasValue ?
3590 Util.Clip((float)alpha.Value, 0.0f, 1.0f) : 0;
3591
3584 // The only way to get a deep copy/ If we don't do this, we can 3592 // The only way to get a deep copy/ If we don't do this, we can
3585 // mever detect color changes further down. 3593 // never detect color changes further down.
3586 Byte[] buf = Shape.Textures.GetBytes(); 3594 Byte[] buf = Shape.Textures.GetBytes();
3587 Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); 3595 Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length);
3588 Color4 texcolor; 3596 Color4 texcolor;
3589 if (face >= 0 && face < GetNumberOfSides()) 3597 if (face >= 0 && face < GetNumberOfSides())
3590 { 3598 {
3591 texcolor = tex.CreateFace((uint)face).RGBA; 3599 texcolor = tex.CreateFace((uint)face).RGBA;
3592 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3600 texcolor.R = clippedColor.X;
3593 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3601 texcolor.G = clippedColor.Y;
3594 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3602 texcolor.B = clippedColor.Z;
3603 if (alpha.HasValue)
3604 {
3605 texcolor.A = clippedAlpha;
3606 }
3595 tex.FaceTextures[face].RGBA = texcolor; 3607 tex.FaceTextures[face].RGBA = texcolor;
3596 UpdateTextureEntry(tex.GetBytes()); 3608 UpdateTextureEntry(tex.GetBytes());
3597 return; 3609 return;
@@ -3603,15 +3615,23 @@ namespace OpenSim.Region.Framework.Scenes
3603 if (tex.FaceTextures[i] != null) 3615 if (tex.FaceTextures[i] != null)
3604 { 3616 {
3605 texcolor = tex.FaceTextures[i].RGBA; 3617 texcolor = tex.FaceTextures[i].RGBA;
3606 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3618 texcolor.R = clippedColor.X;
3607 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3619 texcolor.G = clippedColor.Y;
3608 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3620 texcolor.B = clippedColor.Z;
3621 if (alpha.HasValue)
3622 {
3623 texcolor.A = clippedAlpha;
3624 }
3609 tex.FaceTextures[i].RGBA = texcolor; 3625 tex.FaceTextures[i].RGBA = texcolor;
3610 } 3626 }
3611 texcolor = tex.DefaultTexture.RGBA; 3627 texcolor = tex.DefaultTexture.RGBA;
3612 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3628 texcolor.R = clippedColor.X;
3613 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3629 texcolor.G = clippedColor.Y;
3614 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3630 texcolor.B = clippedColor.Z;
3631 if (alpha.HasValue)
3632 {
3633 texcolor.A = clippedAlpha;
3634 }
3615 tex.DefaultTexture.RGBA = texcolor; 3635 tex.DefaultTexture.RGBA = texcolor;
3616 } 3636 }
3617 UpdateTextureEntry(tex.GetBytes()); 3637 UpdateTextureEntry(tex.GetBytes());
@@ -4899,6 +4919,57 @@ namespace OpenSim.Region.Framework.Scenes
4899 ScheduleFullUpdate(); 4919 ScheduleFullUpdate();
4900 } 4920 }
4901 4921
4922 public void UpdateSlice(float begin, float end)
4923 {
4924 if (end < begin)
4925 {
4926 float temp = begin;
4927 begin = end;
4928 end = temp;
4929 }
4930 end = Math.Min(1f, Math.Max(0f, end));
4931 begin = Math.Min(Math.Min(1f, Math.Max(0f, begin)), end - 0.02f);
4932 if (begin < 0.02f && end < 0.02f)
4933 {
4934 begin = 0f;
4935 end = 0.02f;
4936 }
4937
4938 ushort uBegin = (ushort)(50000.0 * begin);
4939 ushort uEnd = (ushort)(50000.0 * (1f - end));
4940 bool updatePossiblyNeeded = false;
4941 PrimType primType = GetPrimType();
4942 if (primType == PrimType.SPHERE || primType == PrimType.TORUS || primType == PrimType.TUBE || primType == PrimType.RING)
4943 {
4944 if (m_shape.ProfileBegin != uBegin || m_shape.ProfileEnd != uEnd)
4945 {
4946 m_shape.ProfileBegin = uBegin;
4947 m_shape.ProfileEnd = uEnd;
4948 updatePossiblyNeeded = true;
4949 }
4950 }
4951 else if (m_shape.PathBegin != uBegin || m_shape.PathEnd != uEnd)
4952 {
4953 m_shape.PathBegin = uBegin;
4954 m_shape.PathEnd = uEnd;
4955 updatePossiblyNeeded = true;
4956 }
4957
4958 if (updatePossiblyNeeded && ParentGroup != null)
4959 {
4960 ParentGroup.HasGroupChanged = true;
4961 }
4962 if (updatePossiblyNeeded && PhysActor != null)
4963 {
4964 PhysActor.Shape = m_shape;
4965 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
4966 }
4967 if (updatePossiblyNeeded)
4968 {
4969 ScheduleFullUpdate();
4970 }
4971 }
4972
4902 /// <summary> 4973 /// <summary>
4903 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics 4974 /// 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. 4975 /// engine can use it.
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index e010864..f41e329 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
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index a8aa551..870bd66 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -69,7 +69,7 @@ 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 {
@@ -188,7 +188,7 @@ namespace OpenSim.Region.Framework.Scenes
188 /// </summary> 188 /// </summary>
189 public bool SitGround { get; private set; } 189 public bool SitGround { get; private set; }
190 190
191 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 191 private SendCoarseLocationsMethod m_sendCoarseLocationsMethod;
192 192
193 //private Vector3 m_requestedSitOffset = new Vector3(); 193 //private Vector3 m_requestedSitOffset = new Vector3();
194 194
@@ -711,7 +711,7 @@ namespace OpenSim.Region.Framework.Scenes
711 AttachmentsSyncLock = new Object(); 711 AttachmentsSyncLock = new Object();
712 AllowMovement = true; 712 AllowMovement = true;
713 IsChildAgent = true; 713 IsChildAgent = true;
714 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 714 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
715 Animator = new ScenePresenceAnimator(this); 715 Animator = new ScenePresenceAnimator(this);
716 PresenceType = type; 716 PresenceType = type;
717 DrawDistance = world.DefaultDrawDistance; 717 DrawDistance = world.DefaultDrawDistance;
@@ -974,7 +974,9 @@ namespace OpenSim.Region.Framework.Scenes
974 { 974 {
975 if (wasChild && HasAttachments()) 975 if (wasChild && HasAttachments())
976 { 976 {
977 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); 977 m_log.DebugFormat(
978 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
979
978 // Resume scripts 980 // Resume scripts
979 Util.FireAndForget(delegate(object x) { 981 Util.FireAndForget(delegate(object x) {
980 foreach (SceneObjectGroup sog in m_attachments) 982 foreach (SceneObjectGroup sog in m_attachments)
@@ -1530,17 +1532,22 @@ namespace OpenSim.Region.Framework.Scenes
1530 bool DCFlagKeyPressed = false; 1532 bool DCFlagKeyPressed = false;
1531 Vector3 agent_control_v3 = Vector3.Zero; 1533 Vector3 agent_control_v3 = Vector3.Zero;
1532 1534
1533 bool oldflying = Flying; 1535 bool newFlying = actor.Flying;
1534 1536
1535 if (ForceFly) 1537 if (ForceFly)
1536 actor.Flying = true; 1538 newFlying = true;
1537 else if (FlyDisabled) 1539 else if (FlyDisabled)
1538 actor.Flying = false; 1540 newFlying = false;
1539 else 1541 else
1540 actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1542 newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1541 1543
1542 if (actor.Flying != oldflying) 1544 if (actor.Flying != newFlying)
1545 {
1546 // Note: ScenePresence.Flying is actually fetched from the physical actor
1547 // so setting PhysActor.Flying here also sets the ScenePresence's value.
1548 actor.Flying = newFlying;
1543 update_movementflag = true; 1549 update_movementflag = true;
1550 }
1544 1551
1545 if (ParentID == 0) 1552 if (ParentID == 0)
1546 { 1553 {
@@ -2622,17 +2629,17 @@ namespace OpenSim.Region.Framework.Scenes
2622 2629
2623 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2630 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
2624 { 2631 {
2625 SendCourseLocationsMethod d = m_sendCourseLocationsMethod; 2632 SendCoarseLocationsMethod d = m_sendCoarseLocationsMethod;
2626 if (d != null) 2633 if (d != null)
2627 { 2634 {
2628 d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs); 2635 d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs);
2629 } 2636 }
2630 } 2637 }
2631 2638
2632 public void SetSendCourseLocationMethod(SendCourseLocationsMethod d) 2639 public void SetSendCoarseLocationMethod(SendCoarseLocationsMethod d)
2633 { 2640 {
2634 if (d != null) 2641 if (d != null)
2635 m_sendCourseLocationsMethod = d; 2642 m_sendCoarseLocationsMethod = d;
2636 } 2643 }
2637 2644
2638 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2645 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
@@ -2836,7 +2843,7 @@ namespace OpenSim.Region.Framework.Scenes
2836 #region Significant Movement Method 2843 #region Significant Movement Method
2837 2844
2838 /// <summary> 2845 /// <summary>
2839 /// This checks for a significant movement and sends a courselocationchange update 2846 /// This checks for a significant movement and sends a coarselocationchange update
2840 /// </summary> 2847 /// </summary>
2841 protected void CheckForSignificantMovement() 2848 protected void CheckForSignificantMovement()
2842 { 2849 {
@@ -3268,7 +3275,7 @@ namespace OpenSim.Region.Framework.Scenes
3268 cAgent.Anims = Animator.Animations.ToArray(); 3275 cAgent.Anims = Animator.Animations.ToArray();
3269 } 3276 }
3270 catch { } 3277 catch { }
3271 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; 3278 cAgent.DefaultAnim = Animator.Animations.ImplicitDefaultAnimation;
3272 3279
3273 if (Scene.AttachmentsModule != null) 3280 if (Scene.AttachmentsModule != null)
3274 Scene.AttachmentsModule.CopyAttachments(this, cAgent); 3281 Scene.AttachmentsModule.CopyAttachments(this, cAgent);
@@ -3627,13 +3634,16 @@ namespace OpenSim.Region.Framework.Scenes
3627 public List<SceneObjectGroup> GetAttachments(uint attachmentPoint) 3634 public List<SceneObjectGroup> GetAttachments(uint attachmentPoint)
3628 { 3635 {
3629 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(); 3636 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
3630 3637
3631 lock (m_attachments) 3638 if (attachmentPoint >= 0)
3632 { 3639 {
3633 foreach (SceneObjectGroup so in m_attachments) 3640 lock (m_attachments)
3634 { 3641 {
3635 if (attachmentPoint == so.AttachmentPoint) 3642 foreach (SceneObjectGroup so in m_attachments)
3636 attachments.Add(so); 3643 {
3644 if (attachmentPoint == so.AttachmentPoint)
3645 attachments.Add(so);
3646 }
3637 } 3647 }
3638 } 3648 }
3639 3649
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/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}