aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs9
-rw-r--r--OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs69
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEstateModule.cs4
-rw-r--r--OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs71
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUrlModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUserManagement.cs29
-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.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs618
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs11
-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/ScenePresence.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs33
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs36
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs136
20 files changed, 1457 insertions, 358 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index 90a13a7..d781eae 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -114,6 +114,15 @@ namespace OpenSim.Region.Framework.Interfaces
114 void DetachSingleAttachmentToGround(IScenePresence sp, uint objectLocalID); 114 void DetachSingleAttachmentToGround(IScenePresence sp, uint objectLocalID);
115 115
116 /// <summary> 116 /// <summary>
117 /// Detach the given item to the ground at the specified coordinates & rotation
118 /// </summary>
119 /// <param name="sp"></param>
120 /// <param name="objectLocalID"></param>
121 /// <param name="absolutePos"></param>
122 /// <param name="absoluteRot"></param>
123 void DetachSingleAttachmentToGround(IScenePresence sp, uint objectLocalID, Vector3 absolutePos, Quaternion absoluteRot);
124
125 /// <summary>
117 /// Detach the given attachment so that it remains in the user's inventory. 126 /// Detach the given attachment so that it remains in the user's inventory.
118 /// </summary> 127 /// </summary>
119 /// <param name="sp">/param> 128 /// <param name="sp">/param>
diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
index 8954513..6df5cc2 100644
--- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
+++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
@@ -25,6 +25,8 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
29using System.Drawing;
28using System.IO; 30using System.IO;
29using OpenMetaverse; 31using OpenMetaverse;
30 32
@@ -33,7 +35,14 @@ namespace OpenSim.Region.Framework.Interfaces
33 public interface IDynamicTextureManager 35 public interface IDynamicTextureManager
34 { 36 {
35 void RegisterRender(string handleType, IDynamicTextureRender render); 37 void RegisterRender(string handleType, IDynamicTextureRender render);
36 void ReturnData(UUID id, byte[] data); 38
39 /// <summary>
40 /// Used by IDynamicTextureRender implementations to return renders
41 /// </summary>
42 /// <param name='id'></param>
43 /// <param name='data'></param>
44 /// <param name='isReuseable'></param>
45 void ReturnData(UUID id, IDynamicTexture texture);
37 46
38 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, 47 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
39 int updateTimer); 48 int updateTimer);
@@ -113,11 +122,65 @@ namespace OpenSim.Region.Framework.Interfaces
113 string GetName(); 122 string GetName();
114 string GetContentType(); 123 string GetContentType();
115 bool SupportsAsynchronous(); 124 bool SupportsAsynchronous();
116 byte[] ConvertUrl(string url, string extraParams); 125
117 byte[] ConvertStream(Stream data, string extraParams); 126// /// <summary>
127// /// Return true if converting the input body and extra params data will always result in the same byte[] array
128// /// </summary>
129// /// <remarks>
130// /// This method allows the caller to use a previously generated asset if it has one.
131// /// </remarks>
132// /// <returns></returns>
133// /// <param name='bodyData'></param>
134// /// <param name='extraParams'></param>
135// bool AlwaysIdenticalConversion(string bodyData, string extraParams);
136
137 IDynamicTexture ConvertUrl(string url, string extraParams);
138 IDynamicTexture ConvertData(string bodyData, string extraParams);
139
118 bool AsyncConvertUrl(UUID id, string url, string extraParams); 140 bool AsyncConvertUrl(UUID id, string url, string extraParams);
119 bool AsyncConvertData(UUID id, string bodyData, string extraParams); 141 bool AsyncConvertData(UUID id, string bodyData, string extraParams);
142
120 void GetDrawStringSize(string text, string fontName, int fontSize, 143 void GetDrawStringSize(string text, string fontName, int fontSize,
121 out double xSize, out double ySize); 144 out double xSize, out double ySize);
122 } 145 }
146
147 public interface IDynamicTexture
148 {
149 /// <summary>
150 /// Input commands used to generate this data.
151 /// </summary>
152 /// <remarks>
153 /// Null if input commands were not used.
154 /// </remarks>
155 string InputCommands { get; }
156
157 /// <summary>
158 /// Uri used to generate this data.
159 /// </summary>
160 /// <remarks>
161 /// Null if a uri was not used.
162 /// </remarks>
163 Uri InputUri { get; }
164
165 /// <summary>
166 /// Extra input params used to generate this data.
167 /// </summary>
168 string InputParams { get; }
169
170 /// <summary>
171 /// Texture data.
172 /// </summary>
173 byte[] Data { get; }
174
175 /// <summary>
176 /// Size of texture.
177 /// </summary>
178 Size Size { get; }
179
180 /// <summary>
181 /// Signal whether the texture is reuseable (i.e. whether the same input data will always generate the same
182 /// texture).
183 /// </summary>
184 bool IsReuseable { get; }
185 }
123} 186}
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
index ca2ad94..292efa4 100644
--- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
@@ -46,6 +46,10 @@ namespace OpenSim.Region.Framework.Interfaces
46 /// </summary> 46 /// </summary>
47 void sendRegionHandshakeToAll(); 47 void sendRegionHandshakeToAll();
48 void TriggerEstateInfoChange(); 48 void TriggerEstateInfoChange();
49
50 /// <summary>
51 /// Fires the OnRegionInfoChange event.
52 /// </summary>
49 void TriggerRegionInfoChange(); 53 void TriggerRegionInfoChange();
50 54
51 void setEstateTerrainBaseTexture(int level, UUID texture); 55 void setEstateTerrainBaseTexture(int level, UUID texture);
diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
index baac6e8..da39e95 100644
--- a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
@@ -35,7 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces
35 35
36 public interface IJsonStoreModule 36 public interface IJsonStoreModule
37 { 37 {
38 bool CreateStore(string value, out UUID result); 38 bool CreateStore(string value, ref UUID result);
39 bool DestroyStore(UUID storeID); 39 bool DestroyStore(UUID storeID);
40 bool TestPath(UUID storeID, string path, bool useJson); 40 bool TestPath(UUID storeID, string path, bool useJson);
41 bool SetValue(UUID storeID, string path, string value, bool useJson); 41 bool SetValue(UUID storeID, string path, string value, bool useJson);
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
index ed71a95..93930ce 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
@@ -46,9 +46,46 @@ namespace OpenSim.Region.Framework.Interfaces
46 /// </summary> 46 /// </summary>
47 event ScriptCommand OnScriptCommand; 47 event ScriptCommand OnScriptCommand;
48 48
49 /// <summary>
50 /// Register an instance method as a script call by method name
51 /// </summary>
52 /// <param name="target"></param>
53 /// <param name="method"></param>
49 void RegisterScriptInvocation(object target, string method); 54 void RegisterScriptInvocation(object target, string method);
55
56 /// <summary>
57 /// Register a static or instance method as a script call by method info
58 /// </summary>
59 /// <param name="target">If target is a Type object, will assume method is static.</param>
60 /// <param name="method"></param>
50 void RegisterScriptInvocation(object target, MethodInfo method); 61 void RegisterScriptInvocation(object target, MethodInfo method);
62
63 /// <summary>
64 /// Register one or more instance methods as script calls by method name
65 /// </summary>
66 /// <param name="target"></param>
67 /// <param name="methods"></param>
51 void RegisterScriptInvocation(object target, string[] methods); 68 void RegisterScriptInvocation(object target, string[] methods);
69
70 /// <summary>
71 /// Register one or more static methods as script calls by method name
72 /// </summary>
73 /// <param name="target"></param>
74 /// <param name="methods"></param>
75 void RegisterScriptInvocation(Type target, string[] methods);
76
77 /// <summary>
78 /// Automatically register script invocations by checking for methods
79 /// with <see cref="ScriptInvocationAttribute"/>. Should only check
80 /// public methods.
81 /// </summary>
82 /// <param name="target"></param>
83 void RegisterScriptInvocations(IRegionModuleBase target);
84
85 /// <summary>
86 /// Returns an array of all registered script calls
87 /// </summary>
88 /// <returns></returns>
52 Delegate[] GetScriptInvocationList(); 89 Delegate[] GetScriptInvocationList();
53 90
54 Delegate LookupScriptInvocation(string fname); 91 Delegate LookupScriptInvocation(string fname);
@@ -67,11 +104,43 @@ namespace OpenSim.Region.Framework.Interfaces
67 /// <param name="key"></param> 104 /// <param name="key"></param>
68 void DispatchReply(UUID scriptId, int code, string text, string key); 105 void DispatchReply(UUID scriptId, int code, string text, string key);
69 106
70 /// For constants 107 /// <summary>
108 /// Operation to for a region module to register a constant to be used
109 /// by the script engine
110 /// </summary>
111 /// <param name="cname">
112 /// The name of the constant. LSL convention is for constant names to
113 /// be uppercase.
114 /// </param>
115 /// <param name="value">
116 /// The value of the constant. Should be of a type that can be
117 /// converted to one of <see cref="OpenSim.Region.ScriptEngine.Shared.LSL_Types"/>
118 /// </param>
71 void RegisterConstant(string cname, object value); 119 void RegisterConstant(string cname, object value);
120
121 /// <summary>
122 /// Automatically register all constants on a region module by
123 /// checking for fields with <see cref="ScriptConstantAttribute"/>.
124 /// </summary>
125 /// <param name="target"></param>
126 void RegisterConstants(IRegionModuleBase target);
127
128 /// <summary>
129 /// Operation to check for a registered constant
130 /// </summary>
131 /// <param name="cname">Name of constant</param>
132 /// <returns>Value of constant or null if none found.</returns>
72 object LookupModConstant(string cname); 133 object LookupModConstant(string cname);
73 134
74 // For use ONLY by the script API 135 // For use ONLY by the script API
75 void RaiseEvent(UUID script, string id, string module, string command, string key); 136 void RaiseEvent(UUID script, string id, string module, string command, string key);
76 } 137 }
138
139 [AttributeUsage(AttributeTargets.Method)]
140 public class ScriptInvocationAttribute : Attribute
141 { }
142
143 [AttributeUsage(AttributeTargets.Field)]
144 public class ScriptConstantAttribute : Attribute
145 { }
77} 146}
diff --git a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs
index 457444c..79e9f9d 100644
--- a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs
@@ -39,6 +39,8 @@ namespace OpenSim.Region.Framework.Interfaces
39 UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID); 39 UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID);
40 void ReleaseURL(string url); 40 void ReleaseURL(string url);
41 void HttpResponse(UUID request, int status, string body); 41 void HttpResponse(UUID request, int status, string body);
42 void HttpContentType(UUID request, string type);
43
42 string GetHttpHeader(UUID request, string header); 44 string GetHttpHeader(UUID request, string header);
43 int GetFreeUrls(); 45 int GetFreeUrls();
44 46
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
index 24cd069..f8088c3 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -1,4 +1,31 @@
1using System; 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
2using System.Collections.Generic; 29using System.Collections.Generic;
3 30
4using OpenMetaverse; 31using OpenMetaverse;
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..16c0d25 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -543,7 +543,7 @@ namespace OpenSim.Region.Framework.Scenes
543 if (!InventoryService.AddFolder(folder)) 543 if (!InventoryService.AddFolder(folder))
544 { 544 {
545 m_log.WarnFormat( 545 m_log.WarnFormat(
546 "[AGENT INVENTORY]: Failed to move create folder for user {0} {1}", 546 "[AGENT INVENTORY]: Failed to create folder for user {0} {1}",
547 remoteClient.Name, remoteClient.AgentId); 547 remoteClient.Name, remoteClient.AgentId);
548 } 548 }
549 } 549 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 8034bc6..45d512b 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;
@@ -1290,6 +1364,8 @@ namespace OpenSim.Region.Framework.Scenes
1290 /// </summary> 1364 /// </summary>
1291 public void Start() 1365 public void Start()
1292 { 1366 {
1367 m_active = true;
1368
1293// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1369// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1294 1370
1295 //m_heartbeatTimer.Enabled = true; 1371 //m_heartbeatTimer.Enabled = true;
@@ -1346,7 +1422,7 @@ namespace OpenSim.Region.Framework.Scenes
1346 #region Update Methods 1422 #region Update Methods
1347 1423
1348 /// <summary> 1424 /// <summary>
1349 /// Performs per-frame updates regularly 1425 /// Activate the various loops necessary to continually update the scene.
1350 /// </summary> 1426 /// </summary>
1351 private void Heartbeat() 1427 private void Heartbeat()
1352 { 1428 {
@@ -1403,7 +1479,7 @@ namespace OpenSim.Region.Framework.Scenes
1403 List<Vector3> coarseLocations; 1479 List<Vector3> coarseLocations;
1404 List<UUID> avatarUUIDs; 1480 List<UUID> avatarUUIDs;
1405 1481
1406 while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) 1482 while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun))
1407 { 1483 {
1408 runtc = Util.EnvironmentTickCount(); 1484 runtc = Util.EnvironmentTickCount();
1409 ++MaintenanceRun; 1485 ++MaintenanceRun;
@@ -1465,7 +1541,7 @@ namespace OpenSim.Region.Framework.Scenes
1465 int sleepMS; 1541 int sleepMS;
1466 int framestart; 1542 int framestart;
1467 1543
1468 while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) 1544 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1469 { 1545 {
1470 framestart = Util.EnvironmentTickCount(); 1546 framestart = Util.EnvironmentTickCount();
1471 ++Frame; 1547 ++Frame;
@@ -2182,10 +2258,14 @@ namespace OpenSim.Region.Framework.Scenes
2182 public bool AddRestoredSceneObject( 2258 public bool AddRestoredSceneObject(
2183 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 2259 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
2184 { 2260 {
2185 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 2261 if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates))
2186 if (result) 2262 {
2187 sceneObject.IsDeleted = false; 2263 sceneObject.IsDeleted = false;
2188 return result; 2264 EventManager.TriggerObjectAddedToScene(sceneObject);
2265 return true;
2266 }
2267
2268 return false;
2189 } 2269 }
2190 2270
2191 /// <summary> 2271 /// <summary>
@@ -2826,77 +2906,89 @@ namespace OpenSim.Region.Framework.Scenes
2826 2906
2827 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2907 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
2828 { 2908 {
2909 ScenePresence sp;
2910 bool vialogin;
2911
2829 // Validation occurs in LLUDPServer 2912 // Validation occurs in LLUDPServer
2913 //
2914 // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with
2915 // each other. In practice, this does not currently occur in the code.
2830 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2916 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2831 2917
2832 bool vialogin 2918 // We lock here on AgentCircuitData to prevent a race condition between the thread adding a new connection
2833 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 2919 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point
2834 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2920 // whilst connecting).
2835 2921 //
2836 CheckHeartbeat(); 2922 // It would be easier to lock across all NewUserConnection(), AddNewClient() and
2837 2923 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
2838 ScenePresence sp = GetScenePresence(client.AgentId); 2924 // response in some module listening to AddNewClient()) from holding up unrelated agent calls.
2839 2925 //
2840 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2926 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all
2841 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause 2927 // AddNewClient() operations (though not other ops).
2842 // other problems, and possible the code calling AddNewClient() should ensure that no client is already 2928 // In the future this can be relieved once locking per agent (not necessarily on AgentCircuitData) is improved.
2843 // connected. 2929 lock (aCircuit)
2844 if (sp == null) 2930 {
2845 { 2931 vialogin
2846 m_log.DebugFormat( 2932 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2847 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 2933 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2848 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); 2934
2849 2935 CheckHeartbeat();
2850 m_clientManager.Add(client); 2936
2851 SubscribeToClientEvents(client); 2937 sp = GetScenePresence(client.AgentId);
2852
2853 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2854 m_eventManager.TriggerOnNewPresence(sp);
2855
2856 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2857 2938
2858 // The first agent upon login is a root agent by design. 2939 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
2859 // For this agent we will have to rez the attachments. 2940 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause
2860 // All other AddNewClient calls find aCircuit.child to be true. 2941 // other problems, and possible the code calling AddNewClient() should ensure that no client is already
2861 if (aCircuit.child == false) 2942 // connected.
2943 if (sp == null)
2862 { 2944 {
2863 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to 2945 m_log.DebugFormat(
2864 // start the scripts again (since this is done in RezAttachments()). 2946 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2865 // XXX: This is convoluted. 2947 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2866 sp.IsChildAgent = false; 2948
2867 2949 m_clientManager.Add(client);
2868 if (AttachmentsModule != null) 2950 SubscribeToClientEvents(client);
2869 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); 2951
2952 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2953 m_eventManager.TriggerOnNewPresence(sp);
2954
2955 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2956
2957 // The first agent upon login is a root agent by design.
2958 // For this agent we will have to rez the attachments.
2959 // All other AddNewClient calls find aCircuit.child to be true.
2960 if (aCircuit.child == false)
2961 {
2962 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to
2963 // start the scripts again (since this is done in RezAttachments()).
2964 // XXX: This is convoluted.
2965 sp.IsChildAgent = false;
2966
2967 if (AttachmentsModule != null)
2968 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
2969 }
2870 } 2970 }
2871 } 2971 else
2872 else 2972 {
2873 { 2973 m_log.WarnFormat(
2874 m_log.WarnFormat( 2974 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2875 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 2975 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2876 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2976 }
2877 } 2977
2978 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2979 // client is for a root or child agent.
2980 client.SceneAgent = sp;
2878 2981
2879 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 2982 // Cache the user's name
2880 // client is for a root or child agent. 2983 CacheUserName(sp, aCircuit);
2881 client.SceneAgent = sp; 2984
2985 EventManager.TriggerOnNewClient(client);
2986 if (vialogin)
2987 EventManager.TriggerOnClientLogin(client);
2988 }
2882 2989
2883 m_LastLogin = Util.EnvironmentTickCount(); 2990 m_LastLogin = Util.EnvironmentTickCount();
2884 2991
2885 // Cache the user's name
2886 CacheUserName(sp, aCircuit);
2887
2888 EventManager.TriggerOnNewClient(client);
2889 if (vialogin)
2890 {
2891 EventManager.TriggerOnClientLogin(client);
2892 // Send initial parcel data
2893/* this is done on TriggerOnNewClient by landmanegement respective event handler
2894 Vector3 pos = sp.AbsolutePosition;
2895 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2896 land.SendLandUpdateToClient(client);
2897*/
2898 }
2899
2900 return sp; 2992 return sp;
2901 } 2993 }
2902 2994
@@ -3436,110 +3528,130 @@ namespace OpenSim.Region.Framework.Scenes
3436 { 3528 {
3437// CheckHeartbeat(); 3529// CheckHeartbeat();
3438 bool isChildAgent = false; 3530 bool isChildAgent = false;
3439 ScenePresence avatar = GetScenePresence(agentID); 3531 AgentCircuitData acd;
3440
3441 if (avatar == null)
3442 {
3443 m_log.WarnFormat(
3444 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3445
3446 return;
3447 }
3448 3532
3449 try 3533 lock (m_removeClientLock)
3450 { 3534 {
3451 isChildAgent = avatar.IsChildAgent; 3535 acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3452
3453 m_log.DebugFormat(
3454 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3455 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3456 3536
3457 // Don't do this to root agents, it's not nice for the viewer 3537 if (acd == null)
3458 if (closeChildAgents && isChildAgent)
3459 { 3538 {
3460 // Tell a single agent to disconnect from the region. 3539 m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID);
3461 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3540 return;
3462 if (eq != null)
3463 {
3464 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3465 }
3466 else
3467 {
3468 avatar.ControllingClient.SendShutdownConnectionNotice();
3469 }
3470 } 3541 }
3471 3542 else
3472 // Only applies to root agents.
3473 if (avatar.ParentID != 0)
3474 { 3543 {
3475 avatar.StandUp(); 3544 // We remove the acd up here to avoid later raec conditions if two RemoveClient() calls occurred
3545 // simultaneously.
3546 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3476 } 3547 }
3548 }
3477 3549
3478 m_sceneGraph.removeUserCount(!isChildAgent); 3550 lock (acd)
3479 3551 {
3480 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3552 ScenePresence avatar = GetScenePresence(agentID);
3481 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3553
3482 if (closeChildAgents && CapsModule != null) 3554 if (avatar == null)
3483 CapsModule.RemoveCaps(agentID);
3484
3485 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3486 // this method is doing is HORRIBLE!!!
3487 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3488
3489 if (closeChildAgents && !isChildAgent)
3490 { 3555 {
3491 List<ulong> regions = avatar.KnownRegionHandles; 3556 m_log.WarnFormat(
3492 regions.Remove(RegionInfo.RegionHandle); 3557 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3493 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3558
3559 return;
3494 } 3560 }
3495 3561
3496 m_eventManager.TriggerClientClosed(agentID, this); 3562 try
3497 m_eventManager.TriggerOnRemovePresence(agentID);
3498
3499 if (!isChildAgent)
3500 { 3563 {
3501 if (AttachmentsModule != null) 3564 isChildAgent = avatar.IsChildAgent;
3565
3566 m_log.DebugFormat(
3567 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3568 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3569
3570 // Don't do this to root agents, it's not nice for the viewer
3571 if (closeChildAgents && isChildAgent)
3502 { 3572 {
3503 AttachmentsModule.DeRezAttachments(avatar); 3573 // Tell a single agent to disconnect from the region.
3574 IEventQueue eq = RequestModuleInterface<IEventQueue>();
3575 if (eq != null)
3576 {
3577 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3578 }
3579 else
3580 {
3581 avatar.ControllingClient.SendShutdownConnectionNotice();
3582 }
3504 } 3583 }
3505 3584
3506 ForEachClient( 3585 // Only applies to root agents.
3507 delegate(IClientAPI client) 3586 if (avatar.ParentID != 0)
3587 {
3588 avatar.StandUp();
3589 }
3590
3591 m_sceneGraph.removeUserCount(!isChildAgent);
3592
3593 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3594 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3595 if (closeChildAgents && CapsModule != null)
3596 CapsModule.RemoveCaps(agentID);
3597
3598 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3599 // this method is doing is HORRIBLE!!!
3600 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3601
3602 if (closeChildAgents && !isChildAgent)
3603 {
3604 List<ulong> regions = avatar.KnownRegionHandles;
3605 regions.Remove(RegionInfo.RegionHandle);
3606 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3607 }
3608
3609 m_eventManager.TriggerClientClosed(agentID, this);
3610 m_eventManager.TriggerOnRemovePresence(agentID);
3611
3612 if (!isChildAgent)
3613 {
3614 if (AttachmentsModule != null)
3508 { 3615 {
3509 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3616 AttachmentsModule.DeRezAttachments(avatar);
3510 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3617 }
3511 catch (NullReferenceException) { }
3512 });
3513 }
3514
3515 // It's possible for child agents to have transactions if changes are being made cross-border.
3516 if (AgentTransactionsModule != null)
3517 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3518 3618
3519 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3619 ForEachClient(
3520 m_log.Debug("[Scene] The avatar has left the building"); 3620 delegate(IClientAPI client)
3521 } 3621 {
3522 catch (Exception e) 3622 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3523 { 3623 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3524 m_log.Error( 3624 catch (NullReferenceException) { }
3525 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); 3625 });
3526 } 3626 }
3527 finally
3528 {
3529 try
3530 {
3531 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3532 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3533 // the same cleanup exception continually.
3534 m_sceneGraph.RemoveScenePresence(agentID);
3535 m_clientManager.Remove(agentID);
3536 3627
3537 avatar.Close(); 3628 // It's possible for child agents to have transactions if changes are being made cross-border.
3629 if (AgentTransactionsModule != null)
3630 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3631 m_log.Debug("[Scene] The avatar has left the building");
3538 } 3632 }
3539 catch (Exception e) 3633 catch (Exception e)
3540 { 3634 {
3541 m_log.Error( 3635 m_log.Error(
3542 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); 3636 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e);
3637 }
3638 finally
3639 {
3640 try
3641 {
3642 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3643 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3644 // the same cleanup exception continually.
3645 m_sceneGraph.RemoveScenePresence(agentID);
3646 m_clientManager.Remove(agentID);
3647
3648 avatar.Close();
3649 }
3650 catch (Exception e)
3651 {
3652 m_log.Error(
3653 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e);
3654 }
3543 } 3655 }
3544 } 3656 }
3545 3657
@@ -3598,11 +3710,9 @@ namespace OpenSim.Region.Framework.Scenes
3598 3710
3599 /// <summary> 3711 /// <summary>
3600 /// Do the work necessary to initiate a new user connection for a particular scene. 3712 /// Do the work necessary to initiate a new user connection for a particular scene.
3601 /// At the moment, this consists of setting up the caps infrastructure
3602 /// The return bool should allow for connections to be refused, but as not all calling paths
3603 /// take proper notice of it let, we allowed banned users in still.
3604 /// </summary> 3713 /// </summary>
3605 /// <param name="agent">CircuitData of the agent who is connecting</param> 3714 /// <param name="agent">CircuitData of the agent who is connecting</param>
3715 /// <param name="teleportFlags"></param>
3606 /// <param name="reason">Outputs the reason for the false response on this string</param> 3716 /// <param name="reason">Outputs the reason for the false response on this string</param>
3607 /// <returns>True if the region accepts this agent. False if it does not. False will 3717 /// <returns>True if the region accepts this agent. False if it does not. False will
3608 /// also return a reason.</returns> 3718 /// also return a reason.</returns>
@@ -3613,10 +3723,20 @@ namespace OpenSim.Region.Framework.Scenes
3613 3723
3614 /// <summary> 3724 /// <summary>
3615 /// Do the work necessary to initiate a new user connection for a particular scene. 3725 /// Do the work necessary to initiate a new user connection for a particular scene.
3616 /// At the moment, this consists of setting up the caps infrastructure 3726 /// </summary>
3727 /// <remarks>
3728 /// The return bool should allow for connections to be refused, but as not all calling paths
3729 /// take proper notice of it yet, we still allowed banned users in.
3730 ///
3731 /// At the moment this method consists of setting up the caps infrastructure
3617 /// The return bool should allow for connections to be refused, but as not all calling paths 3732 /// The return bool should allow for connections to be refused, but as not all calling paths
3618 /// take proper notice of it let, we allowed banned users in still. 3733 /// take proper notice of it let, we allowed banned users in still.
3619 /// </summary> 3734 ///
3735 /// This method is called by the login service (in the case of login) or another simulator (in the case of region
3736 /// cross or teleport) to initiate the connection. It is not triggered by the viewer itself - the connection
3737 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
3738 /// the LLUDP stack).
3739 /// </remarks>
3620 /// <param name="agent">CircuitData of the agent who is connecting</param> 3740 /// <param name="agent">CircuitData of the agent who is connecting</param>
3621 /// <param name="reason">Outputs the reason for the false response on this string</param> 3741 /// <param name="reason">Outputs the reason for the false response on this string</param>
3622 /// <param name="requirePresenceLookup">True for normal presence. False for NPC 3742 /// <param name="requirePresenceLookup">True for normal presence. False for NPC
@@ -3715,83 +3835,86 @@ namespace OpenSim.Region.Framework.Scenes
3715 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3835 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3716 sp.Name, sp.UUID, RegionInfo.RegionName); 3836 sp.Name, sp.UUID, RegionInfo.RegionName);
3717 3837
3718 sp.ControllingClient.Close(); 3838 sp.ControllingClient.Close(true, true);
3719 sp = null; 3839 sp = null;
3720 } 3840 }
3721 3841
3722 3842 lock (agent)
3723 //On login test land permisions
3724 if (vialogin)
3725 { 3843 {
3726 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); 3844 //On login test land permisions
3727 if (cache != null) 3845 if (vialogin)
3728 cache.Remove(agent.firstname + " " + agent.lastname);
3729 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3730 { 3846 {
3731 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); 3847 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3732 return false; 3848 if (cache != null)
3849 cache.Remove(agent.firstname + " " + agent.lastname);
3850 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3851 {
3852 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3853 return false;
3854 }
3733 } 3855 }
3734 }
3735 3856
3736 if (sp == null) // We don't have an [child] agent here already 3857 if (sp == null) // We don't have an [child] agent here already
3737 {
3738 if (requirePresenceLookup)
3739 { 3858 {
3740 try 3859 if (requirePresenceLookup)
3741 { 3860 {
3742 if (!VerifyUserPresence(agent, out reason)) 3861 try
3862 {
3863 if (!VerifyUserPresence(agent, out reason))
3864 return false;
3865 } catch (Exception e)
3866 {
3867 m_log.ErrorFormat(
3868 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3743 return false; 3869 return false;
3744 } catch (Exception e) 3870 }
3871 }
3872
3873 try
3874 {
3875 // Always check estate if this is a login. Always
3876 // check if banned regions are to be blacked out.
3877 if (vialogin || (!m_seeIntoBannedRegion))
3878 {
3879 if (!AuthorizeUser(agent, out reason))
3880 return false;
3881 }
3882 }
3883 catch (Exception e)
3745 { 3884 {
3746 m_log.ErrorFormat( 3885 m_log.ErrorFormat(
3747 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3886 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
3748 return false; 3887 return false;
3749 } 3888 }
3750 }
3751 3889
3752 try 3890 m_log.InfoFormat(
3753 { 3891 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3754 // Always check estate if this is a login. Always 3892 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3755 // check if banned regions are to be blacked out. 3893 agent.AgentID, agent.circuitcode);
3756 if (vialogin || (!m_seeIntoBannedRegion)) 3894
3895 if (CapsModule != null)
3757 { 3896 {
3758 if (!AuthorizeUser(agent, out reason)) 3897 CapsModule.SetAgentCapsSeeds(agent);
3759 return false; 3898 CapsModule.CreateCaps(agent.AgentID);
3760 } 3899 }
3761 } 3900 }
3762 catch (Exception e) 3901 else
3763 { 3902 {
3764 m_log.ErrorFormat( 3903 // Let the SP know how we got here. This has a lot of interesting
3765 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); 3904 // uses down the line.
3766 return false; 3905 sp.TeleportFlags = (TPFlags)teleportFlags;
3767 }
3768
3769 m_log.InfoFormat(
3770 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3771 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3772 agent.AgentID, agent.circuitcode);
3773 3906
3774 if (CapsModule != null) 3907 if (sp.IsChildAgent)
3775 { 3908 {
3776 CapsModule.SetAgentCapsSeeds(agent); 3909 m_log.DebugFormat(
3777 CapsModule.CreateCaps(agent.AgentID); 3910 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3778 } 3911 agent.AgentID, RegionInfo.RegionName);
3779 } else
3780 {
3781 // Let the SP know how we got here. This has a lot of interesting
3782 // uses down the line.
3783 sp.TeleportFlags = (TPFlags)teleportFlags;
3784 3912
3785 if (sp.IsChildAgent) 3913 sp.AdjustKnownSeeds();
3786 {
3787 m_log.DebugFormat(
3788 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3789 agent.AgentID, RegionInfo.RegionName);
3790 3914
3791 sp.AdjustKnownSeeds(); 3915 if (CapsModule != null)
3792 3916 CapsModule.SetAgentCapsSeeds(agent);
3793 if (CapsModule != null) 3917 }
3794 CapsModule.SetAgentCapsSeeds(agent);
3795 } 3918 }
3796 } 3919 }
3797 3920
@@ -4222,8 +4345,9 @@ namespace OpenSim.Region.Framework.Scenes
4222 return false; 4345 return false;
4223 } 4346 }
4224 4347
4225 // We have to wait until the viewer contacts this region after receiving EAC. 4348 // We have to wait until the viewer contacts this region
4226 // That calls AddNewClient, which finally creates the ScenePresence 4349 // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send
4350 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence.
4227 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4351 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
4228 4352
4229 if (childAgentUpdate != null) 4353 if (childAgentUpdate != null)
@@ -4318,15 +4442,18 @@ namespace OpenSim.Region.Framework.Scenes
4318 /// Tell a single agent to disconnect from the region. 4442 /// Tell a single agent to disconnect from the region.
4319 /// </summary> 4443 /// </summary>
4320 /// <param name="agentID"></param> 4444 /// <param name="agentID"></param>
4321 /// <param name="childOnly"></param> 4445 /// <param name="force">
4322 public bool IncomingCloseAgent(UUID agentID, bool childOnly) 4446 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4447 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4448 /// </param>
4449 public bool IncomingCloseAgent(UUID agentID, bool force)
4323 { 4450 {
4324 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4451 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
4325 4452
4326 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4453 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4327 if (presence != null) 4454 if (presence != null)
4328 { 4455 {
4329 presence.ControllingClient.Close(false); 4456 presence.ControllingClient.Close(force, force);
4330 return true; 4457 return true;
4331 } 4458 }
4332 4459
@@ -4532,6 +4659,16 @@ namespace OpenSim.Region.Framework.Scenes
4532 return LandChannel.GetLandObject(x, y).LandData; 4659 return LandChannel.GetLandObject(x, y).LandData;
4533 } 4660 }
4534 4661
4662 /// <summary>
4663 /// Get LandData by position.
4664 /// </summary>
4665 /// <param name="pos"></param>
4666 /// <returns></returns>
4667 public LandData GetLandData(Vector3 pos)
4668 {
4669 return GetLandData(pos.X, pos.Y);
4670 }
4671
4535 public LandData GetLandData(uint x, uint y) 4672 public LandData GetLandData(uint x, uint y)
4536 { 4673 {
4537 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); 4674 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
@@ -4780,6 +4917,18 @@ namespace OpenSim.Region.Framework.Scenes
4780 } 4917 }
4781 4918
4782 /// <summary> 4919 /// <summary>
4920 /// Attempt to get the SOG via its UUID
4921 /// </summary>
4922 /// <param name="fullID"></param>
4923 /// <param name="sog"></param>
4924 /// <returns></returns>
4925 public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog)
4926 {
4927 sog = GetSceneObjectGroup(fullID);
4928 return sog != null;
4929 }
4930
4931 /// <summary>
4783 /// Get a prim by name from the scene (will return the first 4932 /// Get a prim by name from the scene (will return the first
4784 /// 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)
4785 /// </summary> 4934 /// </summary>
@@ -4811,6 +4960,18 @@ namespace OpenSim.Region.Framework.Scenes
4811 } 4960 }
4812 4961
4813 /// <summary> 4962 /// <summary>
4963 /// Attempt to get a prim via its UUID
4964 /// </summary>
4965 /// <param name="fullID"></param>
4966 /// <param name="sop"></param>
4967 /// <returns></returns>
4968 public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop)
4969 {
4970 sop = GetSceneObjectPart(fullID);
4971 return sop != null;
4972 }
4973
4974 /// <summary>
4814 /// Get a scene object group that contains the prim with the given local id 4975 /// Get a scene object group that contains the prim with the given local id
4815 /// </summary> 4976 /// </summary>
4816 /// <param name="localID"></param> 4977 /// <param name="localID"></param>
@@ -5865,6 +6026,9 @@ Environment.Exit(1);
5865 6026
5866 public string GetExtraSetting(string name) 6027 public string GetExtraSetting(string name)
5867 { 6028 {
6029 if (m_extraSettings == null)
6030 return String.Empty;
6031
5868 string val; 6032 string val;
5869 6033
5870 if (!m_extraSettings.TryGetValue(name, out val)) 6034 if (!m_extraSettings.TryGetValue(name, out val))
@@ -5875,6 +6039,9 @@ Environment.Exit(1);
5875 6039
5876 public void StoreExtraSetting(string name, string val) 6040 public void StoreExtraSetting(string name, string val)
5877 { 6041 {
6042 if (m_extraSettings == null)
6043 return;
6044
5878 string oldVal; 6045 string oldVal;
5879 6046
5880 if (m_extraSettings.TryGetValue(name, out oldVal)) 6047 if (m_extraSettings.TryGetValue(name, out oldVal))
@@ -5892,6 +6059,9 @@ Environment.Exit(1);
5892 6059
5893 public void RemoveExtraSetting(string name) 6060 public void RemoveExtraSetting(string name)
5894 { 6061 {
6062 if (m_extraSettings == null)
6063 return;
6064
5895 if (!m_extraSettings.ContainsKey(name)) 6065 if (!m_extraSettings.ContainsKey(name))
5896 return; 6066 return;
5897 6067
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index af13b46..1beb584 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 }
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 5bd0a1b..782a1af 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2742,6 +2742,25 @@ namespace OpenSim.Region.Framework.Scenes
2742 if (objectGroup == this) 2742 if (objectGroup == this)
2743 return; 2743 return;
2744 2744
2745 // If the configured linkset capacity is greater than zero,
2746 // and the new linkset would have a prim count higher than this
2747 // value, do not link it.
2748 if (m_scene.m_linksetCapacity > 0 &&
2749 (PrimCount + objectGroup.PrimCount) >
2750 m_scene.m_linksetCapacity)
2751 {
2752 m_log.DebugFormat(
2753 "[SCENE OBJECT GROUP]: Cannot link group with root" +
2754 " part {0}, {1} ({2} prims) to group with root part" +
2755 " {3}, {4} ({5} prims) because the new linkset" +
2756 " would exceed the configured maximum of {6}",
2757 objectGroup.RootPart.Name, objectGroup.RootPart.UUID,
2758 objectGroup.PrimCount, RootPart.Name, RootPart.UUID,
2759 PrimCount, m_scene.m_linksetCapacity);
2760
2761 return;
2762 }
2763
2745 // 'linkPart' == the root of the group being linked into this group 2764 // 'linkPart' == the root of the group being linked into this group
2746 SceneObjectPart linkPart = objectGroup.m_rootPart; 2765 SceneObjectPart linkPart = objectGroup.m_rootPart;
2747 2766
@@ -3479,27 +3498,33 @@ namespace OpenSim.Region.Framework.Scenes
3479 /// <param name="scale"></param> 3498 /// <param name="scale"></param>
3480 public void GroupResize(Vector3 scale) 3499 public void GroupResize(Vector3 scale)
3481 { 3500 {
3482 scale.X = Math.Min(scale.X, Scene.m_maxNonphys); 3501// m_log.DebugFormat(
3483 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); 3502// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
3484 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
3485 3503
3486 PhysicsActor pa = m_rootPart.PhysActor; 3504 PhysicsActor pa = m_rootPart.PhysActor;
3487 3505
3488 if (pa != null && pa.IsPhysical) 3506 if (Scene != null)
3489 { 3507 {
3490 scale.X = Math.Min(scale.X, Scene.m_maxPhys); 3508 scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X));
3491 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); 3509 scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y));
3492 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); 3510 scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z));
3511
3512 if (pa != null && pa.IsPhysical)
3513 {
3514 scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X));
3515 scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y));
3516 scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z));
3517 }
3493 } 3518 }
3494 3519
3495 float x = (scale.X / RootPart.Scale.X); 3520 float x = (scale.X / RootPart.Scale.X);
3496 float y = (scale.Y / RootPart.Scale.Y); 3521 float y = (scale.Y / RootPart.Scale.Y);
3497 float z = (scale.Z / RootPart.Scale.Z); 3522 float z = (scale.Z / RootPart.Scale.Z);
3498 3523
3499 SceneObjectPart[] parts; 3524 SceneObjectPart[] parts = m_parts.GetArray();
3500 if (x > 1.0f || y > 1.0f || z > 1.0f) 3525
3526 if (Scene != null & (x > 1.0f || y > 1.0f || z > 1.0f))
3501 { 3527 {
3502 parts = m_parts.GetArray();
3503 for (int i = 0; i < parts.Length; i++) 3528 for (int i = 0; i < parts.Length; i++)
3504 { 3529 {
3505 SceneObjectPart obPart = parts[i]; 3530 SceneObjectPart obPart = parts[i];
@@ -3512,7 +3537,7 @@ namespace OpenSim.Region.Framework.Scenes
3512 3537
3513 if (pa != null && pa.IsPhysical) 3538 if (pa != null && pa.IsPhysical)
3514 { 3539 {
3515 if (oldSize.X * x > m_scene.m_maxPhys) 3540 if (oldSize.X * x > Scene.m_maxPhys)
3516 { 3541 {
3517 f = m_scene.m_maxPhys / oldSize.X; 3542 f = m_scene.m_maxPhys / oldSize.X;
3518 a = f / x; 3543 a = f / x;
@@ -3520,8 +3545,16 @@ namespace OpenSim.Region.Framework.Scenes
3520 y *= a; 3545 y *= a;
3521 z *= a; 3546 z *= a;
3522 } 3547 }
3548 else if (oldSize.X * x < Scene.m_minPhys)
3549 {
3550 f = m_scene.m_minPhys / oldSize.X;
3551 a = f / x;
3552 x *= a;
3553 y *= a;
3554 z *= a;
3555 }
3523 3556
3524 if (oldSize.Y * y > m_scene.m_maxPhys) 3557 if (oldSize.Y * y > Scene.m_maxPhys)
3525 { 3558 {
3526 f = m_scene.m_maxPhys / oldSize.Y; 3559 f = m_scene.m_maxPhys / oldSize.Y;
3527 a = f / y; 3560 a = f / y;
@@ -3529,8 +3562,16 @@ namespace OpenSim.Region.Framework.Scenes
3529 y *= a; 3562 y *= a;
3530 z *= a; 3563 z *= a;
3531 } 3564 }
3565 else if (oldSize.Y * y < Scene.m_minPhys)
3566 {
3567 f = m_scene.m_minPhys / oldSize.Y;
3568 a = f / y;
3569 x *= a;
3570 y *= a;
3571 z *= a;
3572 }
3532 3573
3533 if (oldSize.Z * z > m_scene.m_maxPhys) 3574 if (oldSize.Z * z > Scene.m_maxPhys)
3534 { 3575 {
3535 f = m_scene.m_maxPhys / oldSize.Z; 3576 f = m_scene.m_maxPhys / oldSize.Z;
3536 a = f / z; 3577 a = f / z;
@@ -3538,10 +3579,18 @@ namespace OpenSim.Region.Framework.Scenes
3538 y *= a; 3579 y *= a;
3539 z *= a; 3580 z *= a;
3540 } 3581 }
3582 else if (oldSize.Z * z < Scene.m_minPhys)
3583 {
3584 f = m_scene.m_minPhys / oldSize.Z;
3585 a = f / z;
3586 x *= a;
3587 y *= a;
3588 z *= a;
3589 }
3541 } 3590 }
3542 else 3591 else
3543 { 3592 {
3544 if (oldSize.X * x > m_scene.m_maxNonphys) 3593 if (oldSize.X * x > Scene.m_maxNonphys)
3545 { 3594 {
3546 f = m_scene.m_maxNonphys / oldSize.X; 3595 f = m_scene.m_maxNonphys / oldSize.X;
3547 a = f / x; 3596 a = f / x;
@@ -3549,8 +3598,16 @@ namespace OpenSim.Region.Framework.Scenes
3549 y *= a; 3598 y *= a;
3550 z *= a; 3599 z *= a;
3551 } 3600 }
3601 else if (oldSize.X * x < Scene.m_minNonphys)
3602 {
3603 f = m_scene.m_minNonphys / oldSize.X;
3604 a = f / x;
3605 x *= a;
3606 y *= a;
3607 z *= a;
3608 }
3552 3609
3553 if (oldSize.Y * y > m_scene.m_maxNonphys) 3610 if (oldSize.Y * y > Scene.m_maxNonphys)
3554 { 3611 {
3555 f = m_scene.m_maxNonphys / oldSize.Y; 3612 f = m_scene.m_maxNonphys / oldSize.Y;
3556 a = f / y; 3613 a = f / y;
@@ -3558,8 +3615,16 @@ namespace OpenSim.Region.Framework.Scenes
3558 y *= a; 3615 y *= a;
3559 z *= a; 3616 z *= a;
3560 } 3617 }
3618 else if (oldSize.Y * y < Scene.m_minNonphys)
3619 {
3620 f = m_scene.m_minNonphys / oldSize.Y;
3621 a = f / y;
3622 x *= a;
3623 y *= a;
3624 z *= a;
3625 }
3561 3626
3562 if (oldSize.Z * z > m_scene.m_maxNonphys) 3627 if (oldSize.Z * z > Scene.m_maxNonphys)
3563 { 3628 {
3564 f = m_scene.m_maxNonphys / oldSize.Z; 3629 f = m_scene.m_maxNonphys / oldSize.Z;
3565 a = f / z; 3630 a = f / z;
@@ -3567,6 +3632,14 @@ namespace OpenSim.Region.Framework.Scenes
3567 y *= a; 3632 y *= a;
3568 z *= a; 3633 z *= a;
3569 } 3634 }
3635 else if (oldSize.Z * z < Scene.m_minNonphys)
3636 {
3637 f = m_scene.m_minNonphys / oldSize.Z;
3638 a = f / z;
3639 x *= a;
3640 y *= a;
3641 z *= a;
3642 }
3570 } 3643 }
3571 } 3644 }
3572 } 3645 }
@@ -3579,7 +3652,6 @@ namespace OpenSim.Region.Framework.Scenes
3579 3652
3580 RootPart.Resize(prevScale); 3653 RootPart.Resize(prevScale);
3581 3654
3582 parts = m_parts.GetArray();
3583 for (int i = 0; i < parts.Length; i++) 3655 for (int i = 0; i < parts.Length; i++)
3584 { 3656 {
3585 SceneObjectPart obPart = parts[i]; 3657 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/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index a8aa551..adb3d38 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -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 {
@@ -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..0d359b9 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,22 @@ 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 " frames",
250 "scene",
251 m_scene.Name,
252 StatVerbosity.Info,
253 "Number of frames where frame time has been significantly longer than the desired frame time.");
254
255 StatsManager.RegisterStat(SlowFramesStat);
229 } 256 }
230 257
231 public void Close() 258 public void Close()
@@ -443,6 +470,7 @@ namespace OpenSim.Region.Framework.Scenes
443 lock (m_lastReportedExtraSimStats) 470 lock (m_lastReportedExtraSimStats)
444 { 471 {
445 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor; 472 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor;
473 m_lastReportedExtraSimStats[SlowFramesStat.ShortName] = (float)SlowFramesStat.Value;
446 474
447 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats(); 475 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
448 476
@@ -563,6 +591,11 @@ namespace OpenSim.Region.Framework.Scenes
563 public void addFrameMS(int ms) 591 public void addFrameMS(int ms)
564 { 592 {
565 m_frameMS += ms; 593 m_frameMS += ms;
594
595 // At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
596 // longer than ideal due to the inaccuracy of the Sleep in Scene.Update() (which in itself is a concern).
597 if (ms > SlowFramesStatReportThreshold)
598 SlowFramesStat.Value++;
566 } 599 }
567 600
568 public void addNetMS(int ms) 601 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/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..b5ef7b0 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 assetCache)
73 { 70 {
74 m_assetCache = assetCache; 71 m_assetService = assetCache;
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}