diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
38 files changed, 1869 insertions, 434 deletions
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs index 2027ca6..30e99b0 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs | |||
@@ -26,9 +26,11 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Threading; | ||
29 | using OpenMetaverse; | 30 | using OpenMetaverse; |
30 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
31 | using OpenSim.Region.Framework.Scenes; | 32 | using OpenSim.Region.Framework.Scenes; |
33 | using OpenSim.Region.ScriptEngine.Shared; | ||
32 | 34 | ||
33 | namespace OpenSim.Region.ScriptEngine.Interfaces | 35 | namespace OpenSim.Region.ScriptEngine.Interfaces |
34 | { | 36 | { |
@@ -38,11 +40,12 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
38 | /// Initialize the API | 40 | /// Initialize the API |
39 | /// </summary> | 41 | /// </summary> |
40 | /// <remarks> | 42 | /// <remarks> |
41 | /// Each API has an identifier, which is used to load the | 43 | /// Each API has an identifier, which is used to load the proper runtime assembly at load time. |
42 | /// proper runtime assembly at load time. | 44 | /// <param name='scriptEngine'>/param> |
43 | /// <param name='engine'>/param> | 45 | /// <param name='host'>/param> |
44 | /// <param name='part'></param> | 46 | /// <param name='item'>/param> |
45 | /// <param name='item'></param> | 47 | /// <param name='coopSleepHandle'>/param> |
46 | void Initialize(IScriptEngine engine, SceneObjectPart part, TaskInventoryItem item); | 48 | void Initialize( |
49 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle); | ||
47 | } | 50 | } |
48 | } \ No newline at end of file | 51 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs index 17c2708..b8fdd01 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs | |||
@@ -25,16 +25,17 @@ | |||
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 | ||
28 | using log4net; | ||
29 | using System; | 28 | using System; |
30 | using OpenSim.Region.ScriptEngine.Shared; | 29 | using System.Reflection; |
30 | using OpenSim.Framework; | ||
31 | using OpenSim.Region.Framework.Scenes; | 31 | using OpenSim.Region.Framework.Scenes; |
32 | using OpenSim.Region.Framework.Interfaces; | 32 | using OpenSim.Region.Framework.Interfaces; |
33 | using OpenMetaverse; | ||
34 | using Nini.Config; | ||
35 | using OpenSim.Region.ScriptEngine.Interfaces; | 33 | using OpenSim.Region.ScriptEngine.Interfaces; |
34 | using OpenSim.Region.ScriptEngine.Shared; | ||
36 | using Amib.Threading; | 35 | using Amib.Threading; |
37 | using OpenSim.Framework; | 36 | using log4net; |
37 | using Nini.Config; | ||
38 | using OpenMetaverse; | ||
38 | 39 | ||
39 | namespace OpenSim.Region.ScriptEngine.Interfaces | 40 | namespace OpenSim.Region.ScriptEngine.Interfaces |
40 | { | 41 | { |
@@ -76,6 +77,38 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
76 | IConfigSource ConfigSource { get; } | 77 | IConfigSource ConfigSource { get; } |
77 | string ScriptEngineName { get; } | 78 | string ScriptEngineName { get; } |
78 | string ScriptEnginePath { get; } | 79 | string ScriptEnginePath { get; } |
80 | |||
81 | /// <summary> | ||
82 | /// Return the name of the class that will be used for all running scripts. | ||
83 | /// </summary> | ||
84 | /// <remarks> | ||
85 | /// Each class goes in its own assembly so we don't need to otherwise distinguish the class name. | ||
86 | /// </remarks> | ||
87 | string ScriptClassName { get; } | ||
88 | |||
89 | /// <summary> | ||
90 | /// Return the name of the base class that will be used for all running scripts. | ||
91 | /// </summary> | ||
92 | string ScriptBaseClassName { get; } | ||
93 | |||
94 | /// <summary> | ||
95 | /// Assemblies that need to be referenced when compiling scripts. | ||
96 | /// </summary> | ||
97 | /// <remarks> | ||
98 | /// These are currently additional to those always referenced by the compiler, BUT THIS MAY CHANGE IN THE | ||
99 | /// FUTURE. | ||
100 | /// This can be null if there are no additional assemblies. | ||
101 | /// </remarks> | ||
102 | string[] ScriptReferencedAssemblies { get; } | ||
103 | |||
104 | /// <summary> | ||
105 | /// Parameters for the generated script's constructor. | ||
106 | /// </summary> | ||
107 | /// <remarks> | ||
108 | /// Can be null if there are no parameters | ||
109 | /// </remarks> | ||
110 | ParameterInfo[] ScriptBaseClassParameters { get; } | ||
111 | |||
79 | IScriptApi GetApi(UUID itemID, string name); | 112 | IScriptApi GetApi(UUID itemID, string name); |
80 | } | 113 | } |
81 | } | 114 | } |
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index b04f6b6..f68612c 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | |||
@@ -28,9 +28,11 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Threading; | ||
31 | using OpenMetaverse; | 32 | using OpenMetaverse; |
32 | using log4net; | 33 | using log4net; |
33 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.Framework.Scenes; | ||
34 | using OpenSim.Region.ScriptEngine.Shared; | 36 | using OpenSim.Region.ScriptEngine.Shared; |
35 | using OpenSim.Region.ScriptEngine.Interfaces; | 37 | using OpenSim.Region.ScriptEngine.Interfaces; |
36 | 38 | ||
@@ -59,6 +61,18 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
59 | public interface IScriptInstance | 61 | public interface IScriptInstance |
60 | { | 62 | { |
61 | /// <summary> | 63 | /// <summary> |
64 | /// Debug level for this script instance. | ||
65 | /// </summary> | ||
66 | /// <remarks> | ||
67 | /// Level == 0, no extra data is logged. | ||
68 | /// Level >= 1, state changes are logged. | ||
69 | /// Level >= 2, event firing is logged. | ||
70 | /// <value> | ||
71 | /// The debug level. | ||
72 | /// </value> | ||
73 | int DebugLevel { get; set; } | ||
74 | |||
75 | /// <summary> | ||
62 | /// Is the script currently running? | 76 | /// Is the script currently running? |
63 | /// </summary> | 77 | /// </summary> |
64 | bool Running { get; set; } | 78 | bool Running { get; set; } |
@@ -93,6 +107,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
93 | /// </summary> | 107 | /// </summary> |
94 | long MeasurementPeriodExecutionTime { get; } | 108 | long MeasurementPeriodExecutionTime { get; } |
95 | 109 | ||
110 | /// <summary> | ||
111 | /// Scene part in which this script instance is contained. | ||
112 | /// </summary> | ||
113 | SceneObjectPart Part { get; } | ||
114 | |||
96 | IScriptEngine Engine { get; } | 115 | IScriptEngine Engine { get; } |
97 | UUID AppDomain { get; set; } | 116 | UUID AppDomain { get; set; } |
98 | string PrimName { get; } | 117 | string PrimName { get; } |
@@ -112,8 +131,24 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
112 | 131 | ||
113 | uint LocalID { get; } | 132 | uint LocalID { get; } |
114 | UUID AssetID { get; } | 133 | UUID AssetID { get; } |
134 | |||
135 | /// <summary> | ||
136 | /// Inventory item containing the script used. | ||
137 | /// </summary> | ||
138 | TaskInventoryItem ScriptTask { get; } | ||
139 | |||
115 | Queue EventQueue { get; } | 140 | Queue EventQueue { get; } |
116 | 141 | ||
142 | /// <summary> | ||
143 | /// Number of events queued for processing. | ||
144 | /// </summary> | ||
145 | long EventsQueued { get; } | ||
146 | |||
147 | /// <summary> | ||
148 | /// Number of events processed by this script instance. | ||
149 | /// </summary> | ||
150 | long EventsProcessed { get; } | ||
151 | |||
117 | void ClearQueue(); | 152 | void ClearQueue(); |
118 | int StartParam { get; set; } | 153 | int StartParam { get; set; } |
119 | 154 | ||
@@ -125,7 +160,13 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
125 | /// <summary> | 160 | /// <summary> |
126 | /// Stop the script instance. | 161 | /// Stop the script instance. |
127 | /// </summary> | 162 | /// </summary> |
163 | /// <remarks> | ||
164 | /// This must not be called by a thread that is in the process of handling an event for this script. Otherwise | ||
165 | /// there is a danger that it will self-abort and not complete the reset. | ||
166 | /// </remarks> | ||
128 | /// <param name="timeout"></param> | 167 | /// <param name="timeout"></param> |
168 | /// How many milliseconds we will wait for an existing script event to finish before | ||
169 | /// forcibly aborting that event. | ||
129 | /// <returns>true if the script was successfully stopped, false otherwise</returns> | 170 | /// <returns>true if the script was successfully stopped, false otherwise</returns> |
130 | bool Stop(int timeout); | 171 | bool Stop(int timeout); |
131 | 172 | ||
@@ -147,8 +188,31 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
147 | object EventProcessor(); | 188 | object EventProcessor(); |
148 | 189 | ||
149 | int EventTime(); | 190 | int EventTime(); |
150 | void ResetScript(); | 191 | |
192 | /// <summary> | ||
193 | /// Reset the script. | ||
194 | /// </summary> | ||
195 | /// <remarks> | ||
196 | /// This must not be called by a thread that is in the process of handling an event for this script. Otherwise | ||
197 | /// there is a danger that it will self-abort and not complete the reset. Such a thread must call | ||
198 | /// ApiResetScript() instead. | ||
199 | /// </remarks> | ||
200 | /// <param name='timeout'> | ||
201 | /// How many milliseconds we will wait for an existing script event to finish before | ||
202 | /// forcibly aborting that event prior to script reset. | ||
203 | /// </param> | ||
204 | void ResetScript(int timeout); | ||
205 | |||
206 | /// <summary> | ||
207 | /// Reset the script. | ||
208 | /// </summary> | ||
209 | /// <remarks> | ||
210 | /// This must not be called by any thread other than the one executing the scripts current event. This is | ||
211 | /// because there is no wait or abort logic if another thread is in the middle of processing a script event. | ||
212 | /// Such an external thread should use ResetScript() instead. | ||
213 | /// </remarks> | ||
151 | void ApiResetScript(); | 214 | void ApiResetScript(); |
215 | |||
152 | Dictionary<string, object> GetVars(); | 216 | Dictionary<string, object> GetVars(); |
153 | void SetVars(Dictionary<string, object> vars); | 217 | void SetVars(Dictionary<string, object> vars); |
154 | DetectParams GetDetectParams(int idx); | 218 | DetectParams GetDetectParams(int idx); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index b5fa6de..fce8ff8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Threading; | ||
29 | using System.Reflection; | 30 | using System.Reflection; |
30 | using System.Collections; | 31 | using System.Collections; |
31 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
@@ -62,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
62 | internal TaskInventoryItem m_item; | 63 | internal TaskInventoryItem m_item; |
63 | internal bool m_CMFunctionsEnabled = false; | 64 | internal bool m_CMFunctionsEnabled = false; |
64 | 65 | ||
65 | public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) | 66 | public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) |
66 | { | 67 | { |
67 | m_ScriptEngine = ScriptEngine; | 68 | m_ScriptEngine = ScriptEngine; |
68 | m_host = host; | 69 | m_host = host; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 53c6e5c..38a9cb0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -87,10 +87,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
87 | public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi | 87 | public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi |
88 | { | 88 | { |
89 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 89 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
90 | |||
90 | protected IScriptEngine m_ScriptEngine; | 91 | protected IScriptEngine m_ScriptEngine; |
91 | protected SceneObjectPart m_host; | 92 | protected SceneObjectPart m_host; |
92 | 93 | ||
93 | /// <summary> | 94 | /// <summary> |
95 | /// Used for script sleeps when we are using co-operative script termination. | ||
96 | /// </summary> | ||
97 | /// <remarks>null if co-operative script termination is not active</remarks> | ||
98 | WaitHandle m_coopSleepHandle; | ||
99 | |||
100 | /// <summary> | ||
94 | /// The item that hosts this script | 101 | /// The item that hosts this script |
95 | /// </summary> | 102 | /// </summary> |
96 | protected TaskInventoryItem m_item; | 103 | protected TaskInventoryItem m_item; |
@@ -100,6 +107,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
100 | protected float m_ScriptDelayFactor = 1.0f; | 107 | protected float m_ScriptDelayFactor = 1.0f; |
101 | protected float m_ScriptDistanceFactor = 1.0f; | 108 | protected float m_ScriptDistanceFactor = 1.0f; |
102 | protected float m_MinTimerInterval = 0.5f; | 109 | protected float m_MinTimerInterval = 0.5f; |
110 | protected float m_recoilScaleFactor = 0.0f; | ||
103 | 111 | ||
104 | protected DateTime m_timer = DateTime.Now; | 112 | protected DateTime m_timer = DateTime.Now; |
105 | protected bool m_waitingForScriptAnswer = false; | 113 | protected bool m_waitingForScriptAnswer = false; |
@@ -141,33 +149,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
141 | {"TURNRIGHT", "Turning Right"} | 149 | {"TURNRIGHT", "Turning Right"} |
142 | }; | 150 | }; |
143 | 151 | ||
144 | public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) | 152 | public void Initialize( |
153 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) | ||
145 | { | 154 | { |
146 | /* | ||
147 | m_ShoutSayTimer = new Timer(1000); | ||
148 | m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed; | ||
149 | m_ShoutSayTimer.AutoReset = true; | ||
150 | m_ShoutSayTimer.Start(); | ||
151 | */ | ||
152 | m_lastSayShoutCheck = DateTime.UtcNow; | 155 | m_lastSayShoutCheck = DateTime.UtcNow; |
153 | 156 | ||
154 | m_ScriptEngine = ScriptEngine; | 157 | m_ScriptEngine = scriptEngine; |
155 | m_host = host; | 158 | m_host = host; |
156 | m_item = item; | 159 | m_item = item; |
157 | m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); | 160 | m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); |
161 | m_coopSleepHandle = coopSleepHandle; | ||
158 | 162 | ||
159 | LoadLimits(); // read script limits from config. | 163 | LoadConfig(); |
160 | 164 | ||
161 | m_TransferModule = | 165 | m_TransferModule = |
162 | m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); | 166 | m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); |
163 | m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); | 167 | m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); |
164 | m_SoundModule = m_ScriptEngine.World.RequestModuleInterface<ISoundModule>(); | 168 | m_SoundModule = m_ScriptEngine.World.RequestModuleInterface<ISoundModule>(); |
165 | 169 | ||
166 | AsyncCommands = new AsyncCommandManager(ScriptEngine); | 170 | AsyncCommands = new AsyncCommandManager(m_ScriptEngine); |
167 | } | 171 | } |
168 | 172 | ||
169 | /* load configuration items that affect script, object and run-time behavior. */ | 173 | /// <summary> |
170 | private void LoadLimits() | 174 | /// Load configuration items that affect script, object and run-time behavior. */ |
175 | /// </summary> | ||
176 | private void LoadConfig() | ||
171 | { | 177 | { |
172 | m_ScriptDelayFactor = | 178 | m_ScriptDelayFactor = |
173 | m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); | 179 | m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); |
@@ -181,12 +187,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
181 | m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); | 187 | m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); |
182 | if (m_notecardLineReadCharsMax > 65535) | 188 | if (m_notecardLineReadCharsMax > 65535) |
183 | m_notecardLineReadCharsMax = 65535; | 189 | m_notecardLineReadCharsMax = 65535; |
190 | |||
184 | // load limits for particular subsystems. | 191 | // load limits for particular subsystems. |
185 | IConfig SMTPConfig; | 192 | IConfig SMTPConfig; |
186 | if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) { | 193 | if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) { |
187 | // there's an smtp config, so load in the snooze time. | 194 | // there's an smtp config, so load in the snooze time. |
188 | EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); | 195 | EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); |
189 | } | 196 | } |
197 | |||
198 | // Rezzing an object with a velocity can create recoil. This feature seems to have been | ||
199 | // removed from recent versions of SL. The code computes recoil (vel*mass) and scales | ||
200 | // it by this factor. May be zero to turn off recoil all together. | ||
201 | m_recoilScaleFactor = m_ScriptEngine.Config.GetFloat("RecoilScaleFactor", m_recoilScaleFactor); | ||
190 | } | 202 | } |
191 | 203 | ||
192 | public override Object InitializeLifetimeService() | 204 | public override Object InitializeLifetimeService() |
@@ -207,7 +219,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
207 | delay = (int)((float)delay * m_ScriptDelayFactor); | 219 | delay = (int)((float)delay * m_ScriptDelayFactor); |
208 | if (delay == 0) | 220 | if (delay == 0) |
209 | return; | 221 | return; |
210 | System.Threading.Thread.Sleep(delay); | 222 | |
223 | Sleep(delay); | ||
224 | } | ||
225 | |||
226 | protected virtual void Sleep(int delay) | ||
227 | { | ||
228 | if (m_coopSleepHandle == null) | ||
229 | System.Threading.Thread.Sleep(delay); | ||
230 | else | ||
231 | CheckForCoopTermination(delay); | ||
232 | } | ||
233 | |||
234 | /// <summary> | ||
235 | /// Check for co-operative termination. | ||
236 | /// </summary> | ||
237 | /// <param name='delay'>If called with 0, then just the check is performed with no wait.</param> | ||
238 | protected virtual void CheckForCoopTermination(int delay) | ||
239 | { | ||
240 | if (m_coopSleepHandle.WaitOne(delay)) | ||
241 | throw new ScriptCoopStopException(); | ||
211 | } | 242 | } |
212 | 243 | ||
213 | public Scene World | 244 | public Scene World |
@@ -1483,19 +1514,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1483 | return 0; | 1514 | return 0; |
1484 | 1515 | ||
1485 | case ScriptBaseClass.STATUS_ROTATE_X: | 1516 | case ScriptBaseClass.STATUS_ROTATE_X: |
1486 | if (m_host.GetAxisRotation(2) == 2) | 1517 | // if (m_host.GetAxisRotation(2) != 0) |
1518 | if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0) | ||
1487 | return 1; | 1519 | return 1; |
1488 | else | 1520 | else |
1489 | return 0; | 1521 | return 0; |
1490 | 1522 | ||
1491 | case ScriptBaseClass.STATUS_ROTATE_Y: | 1523 | case ScriptBaseClass.STATUS_ROTATE_Y: |
1492 | if (m_host.GetAxisRotation(4) == 4) | 1524 | if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0) |
1493 | return 1; | 1525 | return 1; |
1494 | else | 1526 | else |
1495 | return 0; | 1527 | return 0; |
1496 | 1528 | ||
1497 | case ScriptBaseClass.STATUS_ROTATE_Z: | 1529 | case ScriptBaseClass.STATUS_ROTATE_Z: |
1498 | if (m_host.GetAxisRotation(8) == 8) | 1530 | if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0) |
1499 | return 1; | 1531 | return 1; |
1500 | else | 1532 | else |
1501 | return 0; | 1533 | return 0; |
@@ -1875,10 +1907,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1875 | part.Shape.FlexiForceX = (float)Force.x; | 1907 | part.Shape.FlexiForceX = (float)Force.x; |
1876 | part.Shape.FlexiForceY = (float)Force.y; | 1908 | part.Shape.FlexiForceY = (float)Force.y; |
1877 | part.Shape.FlexiForceZ = (float)Force.z; | 1909 | part.Shape.FlexiForceZ = (float)Force.z; |
1878 | part.Shape.PathCurve = 0x80; | 1910 | part.Shape.PathCurve = (byte)Extrusion.Flexible; |
1879 | part.ParentGroup.HasGroupChanged = true; | ||
1880 | part.ScheduleFullUpdate(); | ||
1881 | } | 1911 | } |
1912 | else | ||
1913 | { | ||
1914 | // Other values not set, they do not seem to be sent to the viewer | ||
1915 | // Setting PathCurve appears to be what actually toggles the check box and turns Flexi on and off | ||
1916 | part.Shape.PathCurve = (byte)Extrusion.Straight; | ||
1917 | part.Shape.FlexiEntry = false; | ||
1918 | } | ||
1919 | part.ParentGroup.HasGroupChanged = true; | ||
1920 | part.ScheduleFullUpdate(); | ||
1882 | } | 1921 | } |
1883 | 1922 | ||
1884 | /// <summary> | 1923 | /// <summary> |
@@ -3141,11 +3180,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3141 | 3180 | ||
3142 | PhysicsActor pa = new_group.RootPart.PhysActor; | 3181 | PhysicsActor pa = new_group.RootPart.PhysActor; |
3143 | 3182 | ||
3183 | //Recoil. | ||
3144 | if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) | 3184 | if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) |
3145 | { | 3185 | { |
3146 | float groupmass = new_group.GetMass(); | 3186 | float groupmass = new_group.GetMass(); |
3147 | vel *= -groupmass; | 3187 | Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; |
3148 | llApplyImpulse(vel, 0); | 3188 | if (recoil != Vector3.Zero) |
3189 | { | ||
3190 | llApplyImpulse(recoil, 0); | ||
3191 | } | ||
3149 | } | 3192 | } |
3150 | // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | 3193 | // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) |
3151 | return; | 3194 | return; |
@@ -3220,7 +3263,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3220 | { | 3263 | { |
3221 | // m_log.Info("llSleep snoozing " + sec + "s."); | 3264 | // m_log.Info("llSleep snoozing " + sec + "s."); |
3222 | m_host.AddScriptLPS(1); | 3265 | m_host.AddScriptLPS(1); |
3223 | Thread.Sleep((int)(sec * 1000)); | 3266 | |
3267 | Sleep((int)(sec * 1000)); | ||
3224 | } | 3268 | } |
3225 | 3269 | ||
3226 | public LSL_Float llGetMass() | 3270 | public LSL_Float llGetMass() |
@@ -3322,7 +3366,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3322 | /// <summary> | 3366 | /// <summary> |
3323 | /// Attach the object containing this script to the avatar that owns it. | 3367 | /// Attach the object containing this script to the avatar that owns it. |
3324 | /// </summary> | 3368 | /// </summary> |
3325 | /// <param name='attachment'>The attachment point (e.g. ATTACH_CHEST)</param> | 3369 | /// <param name='attachmentPoint'> |
3370 | /// The attachment point (e.g. <see cref="OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass.ATTACH_CHEST">ATTACH_CHEST</see>) | ||
3371 | /// </param> | ||
3326 | /// <returns>true if the attach suceeded, false if it did not</returns> | 3372 | /// <returns>true if the attach suceeded, false if it did not</returns> |
3327 | public bool AttachToAvatar(int attachmentPoint) | 3373 | public bool AttachToAvatar(int attachmentPoint) |
3328 | { | 3374 | { |
@@ -3680,7 +3726,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3680 | if (animID == UUID.Zero) | 3726 | if (animID == UUID.Zero) |
3681 | presence.Animator.RemoveAnimation(anim); | 3727 | presence.Animator.RemoveAnimation(anim); |
3682 | else | 3728 | else |
3683 | presence.Animator.RemoveAnimation(animID); | 3729 | presence.Animator.RemoveAnimation(animID, true); |
3684 | } | 3730 | } |
3685 | } | 3731 | } |
3686 | } | 3732 | } |
@@ -3753,21 +3799,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3753 | } | 3799 | } |
3754 | else | 3800 | else |
3755 | { | 3801 | { |
3756 | bool sitting = false; | 3802 | if (m_host.ParentGroup.GetSittingAvatars().Contains(agentID)) |
3757 | if (m_host.SitTargetAvatar == agentID) | ||
3758 | { | ||
3759 | sitting = true; | ||
3760 | } | ||
3761 | else | ||
3762 | { | ||
3763 | foreach (SceneObjectPart p in m_host.ParentGroup.Parts) | ||
3764 | { | ||
3765 | if (p.SitTargetAvatar == agentID) | ||
3766 | sitting = true; | ||
3767 | } | ||
3768 | } | ||
3769 | |||
3770 | if (sitting) | ||
3771 | { | 3803 | { |
3772 | // When agent is sitting, certain permissions are implicit if requested from sitting agent | 3804 | // When agent is sitting, certain permissions are implicit if requested from sitting agent |
3773 | implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | | 3805 | implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | |
@@ -3809,7 +3841,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3809 | INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); | 3841 | INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); |
3810 | if (npcModule != null && npcModule.IsNPC(agentID, World)) | 3842 | if (npcModule != null && npcModule.IsNPC(agentID, World)) |
3811 | { | 3843 | { |
3812 | if (agentID == m_host.ParentGroup.OwnerID || npcModule.GetOwner(agentID) == m_host.ParentGroup.OwnerID) | 3844 | if (npcModule.CheckPermissions(agentID, m_host.OwnerID)) |
3813 | { | 3845 | { |
3814 | lock (m_host.TaskInventory) | 3846 | lock (m_host.TaskInventory) |
3815 | { | 3847 | { |
@@ -4184,62 +4216,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4184 | public LSL_String llGetLinkName(int linknum) | 4216 | public LSL_String llGetLinkName(int linknum) |
4185 | { | 4217 | { |
4186 | m_host.AddScriptLPS(1); | 4218 | m_host.AddScriptLPS(1); |
4187 | // simplest case, this prims link number | ||
4188 | if (linknum == m_host.LinkNum || linknum == ScriptBaseClass.LINK_THIS) | ||
4189 | return m_host.Name; | ||
4190 | 4219 | ||
4191 | // parse for sitting avatare-names | 4220 | if (linknum < 0) |
4192 | List<String> nametable = new List<String>(); | ||
4193 | World.ForEachRootScenePresence(delegate(ScenePresence presence) | ||
4194 | { | 4221 | { |
4195 | SceneObjectPart sitPart = presence.ParentPart; | 4222 | if (linknum == ScriptBaseClass.LINK_THIS) |
4196 | if (sitPart != null && m_host.ParentGroup.ContainsPart(sitPart.LocalId)) | ||
4197 | nametable.Add(presence.ControllingClient.Name); | ||
4198 | }); | ||
4199 | |||
4200 | int totalprims = m_host.ParentGroup.PrimCount + nametable.Count; | ||
4201 | if (totalprims > m_host.ParentGroup.PrimCount) | ||
4202 | { | ||
4203 | // sitting Avatar-Name with negativ linknum / SinglePrim | ||
4204 | if (linknum < 0 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1) | ||
4205 | return nametable[0]; | ||
4206 | // Prim-Name / SinglePrim Sitting Avatar | ||
4207 | if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1) | ||
4208 | return m_host.Name; | 4223 | return m_host.Name; |
4209 | // LinkNumber > of Real PrimSet = AvatarName | 4224 | else |
4210 | if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims) | 4225 | return ScriptBaseClass.NULL_KEY; |
4211 | return nametable[totalprims - linknum]; | ||
4212 | } | 4226 | } |
4213 | 4227 | ||
4214 | // Single prim | 4228 | int actualPrimCount = m_host.ParentGroup.PrimCount; |
4215 | if (m_host.LinkNum == 0) | 4229 | List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars(); |
4230 | int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count; | ||
4231 | |||
4232 | // Special case for a single prim. In this case the linknum is zero. However, this will not match a single | ||
4233 | // prim that has any avatars sat upon it (in which case the root prim is link 1). | ||
4234 | if (linknum == 0) | ||
4216 | { | 4235 | { |
4217 | if (linknum == 0 || linknum == ScriptBaseClass.LINK_ROOT) | 4236 | if (actualPrimCount == 1 && sittingAvatarIds.Count == 0) |
4218 | return m_host.Name; | 4237 | return m_host.Name; |
4219 | else | ||
4220 | return UUID.Zero.ToString(); | ||
4221 | } | ||
4222 | 4238 | ||
4223 | // Link set | 4239 | return ScriptBaseClass.NULL_KEY; |
4224 | SceneObjectPart part = null; | 4240 | } |
4225 | if (m_host.LinkNum == 1) // this is the Root prim | 4241 | // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but |
4242 | // here we must match 1 (ScriptBaseClass.LINK_ROOT). | ||
4243 | else if (linknum == 1 && actualPrimCount == 1) | ||
4226 | { | 4244 | { |
4227 | if (linknum < 0) | 4245 | if (sittingAvatarIds.Count > 0) |
4228 | part = m_host.ParentGroup.GetLinkNumPart(2); | 4246 | return m_host.ParentGroup.RootPart.Name; |
4229 | else | 4247 | else |
4230 | part = m_host.ParentGroup.GetLinkNumPart(linknum); | 4248 | return ScriptBaseClass.NULL_KEY; |
4231 | } | 4249 | } |
4232 | else // this is a child prim | 4250 | else if (linknum <= adjustedPrimCount) |
4233 | { | 4251 | { |
4234 | if (linknum < 2) | 4252 | if (linknum <= actualPrimCount) |
4235 | part = m_host.ParentGroup.GetLinkNumPart(1); | 4253 | { |
4254 | return m_host.ParentGroup.GetLinkNumPart(linknum).Name; | ||
4255 | } | ||
4236 | else | 4256 | else |
4237 | part = m_host.ParentGroup.GetLinkNumPart(linknum); | 4257 | { |
4258 | ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]); | ||
4259 | if (sp != null) | ||
4260 | return sp.Name; | ||
4261 | else | ||
4262 | return ScriptBaseClass.NULL_KEY; | ||
4263 | } | ||
4238 | } | 4264 | } |
4239 | if (part != null) | ||
4240 | return part.Name; | ||
4241 | else | 4265 | else |
4242 | return UUID.Zero.ToString(); | 4266 | { |
4267 | return ScriptBaseClass.NULL_KEY; | ||
4268 | } | ||
4243 | } | 4269 | } |
4244 | 4270 | ||
4245 | public LSL_Integer llGetInventoryNumber(int type) | 4271 | public LSL_Integer llGetInventoryNumber(int type) |
@@ -5852,9 +5878,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5852 | } | 5878 | } |
5853 | 5879 | ||
5854 | /// <summary> | 5880 | /// <summary> |
5855 | /// Insert the list identified by <src> into the | 5881 | /// Insert the list identified by <paramref name="src"/> into the |
5856 | /// list designated by <dest> such that the first | 5882 | /// list designated by <paramref name="dest"/> such that the first |
5857 | /// new element has the index specified by <index> | 5883 | /// new element has the index specified by <paramref name="index"/> |
5858 | /// </summary> | 5884 | /// </summary> |
5859 | 5885 | ||
5860 | public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index) | 5886 | public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index) |
@@ -6220,13 +6246,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6220 | if (parcelOwned && land.LandData.OwnerID == id || | 6246 | if (parcelOwned && land.LandData.OwnerID == id || |
6221 | parcel && land.LandData.GlobalID == id) | 6247 | parcel && land.LandData.GlobalID == id) |
6222 | { | 6248 | { |
6223 | result.Add(ssp.UUID.ToString()); | 6249 | result.Add(new LSL_Key(ssp.UUID.ToString())); |
6224 | } | 6250 | } |
6225 | } | 6251 | } |
6226 | } | 6252 | } |
6227 | else | 6253 | else |
6228 | { | 6254 | { |
6229 | result.Add(ssp.UUID.ToString()); | 6255 | result.Add(new LSL_Key(ssp.UUID.ToString())); |
6230 | } | 6256 | } |
6231 | } | 6257 | } |
6232 | // Maximum of 100 results | 6258 | // Maximum of 100 results |
@@ -6687,6 +6713,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6687 | ps.BurstSpeedMax = 1.0f; | 6713 | ps.BurstSpeedMax = 1.0f; |
6688 | ps.BurstRate = 0.1f; | 6714 | ps.BurstRate = 0.1f; |
6689 | ps.PartMaxAge = 10.0f; | 6715 | ps.PartMaxAge = 10.0f; |
6716 | ps.BurstPartCount = 1; | ||
6690 | return ps; | 6717 | return ps; |
6691 | } | 6718 | } |
6692 | 6719 | ||
@@ -6708,10 +6735,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6708 | SetParticleSystem(m_host, rules); | 6735 | SetParticleSystem(m_host, rules); |
6709 | } | 6736 | } |
6710 | 6737 | ||
6711 | private void SetParticleSystem(SceneObjectPart part, LSL_List rules) | 6738 | private void SetParticleSystem(SceneObjectPart part, LSL_List rules) |
6712 | { | 6739 | { |
6713 | |||
6714 | |||
6715 | if (rules.Length == 0) | 6740 | if (rules.Length == 0) |
6716 | { | 6741 | { |
6717 | part.RemoveParticleSystem(); | 6742 | part.RemoveParticleSystem(); |
@@ -7371,6 +7396,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7371 | public void llCloseRemoteDataChannel(string channel) | 7396 | public void llCloseRemoteDataChannel(string channel) |
7372 | { | 7397 | { |
7373 | m_host.AddScriptLPS(1); | 7398 | m_host.AddScriptLPS(1); |
7399 | |||
7400 | IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>(); | ||
7401 | if (xmlRpcRouter != null) | ||
7402 | { | ||
7403 | xmlRpcRouter.UnRegisterReceiver(channel, m_item.ItemID); | ||
7404 | } | ||
7405 | |||
7374 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); | 7406 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); |
7375 | if (xmlrpcMod != null) | 7407 | if (xmlrpcMod != null) |
7376 | xmlrpcMod.CloseXMLRPCChannel((UUID)channel); | 7408 | xmlrpcMod.CloseXMLRPCChannel((UUID)channel); |
@@ -11517,6 +11549,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11517 | case ScriptBaseClass.OBJECT_PHYSICS_COST: | 11549 | case ScriptBaseClass.OBJECT_PHYSICS_COST: |
11518 | ret.Add(new LSL_Float(0)); | 11550 | ret.Add(new LSL_Float(0)); |
11519 | break; | 11551 | break; |
11552 | case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding | ||
11553 | ret.Add(new LSL_Float(0)); | ||
11554 | break; | ||
11555 | case ScriptBaseClass.OBJECT_ROOT: | ||
11556 | SceneObjectPart p = av.ParentPart; | ||
11557 | if (p != null) | ||
11558 | { | ||
11559 | ret.Add(new LSL_String(p.ParentGroup.RootPart.UUID.ToString())); | ||
11560 | } | ||
11561 | else | ||
11562 | { | ||
11563 | ret.Add(new LSL_String(id)); | ||
11564 | } | ||
11565 | break; | ||
11566 | case ScriptBaseClass.OBJECT_ATTACHED_POINT: | ||
11567 | ret.Add(new LSL_Integer(0)); | ||
11568 | break; | ||
11569 | case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: // Pathfinding | ||
11570 | ret.Add(new LSL_Integer(ScriptBaseClass.OPT_AVATAR)); | ||
11571 | break; | ||
11572 | case ScriptBaseClass.OBJECT_PHYSICS: | ||
11573 | ret.Add(new LSL_Integer(0)); | ||
11574 | break; | ||
11575 | case ScriptBaseClass.OBJECT_PHANTOM: | ||
11576 | ret.Add(new LSL_Integer(0)); | ||
11577 | break; | ||
11578 | case ScriptBaseClass.OBJECT_TEMP_ON_REZ: | ||
11579 | ret.Add(new LSL_Integer(0)); | ||
11580 | break; | ||
11520 | default: | 11581 | default: |
11521 | // Invalid or unhandled constant. | 11582 | // Invalid or unhandled constant. |
11522 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); | 11583 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); |
@@ -11608,6 +11669,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11608 | // The value returned in SL for normal prims is prim count | 11669 | // The value returned in SL for normal prims is prim count |
11609 | ret.Add(new LSL_Float(obj.PhysicsCost)); | 11670 | ret.Add(new LSL_Float(obj.PhysicsCost)); |
11610 | break; | 11671 | break; |
11672 | case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding | ||
11673 | ret.Add(new LSL_Float(0)); | ||
11674 | break; | ||
11675 | case ScriptBaseClass.OBJECT_ROOT: | ||
11676 | ret.Add(new LSL_String(obj.ParentGroup.RootPart.UUID.ToString())); | ||
11677 | break; | ||
11678 | case ScriptBaseClass.OBJECT_ATTACHED_POINT: | ||
11679 | ret.Add(new LSL_Integer(obj.ParentGroup.AttachmentPoint)); | ||
11680 | break; | ||
11681 | case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: | ||
11682 | byte pcode = obj.Shape.PCode; | ||
11683 | if (obj.ParentGroup.AttachmentPoint != 0 | ||
11684 | || pcode == (byte)PCode.Grass | ||
11685 | || pcode == (byte)PCode.Tree | ||
11686 | || pcode == (byte)PCode.NewTree) | ||
11687 | { | ||
11688 | ret.Add(new LSL_Integer(ScriptBaseClass.OPT_OTHER)); | ||
11689 | } | ||
11690 | else | ||
11691 | { | ||
11692 | ret.Add(new LSL_Integer(ScriptBaseClass.OPT_LEGACY_LINKSET)); | ||
11693 | } | ||
11694 | break; | ||
11695 | case ScriptBaseClass.OBJECT_PHYSICS: | ||
11696 | if (obj.ParentGroup.AttachmentPoint != 0) | ||
11697 | { | ||
11698 | ret.Add(new LSL_Integer(0)); // Always false if attached | ||
11699 | } | ||
11700 | else | ||
11701 | { | ||
11702 | ret.Add(new LSL_Integer(obj.ParentGroup.UsesPhysics ? 1 : 0)); | ||
11703 | } | ||
11704 | break; | ||
11705 | case ScriptBaseClass.OBJECT_PHANTOM: | ||
11706 | if (obj.ParentGroup.AttachmentPoint != 0) | ||
11707 | { | ||
11708 | ret.Add(new LSL_Integer(0)); // Always false if attached | ||
11709 | } | ||
11710 | else | ||
11711 | { | ||
11712 | ret.Add(new LSL_Integer(obj.ParentGroup.IsPhantom ? 1 : 0)); | ||
11713 | } | ||
11714 | break; | ||
11715 | case ScriptBaseClass.OBJECT_TEMP_ON_REZ: | ||
11716 | ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0)); | ||
11717 | break; | ||
11611 | default: | 11718 | default: |
11612 | // Invalid or unhandled constant. | 11719 | // Invalid or unhandled constant. |
11613 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); | 11720 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); |
@@ -11991,12 +12098,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11991 | radius = Math.Abs(maxY); | 12098 | radius = Math.Abs(maxY); |
11992 | if (Math.Abs(maxZ) > radius) | 12099 | if (Math.Abs(maxZ) > radius) |
11993 | radius = Math.Abs(maxZ); | 12100 | radius = Math.Abs(maxZ); |
11994 | 12101 | radius = radius*1.413f; | |
11995 | Vector3 ac = group.AbsolutePosition - rayStart; | 12102 | Vector3 ac = group.AbsolutePosition - rayStart; |
11996 | Vector3 bc = group.AbsolutePosition - rayEnd; | 12103 | Vector3 bc = group.AbsolutePosition - rayEnd; |
11997 | 12104 | ||
11998 | double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); | 12105 | double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); |
11999 | 12106 | ||
12000 | // Too far off ray, don't bother | 12107 | // Too far off ray, don't bother |
12001 | if (d > radius) | 12108 | if (d > radius) |
12002 | return; | 12109 | return; |
@@ -12006,11 +12113,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12006 | if (d2 > 0) | 12113 | if (d2 > 0) |
12007 | return; | 12114 | return; |
12008 | 12115 | ||
12116 | ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); | ||
12009 | EntityIntersection intersection = group.TestIntersection(ray, true, false); | 12117 | EntityIntersection intersection = group.TestIntersection(ray, true, false); |
12010 | // Miss. | 12118 | // Miss. |
12011 | if (!intersection.HitTF) | 12119 | if (!intersection.HitTF) |
12012 | return; | 12120 | return; |
12013 | 12121 | ||
12122 | Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ); | ||
12123 | Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ); | ||
12124 | //m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z); | ||
12125 | if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X && | ||
12126 | intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y && | ||
12127 | intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z)) | ||
12128 | return; | ||
12129 | |||
12014 | ContactResult result = new ContactResult (); | 12130 | ContactResult result = new ContactResult (); |
12015 | result.ConsumerID = group.LocalId; | 12131 | result.ConsumerID = group.LocalId; |
12016 | // result.Depth = intersection.distance; | 12132 | // result.Depth = intersection.distance; |
@@ -12284,8 +12400,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12284 | if (checkPhysical || checkNonPhysical || detectPhantom) | 12400 | if (checkPhysical || checkNonPhysical || detectPhantom) |
12285 | { | 12401 | { |
12286 | ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); | 12402 | ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); |
12287 | foreach (ContactResult r in objectHits) | 12403 | for (int iter = 0; iter < objectHits.Length; iter++) |
12288 | results.Add(r); | 12404 | { |
12405 | // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler. | ||
12406 | objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart); | ||
12407 | results.Add(objectHits[iter]); | ||
12408 | } | ||
12289 | } | 12409 | } |
12290 | } | 12410 | } |
12291 | 12411 | ||
@@ -13271,7 +13391,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13271 | /// Get a notecard line. | 13391 | /// Get a notecard line. |
13272 | /// </summary> | 13392 | /// </summary> |
13273 | /// <param name="assetID"></param> | 13393 | /// <param name="assetID"></param> |
13274 | /// <param name="line">Lines start at index 0</param> | 13394 | /// <param name="lineNumber">Lines start at index 0</param> |
13275 | /// <returns></returns> | 13395 | /// <returns></returns> |
13276 | public static string GetLine(UUID assetID, int lineNumber) | 13396 | public static string GetLine(UUID assetID, int lineNumber) |
13277 | { | 13397 | { |
@@ -13300,9 +13420,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13300 | /// Get a notecard line. | 13420 | /// Get a notecard line. |
13301 | /// </summary> | 13421 | /// </summary> |
13302 | /// <param name="assetID"></param> | 13422 | /// <param name="assetID"></param> |
13303 | /// <param name="line">Lines start at index 0</param> | 13423 | /// <param name="lineNumber">Lines start at index 0</param> |
13304 | /// <param name="maxLength">Maximum length of the returned line. Longer lines will be truncated</para> | 13424 | /// <param name="maxLength"> |
13305 | /// <returns></returns> | 13425 | /// Maximum length of the returned line. |
13426 | /// </param> | ||
13427 | /// <returns> | ||
13428 | /// If the line length is longer than <paramref name="maxLength"/>, | ||
13429 | /// the return string will be truncated. | ||
13430 | /// </returns> | ||
13306 | public static string GetLine(UUID assetID, int lineNumber, int maxLength) | 13431 | public static string GetLine(UUID assetID, int lineNumber, int maxLength) |
13307 | { | 13432 | { |
13308 | string line = GetLine(assetID, lineNumber); | 13433 | string line = GetLine(assetID, lineNumber); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index ceb4660..1d6cb6d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs | |||
@@ -30,6 +30,7 @@ using System.Reflection; | |||
30 | using System.Collections; | 30 | using System.Collections; |
31 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
32 | using System.Runtime.Remoting.Lifetime; | 32 | using System.Runtime.Remoting.Lifetime; |
33 | using System.Threading; | ||
33 | using OpenMetaverse; | 34 | using OpenMetaverse; |
34 | using Nini.Config; | 35 | using Nini.Config; |
35 | using OpenSim; | 36 | using OpenSim; |
@@ -61,9 +62,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
61 | internal bool m_LSFunctionsEnabled = false; | 62 | internal bool m_LSFunctionsEnabled = false; |
62 | internal IScriptModuleComms m_comms = null; | 63 | internal IScriptModuleComms m_comms = null; |
63 | 64 | ||
64 | public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) | 65 | public void Initialize( |
66 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) | ||
65 | { | 67 | { |
66 | m_ScriptEngine = ScriptEngine; | 68 | m_ScriptEngine = scriptEngine; |
67 | m_host = host; | 69 | m_host = host; |
68 | 70 | ||
69 | if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) | 71 | if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) |
@@ -92,10 +94,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
92 | get { return m_ScriptEngine.World; } | 94 | get { return m_ScriptEngine.World; } |
93 | } | 95 | } |
94 | 96 | ||
95 | // | 97 | /// <summary> |
96 | //Dumps an error message on the debug console. | 98 | /// Dumps an error message on the debug console. |
97 | // | 99 | /// </summary> |
98 | |||
99 | internal void LSShoutError(string message) | 100 | internal void LSShoutError(string message) |
100 | { | 101 | { |
101 | if (message.Length > 1023) | 102 | if (message.Length > 1023) |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 8f34833..9045672 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs | |||
@@ -30,6 +30,7 @@ using System.Reflection; | |||
30 | using System.Collections; | 30 | using System.Collections; |
31 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
32 | using System.Runtime.Remoting.Lifetime; | 32 | using System.Runtime.Remoting.Lifetime; |
33 | using System.Threading; | ||
33 | using OpenMetaverse; | 34 | using OpenMetaverse; |
34 | using Nini.Config; | 35 | using Nini.Config; |
35 | using OpenSim; | 36 | using OpenSim; |
@@ -61,9 +62,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
61 | internal bool m_MODFunctionsEnabled = false; | 62 | internal bool m_MODFunctionsEnabled = false; |
62 | internal IScriptModuleComms m_comms = null; | 63 | internal IScriptModuleComms m_comms = null; |
63 | 64 | ||
64 | public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) | 65 | public void Initialize( |
66 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) | ||
65 | { | 67 | { |
66 | m_ScriptEngine = ScriptEngine; | 68 | m_ScriptEngine = scriptEngine; |
67 | m_host = host; | 69 | m_host = host; |
68 | m_item = item; | 70 | m_item = item; |
69 | 71 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 7c2f8ed..6ff6b00 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -143,9 +143,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
143 | 143 | ||
144 | protected IUrlModule m_UrlModule = null; | 144 | protected IUrlModule m_UrlModule = null; |
145 | 145 | ||
146 | public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) | 146 | public void Initialize( |
147 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) | ||
147 | { | 148 | { |
148 | m_ScriptEngine = ScriptEngine; | 149 | m_ScriptEngine = scriptEngine; |
149 | m_host = host; | 150 | m_host = host; |
150 | m_item = item; | 151 | m_item = item; |
151 | m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); | 152 | m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); |
@@ -254,11 +255,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
254 | wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); | 255 | wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); |
255 | } | 256 | } |
256 | 257 | ||
258 | // Returns of the function is allowed. Throws a script exception if not allowed. | ||
257 | public void CheckThreatLevel(ThreatLevel level, string function) | 259 | public void CheckThreatLevel(ThreatLevel level, string function) |
258 | { | 260 | { |
259 | if (!m_OSFunctionsEnabled) | 261 | if (!m_OSFunctionsEnabled) |
260 | OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws | 262 | OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws |
261 | 263 | ||
264 | string reasonWhyNot = CheckThreatLevelTest(level, function); | ||
265 | if (!String.IsNullOrEmpty(reasonWhyNot)) | ||
266 | { | ||
267 | OSSLError(reasonWhyNot); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | // Check to see if function is allowed. Returns an empty string if function permitted | ||
272 | // or a string explaining why this function can't be used. | ||
273 | private string CheckThreatLevelTest(ThreatLevel level, string function) | ||
274 | { | ||
262 | if (!m_FunctionPerms.ContainsKey(function)) | 275 | if (!m_FunctionPerms.ContainsKey(function)) |
263 | { | 276 | { |
264 | FunctionPerms perms = new FunctionPerms(); | 277 | FunctionPerms perms = new FunctionPerms(); |
@@ -338,10 +351,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
338 | { | 351 | { |
339 | // Allow / disallow by threat level | 352 | // Allow / disallow by threat level |
340 | if (level > m_MaxThreatLevel) | 353 | if (level > m_MaxThreatLevel) |
341 | OSSLError( | 354 | return |
342 | String.Format( | 355 | String.Format( |
343 | "{0} permission denied. Allowed threat level is {1} but function threat level is {2}.", | 356 | "{0} permission denied. Allowed threat level is {1} but function threat level is {2}.", |
344 | function, m_MaxThreatLevel, level)); | 357 | function, m_MaxThreatLevel, level); |
345 | } | 358 | } |
346 | else | 359 | else |
347 | { | 360 | { |
@@ -351,7 +364,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
351 | if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID)) | 364 | if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID)) |
352 | { | 365 | { |
353 | // prim owner is in the list of allowed owners | 366 | // prim owner is in the list of allowed owners |
354 | return; | 367 | return String.Empty; |
355 | } | 368 | } |
356 | 369 | ||
357 | UUID ownerID = m_item.OwnerID; | 370 | UUID ownerID = m_item.OwnerID; |
@@ -363,7 +376,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
363 | 376 | ||
364 | if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero) | 377 | if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero) |
365 | { | 378 | { |
366 | return; | 379 | return String.Empty; |
367 | } | 380 | } |
368 | } | 381 | } |
369 | 382 | ||
@@ -374,7 +387,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
374 | 387 | ||
375 | if (land.LandData.OwnerID == ownerID) | 388 | if (land.LandData.OwnerID == ownerID) |
376 | { | 389 | { |
377 | return; | 390 | return String.Empty; |
378 | } | 391 | } |
379 | } | 392 | } |
380 | 393 | ||
@@ -384,7 +397,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
384 | //Only Estate Managers may use the function | 397 | //Only Estate Managers may use the function |
385 | if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID) | 398 | if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID) |
386 | { | 399 | { |
387 | return; | 400 | return String.Empty; |
388 | } | 401 | } |
389 | } | 402 | } |
390 | 403 | ||
@@ -393,25 +406,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
393 | { | 406 | { |
394 | if (World.RegionInfo.EstateSettings.EstateOwner == ownerID) | 407 | if (World.RegionInfo.EstateSettings.EstateOwner == ownerID) |
395 | { | 408 | { |
396 | return; | 409 | return String.Empty; |
397 | } | 410 | } |
398 | } | 411 | } |
399 | 412 | ||
400 | if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID)) | 413 | if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID)) |
401 | OSSLError( | 414 | return( |
402 | String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.", | 415 | String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.", |
403 | function)); | 416 | function)); |
404 | 417 | ||
405 | if (m_item.CreatorID != ownerID) | 418 | if (m_item.CreatorID != ownerID) |
406 | { | 419 | { |
407 | if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0) | 420 | if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0) |
408 | OSSLError( | 421 | return String.Format("{0} permission denied. Script permissions error.", function); |
409 | String.Format("{0} permission denied. Script permissions error.", | ||
410 | function)); | ||
411 | 422 | ||
412 | } | 423 | } |
413 | } | 424 | } |
414 | } | 425 | } |
426 | return String.Empty; | ||
415 | } | 427 | } |
416 | 428 | ||
417 | internal void OSSLDeprecated(string function, string replacement) | 429 | internal void OSSLDeprecated(string function, string replacement) |
@@ -983,7 +995,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
983 | if (animID == UUID.Zero) | 995 | if (animID == UUID.Zero) |
984 | target.Animator.RemoveAnimation(animation); | 996 | target.Animator.RemoveAnimation(animation); |
985 | else | 997 | else |
986 | target.Animator.RemoveAnimation(animID); | 998 | target.Animator.RemoveAnimation(animID, true); |
987 | } | 999 | } |
988 | } | 1000 | } |
989 | } | 1001 | } |
@@ -1214,12 +1226,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1214 | sunHour += 24.0; | 1226 | sunHour += 24.0; |
1215 | 1227 | ||
1216 | World.RegionInfo.RegionSettings.UseEstateSun = useEstateSun; | 1228 | World.RegionInfo.RegionSettings.UseEstateSun = useEstateSun; |
1217 | World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30 | 1229 | World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30 |
1218 | World.RegionInfo.RegionSettings.FixedSun = sunFixed; | 1230 | World.RegionInfo.RegionSettings.FixedSun = sunFixed; |
1219 | World.RegionInfo.RegionSettings.Save(); | 1231 | World.RegionInfo.RegionSettings.Save(); |
1220 | 1232 | ||
1221 | World.EventManager.TriggerEstateToolsSunUpdate( | 1233 | World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle); |
1222 | World.RegionInfo.RegionHandle, sunFixed, useEstateSun, (float)sunHour); | ||
1223 | } | 1234 | } |
1224 | 1235 | ||
1225 | /// <summary> | 1236 | /// <summary> |
@@ -1244,8 +1255,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1244 | World.RegionInfo.EstateSettings.FixedSun = sunFixed; | 1255 | World.RegionInfo.EstateSettings.FixedSun = sunFixed; |
1245 | World.RegionInfo.EstateSettings.Save(); | 1256 | World.RegionInfo.EstateSettings.Save(); |
1246 | 1257 | ||
1247 | World.EventManager.TriggerEstateToolsSunUpdate( | 1258 | World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle); |
1248 | World.RegionInfo.RegionHandle, sunFixed, World.RegionInfo.RegionSettings.UseEstateSun, (float)sunHour); | ||
1249 | } | 1259 | } |
1250 | 1260 | ||
1251 | /// <summary> | 1261 | /// <summary> |
@@ -1569,6 +1579,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1569 | } | 1579 | } |
1570 | } | 1580 | } |
1571 | 1581 | ||
1582 | public string osGetPhysicsEngineType() | ||
1583 | { | ||
1584 | // High because it can be used to target attacks to known weaknesses | ||
1585 | // This would allow a new class of griefer scripts that don't even | ||
1586 | // require their user to know what they are doing (see script | ||
1587 | // kiddie) | ||
1588 | // Because it would be nice if scripts didn't blow up if the information | ||
1589 | // about the physics engine, this function returns an empty string if | ||
1590 | // the user does not have permission to see it. This as opposed to | ||
1591 | // throwing an exception. | ||
1592 | m_host.AddScriptLPS(1); | ||
1593 | string ret = String.Empty; | ||
1594 | if (String.IsNullOrEmpty(CheckThreatLevelTest(ThreatLevel.High, "osGetPhysicsEngineType"))) | ||
1595 | { | ||
1596 | if (m_ScriptEngine.World.PhysicsScene != null) | ||
1597 | { | ||
1598 | ret = m_ScriptEngine.World.PhysicsScene.EngineType; | ||
1599 | // An old physics engine might have an uninitialized engine type | ||
1600 | if (ret == null) | ||
1601 | ret = "unknown"; | ||
1602 | } | ||
1603 | } | ||
1604 | |||
1605 | return ret; | ||
1606 | } | ||
1607 | |||
1572 | public string osGetSimulatorVersion() | 1608 | public string osGetSimulatorVersion() |
1573 | { | 1609 | { |
1574 | // High because it can be used to target attacks to known weaknesses | 1610 | // High because it can be used to target attacks to known weaknesses |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 4dd795d..d3ef378 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs | |||
@@ -42,6 +42,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
42 | { | 42 | { |
43 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 43 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
44 | 44 | ||
45 | /// <summary> | ||
46 | /// Used by one-off and repeated sensors | ||
47 | /// </summary> | ||
48 | public class SensorInfo | ||
49 | { | ||
50 | public uint localID; | ||
51 | public UUID itemID; | ||
52 | public double interval; | ||
53 | public DateTime next; | ||
54 | |||
55 | public string name; | ||
56 | public UUID keyID; | ||
57 | public int type; | ||
58 | public double range; | ||
59 | public double arc; | ||
60 | public SceneObjectPart host; | ||
61 | |||
62 | public SensorInfo Clone() | ||
63 | { | ||
64 | return (SensorInfo)this.MemberwiseClone(); | ||
65 | } | ||
66 | } | ||
67 | |||
45 | public AsyncCommandManager m_CmdManager; | 68 | public AsyncCommandManager m_CmdManager; |
46 | 69 | ||
47 | /// <summary> | 70 | /// <summary> |
@@ -78,24 +101,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
78 | private int maximumToReturn = 16; | 101 | private int maximumToReturn = 16; |
79 | 102 | ||
80 | // | 103 | // |
81 | // SenseRepeater and Sensors | ||
82 | // | ||
83 | private class SenseRepeatClass | ||
84 | { | ||
85 | public uint localID; | ||
86 | public UUID itemID; | ||
87 | public double interval; | ||
88 | public DateTime next; | ||
89 | |||
90 | public string name; | ||
91 | public UUID keyID; | ||
92 | public int type; | ||
93 | public double range; | ||
94 | public double arc; | ||
95 | public SceneObjectPart host; | ||
96 | } | ||
97 | |||
98 | // | ||
99 | // Sensed entity | 104 | // Sensed entity |
100 | // | 105 | // |
101 | private class SensedEntity : IComparable | 106 | private class SensedEntity : IComparable |
@@ -127,7 +132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
127 | /// | 132 | /// |
128 | /// Always lock SenseRepeatListLock when updating this list. | 133 | /// Always lock SenseRepeatListLock when updating this list. |
129 | /// </remarks> | 134 | /// </remarks> |
130 | private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>(); | 135 | private List<SensorInfo> SenseRepeaters = new List<SensorInfo>(); |
131 | private object SenseRepeatListLock = new object(); | 136 | private object SenseRepeatListLock = new object(); |
132 | 137 | ||
133 | public void SetSenseRepeatEvent(uint m_localID, UUID m_itemID, | 138 | public void SetSenseRepeatEvent(uint m_localID, UUID m_itemID, |
@@ -141,7 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
141 | return; | 146 | return; |
142 | 147 | ||
143 | // Add to timer | 148 | // Add to timer |
144 | SenseRepeatClass ts = new SenseRepeatClass(); | 149 | SensorInfo ts = new SensorInfo(); |
145 | ts.localID = m_localID; | 150 | ts.localID = m_localID; |
146 | ts.itemID = m_itemID; | 151 | ts.itemID = m_itemID; |
147 | ts.interval = sec; | 152 | ts.interval = sec; |
@@ -160,11 +165,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
160 | AddSenseRepeater(ts); | 165 | AddSenseRepeater(ts); |
161 | } | 166 | } |
162 | 167 | ||
163 | private void AddSenseRepeater(SenseRepeatClass senseRepeater) | 168 | private void AddSenseRepeater(SensorInfo senseRepeater) |
164 | { | 169 | { |
165 | lock (SenseRepeatListLock) | 170 | lock (SenseRepeatListLock) |
166 | { | 171 | { |
167 | List<SenseRepeatClass> newSenseRepeaters = new List<SenseRepeatClass>(SenseRepeaters); | 172 | List<SensorInfo> newSenseRepeaters = new List<SensorInfo>(SenseRepeaters); |
168 | newSenseRepeaters.Add(senseRepeater); | 173 | newSenseRepeaters.Add(senseRepeater); |
169 | SenseRepeaters = newSenseRepeaters; | 174 | SenseRepeaters = newSenseRepeaters; |
170 | } | 175 | } |
@@ -175,8 +180,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
175 | // Remove from timer | 180 | // Remove from timer |
176 | lock (SenseRepeatListLock) | 181 | lock (SenseRepeatListLock) |
177 | { | 182 | { |
178 | List<SenseRepeatClass> newSenseRepeaters = new List<SenseRepeatClass>(); | 183 | List<SensorInfo> newSenseRepeaters = new List<SensorInfo>(); |
179 | foreach (SenseRepeatClass ts in SenseRepeaters) | 184 | foreach (SensorInfo ts in SenseRepeaters) |
180 | { | 185 | { |
181 | if (ts.localID != m_localID || ts.itemID != m_itemID) | 186 | if (ts.localID != m_localID || ts.itemID != m_itemID) |
182 | { | 187 | { |
@@ -191,7 +196,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
191 | public void CheckSenseRepeaterEvents() | 196 | public void CheckSenseRepeaterEvents() |
192 | { | 197 | { |
193 | // Go through all timers | 198 | // Go through all timers |
194 | foreach (SenseRepeatClass ts in SenseRepeaters) | 199 | foreach (SensorInfo ts in SenseRepeaters) |
195 | { | 200 | { |
196 | // Time has passed? | 201 | // Time has passed? |
197 | if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) | 202 | if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) |
@@ -208,7 +213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
208 | double range, double arc, SceneObjectPart host) | 213 | double range, double arc, SceneObjectPart host) |
209 | { | 214 | { |
210 | // Add to timer | 215 | // Add to timer |
211 | SenseRepeatClass ts = new SenseRepeatClass(); | 216 | SensorInfo ts = new SensorInfo(); |
212 | ts.localID = m_localID; | 217 | ts.localID = m_localID; |
213 | ts.itemID = m_itemID; | 218 | ts.itemID = m_itemID; |
214 | ts.interval = 0; | 219 | ts.interval = 0; |
@@ -224,7 +229,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
224 | SensorSweep(ts); | 229 | SensorSweep(ts); |
225 | } | 230 | } |
226 | 231 | ||
227 | private void SensorSweep(SenseRepeatClass ts) | 232 | private void SensorSweep(SensorInfo ts) |
228 | { | 233 | { |
229 | if (ts.host == null) | 234 | if (ts.host == null) |
230 | { | 235 | { |
@@ -300,7 +305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
300 | } | 305 | } |
301 | } | 306 | } |
302 | 307 | ||
303 | private List<SensedEntity> doObjectSensor(SenseRepeatClass ts) | 308 | private List<SensedEntity> doObjectSensor(SensorInfo ts) |
304 | { | 309 | { |
305 | List<EntityBase> Entities; | 310 | List<EntityBase> Entities; |
306 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); | 311 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); |
@@ -451,7 +456,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
451 | return sensedEntities; | 456 | return sensedEntities; |
452 | } | 457 | } |
453 | 458 | ||
454 | private List<SensedEntity> doAgentSensor(SenseRepeatClass ts) | 459 | private List<SensedEntity> doAgentSensor(SensorInfo ts) |
455 | { | 460 | { |
456 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); | 461 | List<SensedEntity> sensedEntities = new List<SensedEntity>(); |
457 | 462 | ||
@@ -630,7 +635,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
630 | { | 635 | { |
631 | List<Object> data = new List<Object>(); | 636 | List<Object> data = new List<Object>(); |
632 | 637 | ||
633 | foreach (SenseRepeatClass ts in SenseRepeaters) | 638 | foreach (SensorInfo ts in SenseRepeaters) |
634 | { | 639 | { |
635 | if (ts.itemID == itemID) | 640 | if (ts.itemID == itemID) |
636 | { | 641 | { |
@@ -660,7 +665,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
660 | 665 | ||
661 | while (idx < data.Length) | 666 | while (idx < data.Length) |
662 | { | 667 | { |
663 | SenseRepeatClass ts = new SenseRepeatClass(); | 668 | SensorInfo ts = new SensorInfo(); |
664 | 669 | ||
665 | ts.localID = localID; | 670 | ts.localID = localID; |
666 | ts.itemID = itemID; | 671 | ts.itemID = itemID; |
@@ -681,5 +686,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
681 | idx += 6; | 686 | idx += 6; |
682 | } | 687 | } |
683 | } | 688 | } |
689 | |||
690 | public List<SensorInfo> GetSensorInfo() | ||
691 | { | ||
692 | List<SensorInfo> retList = new List<SensorInfo>(); | ||
693 | |||
694 | lock (SenseRepeatListLock) | ||
695 | { | ||
696 | foreach (SensorInfo i in SenseRepeaters) | ||
697 | retList.Add(i.Clone()); | ||
698 | } | ||
699 | |||
700 | return retList; | ||
701 | } | ||
684 | } | 702 | } |
685 | } | 703 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs index 9ee6946..68aacd2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs | |||
@@ -35,6 +35,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
35 | { | 35 | { |
36 | public class Timer | 36 | public class Timer |
37 | { | 37 | { |
38 | public class TimerInfo | ||
39 | { | ||
40 | public uint localID; | ||
41 | public UUID itemID; | ||
42 | //public double interval; | ||
43 | public long interval; | ||
44 | //public DateTime next; | ||
45 | public long next; | ||
46 | |||
47 | public TimerInfo Clone() | ||
48 | { | ||
49 | return (TimerInfo)this.MemberwiseClone(); | ||
50 | } | ||
51 | } | ||
52 | |||
38 | public AsyncCommandManager m_CmdManager; | 53 | public AsyncCommandManager m_CmdManager; |
39 | 54 | ||
40 | public int TimersCount | 55 | public int TimersCount |
@@ -59,17 +74,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
59 | return localID.ToString() + itemID.ToString(); | 74 | return localID.ToString() + itemID.ToString(); |
60 | } | 75 | } |
61 | 76 | ||
62 | private class TimerClass | 77 | private Dictionary<string,TimerInfo> Timers = new Dictionary<string,TimerInfo>(); |
63 | { | ||
64 | public uint localID; | ||
65 | public UUID itemID; | ||
66 | //public double interval; | ||
67 | public long interval; | ||
68 | //public DateTime next; | ||
69 | public long next; | ||
70 | } | ||
71 | |||
72 | private Dictionary<string,TimerClass> Timers = new Dictionary<string,TimerClass>(); | ||
73 | private object TimerListLock = new object(); | 78 | private object TimerListLock = new object(); |
74 | 79 | ||
75 | public void SetTimerEvent(uint m_localID, UUID m_itemID, double sec) | 80 | public void SetTimerEvent(uint m_localID, UUID m_itemID, double sec) |
@@ -81,7 +86,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
81 | } | 86 | } |
82 | 87 | ||
83 | // Add to timer | 88 | // Add to timer |
84 | TimerClass ts = new TimerClass(); | 89 | TimerInfo ts = new TimerInfo(); |
85 | ts.localID = m_localID; | 90 | ts.localID = m_localID; |
86 | ts.itemID = m_itemID; | 91 | ts.itemID = m_itemID; |
87 | ts.interval = Convert.ToInt64(sec * 10000000); // How many 100 nanoseconds (ticks) should we wait | 92 | ts.interval = Convert.ToInt64(sec * 10000000); // How many 100 nanoseconds (ticks) should we wait |
@@ -118,14 +123,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
118 | if (Timers.Count == 0) | 123 | if (Timers.Count == 0) |
119 | return; | 124 | return; |
120 | 125 | ||
121 | Dictionary<string, TimerClass>.ValueCollection tvals; | 126 | Dictionary<string, TimerInfo>.ValueCollection tvals; |
122 | lock (TimerListLock) | 127 | lock (TimerListLock) |
123 | { | 128 | { |
124 | // Go through all timers | 129 | // Go through all timers |
125 | tvals = Timers.Values; | 130 | tvals = Timers.Values; |
126 | } | 131 | } |
127 | 132 | ||
128 | foreach (TimerClass ts in tvals) | 133 | foreach (TimerInfo ts in tvals) |
129 | { | 134 | { |
130 | // Time has passed? | 135 | // Time has passed? |
131 | if (ts.next < DateTime.Now.Ticks) | 136 | if (ts.next < DateTime.Now.Ticks) |
@@ -149,8 +154,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
149 | 154 | ||
150 | lock (TimerListLock) | 155 | lock (TimerListLock) |
151 | { | 156 | { |
152 | Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; | 157 | Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; |
153 | foreach (TimerClass ts in tvals) | 158 | foreach (TimerInfo ts in tvals) |
154 | { | 159 | { |
155 | if (ts.itemID == itemID) | 160 | if (ts.itemID == itemID) |
156 | { | 161 | { |
@@ -169,7 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
169 | 174 | ||
170 | while (idx < data.Length) | 175 | while (idx < data.Length) |
171 | { | 176 | { |
172 | TimerClass ts = new TimerClass(); | 177 | TimerInfo ts = new TimerInfo(); |
173 | 178 | ||
174 | ts.localID = localID; | 179 | ts.localID = localID; |
175 | ts.itemID = itemID; | 180 | ts.itemID = itemID; |
@@ -183,5 +188,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
183 | } | 188 | } |
184 | } | 189 | } |
185 | } | 190 | } |
191 | |||
192 | public List<TimerInfo> GetTimersInfo() | ||
193 | { | ||
194 | List<TimerInfo> retList = new List<TimerInfo>(); | ||
195 | |||
196 | lock (TimerListLock) | ||
197 | { | ||
198 | foreach (TimerInfo i in Timers.Values) | ||
199 | retList.Add(i.Clone()); | ||
200 | } | ||
201 | |||
202 | return retList; | ||
203 | } | ||
186 | } | 204 | } |
187 | } | 205 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index c447d1f..7eb347e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | |||
@@ -259,6 +259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
259 | 259 | ||
260 | string osGetScriptEngineName(); | 260 | string osGetScriptEngineName(); |
261 | string osGetSimulatorVersion(); | 261 | string osGetSimulatorVersion(); |
262 | string osGetPhysicsEngineType(); | ||
262 | Object osParseJSONNew(string JSON); | 263 | Object osParseJSONNew(string JSON); |
263 | Hashtable osParseJSON(string JSON); | 264 | Hashtable osParseJSON(string JSON); |
264 | 265 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 0dd5a57..da3b31f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | |||
@@ -557,6 +557,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
557 | public const int OBJECT_SERVER_COST = 14; | 557 | public const int OBJECT_SERVER_COST = 14; |
558 | public const int OBJECT_STREAMING_COST = 15; | 558 | public const int OBJECT_STREAMING_COST = 15; |
559 | public const int OBJECT_PHYSICS_COST = 16; | 559 | public const int OBJECT_PHYSICS_COST = 16; |
560 | public const int OBJECT_CHARACTER_TIME = 17; | ||
561 | public const int OBJECT_ROOT = 18; | ||
562 | public const int OBJECT_ATTACHED_POINT = 19; | ||
563 | public const int OBJECT_PATHFINDING_TYPE = 20; | ||
564 | public const int OBJECT_PHYSICS = 21; | ||
565 | public const int OBJECT_PHANTOM = 22; | ||
566 | public const int OBJECT_TEMP_ON_REZ = 23; | ||
567 | |||
568 | // Pathfinding types | ||
569 | public const int OPT_OTHER = -1; | ||
570 | public const int OPT_LEGACY_LINKSET = 0; | ||
571 | public const int OPT_AVATAR = 1; | ||
572 | public const int OPT_CHARACTER = 2; | ||
573 | public const int OPT_WALKABLE = 3; | ||
574 | public const int OPT_STATIC_OBSTACLE = 4; | ||
575 | public const int OPT_MATERIAL_VOLUME = 5; | ||
576 | public const int OPT_EXCLUSION_VOLUME = 6; | ||
560 | 577 | ||
561 | // for llGetAgentList | 578 | // for llGetAgentList |
562 | public const int AGENT_LIST_PARCEL = 1; | 579 | public const int AGENT_LIST_PARCEL = 1; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index afa9ae0..c9902e4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | |||
@@ -420,6 +420,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
420 | return m_OSSL_Functions.osGetScriptEngineName(); | 420 | return m_OSSL_Functions.osGetScriptEngineName(); |
421 | } | 421 | } |
422 | 422 | ||
423 | public string osGetPhysicsEngineType() | ||
424 | { | ||
425 | return m_OSSL_Functions.osGetPhysicsEngineType(); | ||
426 | } | ||
427 | |||
423 | public string osGetSimulatorVersion() | 428 | public string osGetSimulatorVersion() |
424 | { | 429 | { |
425 | return m_OSSL_Functions.osGetSimulatorVersion(); | 430 | return m_OSSL_Functions.osGetSimulatorVersion(); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 97dd0f6..9e32f40 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs | |||
@@ -31,7 +31,6 @@ using System.Collections.Generic; | |||
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using log4net; | 32 | using log4net; |
33 | using Tools; | 33 | using Tools; |
34 | |||
35 | using OpenSim.Region.Framework.Interfaces; | 34 | using OpenSim.Region.Framework.Interfaces; |
36 | 35 | ||
37 | namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | 36 | namespace OpenSim.Region.ScriptEngine.Shared.CodeTools |
@@ -49,6 +48,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
49 | private List<string> m_warnings = new List<string>(); | 48 | private List<string> m_warnings = new List<string>(); |
50 | private IScriptModuleComms m_comms = null; | 49 | private IScriptModuleComms m_comms = null; |
51 | 50 | ||
51 | private bool m_insertCoopTerminationChecks; | ||
52 | private static string m_coopTerminationCheck = "opensim_reserved_CheckForCoopTermination();"; | ||
53 | |||
54 | /// <summary> | ||
55 | /// Keep a record of the previous node when we do the parsing. | ||
56 | /// </summary> | ||
57 | /// <remarks> | ||
58 | /// We do this here because the parser generated by CSTools does not retain a reference to its parent node. | ||
59 | /// The previous node is required so we can correctly insert co-op termination checks when required. | ||
60 | /// </remarks> | ||
61 | // private SYMBOL m_previousNode; | ||
62 | |||
52 | /// <summary> | 63 | /// <summary> |
53 | /// Creates an 'empty' CSCodeGenerator instance. | 64 | /// Creates an 'empty' CSCodeGenerator instance. |
54 | /// </summary> | 65 | /// </summary> |
@@ -58,9 +69,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
58 | ResetCounters(); | 69 | ResetCounters(); |
59 | } | 70 | } |
60 | 71 | ||
61 | public CSCodeGenerator(IScriptModuleComms comms) | 72 | public CSCodeGenerator(IScriptModuleComms comms, bool insertCoopTerminationChecks) |
62 | { | 73 | { |
63 | m_comms = comms; | 74 | m_comms = comms; |
75 | m_insertCoopTerminationChecks = insertCoopTerminationChecks; | ||
64 | ResetCounters(); | 76 | ResetCounters(); |
65 | } | 77 | } |
66 | 78 | ||
@@ -155,7 +167,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
155 | // here's the payload | 167 | // here's the payload |
156 | retstr += GenerateLine(); | 168 | retstr += GenerateLine(); |
157 | foreach (SYMBOL s in m_astRoot.kids) | 169 | foreach (SYMBOL s in m_astRoot.kids) |
158 | retstr += GenerateNode(s); | 170 | retstr += GenerateNode(m_astRoot, s); |
159 | 171 | ||
160 | // close braces! | 172 | // close braces! |
161 | m_braceCount--; | 173 | m_braceCount--; |
@@ -165,7 +177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
165 | 177 | ||
166 | // Removes all carriage return characters which may be generated in Windows platform. Is there | 178 | // Removes all carriage return characters which may be generated in Windows platform. Is there |
167 | // cleaner way of doing this? | 179 | // cleaner way of doing this? |
168 | retstr=retstr.Replace("\r", ""); | 180 | retstr = retstr.Replace("\r", ""); |
169 | 181 | ||
170 | return retstr; | 182 | return retstr; |
171 | } | 183 | } |
@@ -191,9 +203,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
191 | /// Recursively called to generate each type of node. Will generate this | 203 | /// Recursively called to generate each type of node. Will generate this |
192 | /// node, then all it's children. | 204 | /// node, then all it's children. |
193 | /// </summary> | 205 | /// </summary> |
206 | /// <param name="previousSymbol">The parent node.</param> | ||
194 | /// <param name="s">The current node to generate code for.</param> | 207 | /// <param name="s">The current node to generate code for.</param> |
195 | /// <returns>String containing C# code for SYMBOL s.</returns> | 208 | /// <returns>String containing C# code for SYMBOL s.</returns> |
196 | private string GenerateNode(SYMBOL s) | 209 | private string GenerateNode(SYMBOL previousSymbol, SYMBOL s) |
197 | { | 210 | { |
198 | string retstr = String.Empty; | 211 | string retstr = String.Empty; |
199 | 212 | ||
@@ -207,11 +220,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
207 | else if (s is State) | 220 | else if (s is State) |
208 | retstr += GenerateState((State) s); | 221 | retstr += GenerateState((State) s); |
209 | else if (s is CompoundStatement) | 222 | else if (s is CompoundStatement) |
210 | retstr += GenerateCompoundStatement((CompoundStatement) s); | 223 | retstr += GenerateCompoundStatement(previousSymbol, (CompoundStatement) s); |
211 | else if (s is Declaration) | 224 | else if (s is Declaration) |
212 | retstr += GenerateDeclaration((Declaration) s); | 225 | retstr += GenerateDeclaration((Declaration) s); |
213 | else if (s is Statement) | 226 | else if (s is Statement) |
214 | retstr += GenerateStatement((Statement) s); | 227 | retstr += GenerateStatement(previousSymbol, (Statement) s); |
215 | else if (s is ReturnStatement) | 228 | else if (s is ReturnStatement) |
216 | retstr += GenerateReturnStatement((ReturnStatement) s); | 229 | retstr += GenerateReturnStatement((ReturnStatement) s); |
217 | else if (s is JumpLabel) | 230 | else if (s is JumpLabel) |
@@ -261,7 +274,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
261 | else | 274 | else |
262 | { | 275 | { |
263 | foreach (SYMBOL kid in s.kids) | 276 | foreach (SYMBOL kid in s.kids) |
264 | retstr += GenerateNode(kid); | 277 | retstr += GenerateNode(s, kid); |
265 | } | 278 | } |
266 | 279 | ||
267 | return retstr; | 280 | return retstr; |
@@ -295,7 +308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
295 | retstr += GenerateLine(")"); | 308 | retstr += GenerateLine(")"); |
296 | 309 | ||
297 | foreach (SYMBOL kid in remainingKids) | 310 | foreach (SYMBOL kid in remainingKids) |
298 | retstr += GenerateNode(kid); | 311 | retstr += GenerateNode(gf, kid); |
299 | 312 | ||
300 | return retstr; | 313 | return retstr; |
301 | } | 314 | } |
@@ -312,7 +325,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
312 | foreach (SYMBOL s in gv.kids) | 325 | foreach (SYMBOL s in gv.kids) |
313 | { | 326 | { |
314 | retstr += Indent(); | 327 | retstr += Indent(); |
315 | retstr += GenerateNode(s); | 328 | retstr += GenerateNode(gv, s); |
316 | retstr += GenerateLine(";"); | 329 | retstr += GenerateLine(";"); |
317 | } | 330 | } |
318 | 331 | ||
@@ -365,7 +378,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
365 | retstr += GenerateLine(")"); | 378 | retstr += GenerateLine(")"); |
366 | 379 | ||
367 | foreach (SYMBOL kid in remainingKids) | 380 | foreach (SYMBOL kid in remainingKids) |
368 | retstr += GenerateNode(kid); | 381 | retstr += GenerateNode(se, kid); |
369 | 382 | ||
370 | return retstr; | 383 | return retstr; |
371 | } | 384 | } |
@@ -404,7 +417,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
404 | 417 | ||
405 | foreach (SYMBOL s in al.kids) | 418 | foreach (SYMBOL s in al.kids) |
406 | { | 419 | { |
407 | retstr += GenerateNode(s); | 420 | retstr += GenerateNode(al, s); |
408 | if (0 < comma--) | 421 | if (0 < comma--) |
409 | retstr += Generate(", "); | 422 | retstr += Generate(", "); |
410 | } | 423 | } |
@@ -417,7 +430,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
417 | /// </summary> | 430 | /// </summary> |
418 | /// <param name="cs">The CompoundStatement node.</param> | 431 | /// <param name="cs">The CompoundStatement node.</param> |
419 | /// <returns>String containing C# code for CompoundStatement cs.</returns> | 432 | /// <returns>String containing C# code for CompoundStatement cs.</returns> |
420 | private string GenerateCompoundStatement(CompoundStatement cs) | 433 | private string GenerateCompoundStatement(SYMBOL previousSymbol, CompoundStatement cs) |
421 | { | 434 | { |
422 | string retstr = String.Empty; | 435 | string retstr = String.Empty; |
423 | 436 | ||
@@ -425,8 +438,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
425 | retstr += GenerateIndentedLine("{"); | 438 | retstr += GenerateIndentedLine("{"); |
426 | m_braceCount++; | 439 | m_braceCount++; |
427 | 440 | ||
441 | if (m_insertCoopTerminationChecks) | ||
442 | { | ||
443 | // We have to check in event functions as well because the user can manually call these. | ||
444 | if (previousSymbol is GlobalFunctionDefinition | ||
445 | || previousSymbol is WhileStatement | ||
446 | || previousSymbol is DoWhileStatement | ||
447 | || previousSymbol is ForLoop | ||
448 | || previousSymbol is StateEvent) | ||
449 | retstr += GenerateIndentedLine(m_coopTerminationCheck); | ||
450 | } | ||
451 | |||
428 | foreach (SYMBOL kid in cs.kids) | 452 | foreach (SYMBOL kid in cs.kids) |
429 | retstr += GenerateNode(kid); | 453 | retstr += GenerateNode(cs, kid); |
430 | 454 | ||
431 | // closing brace | 455 | // closing brace |
432 | m_braceCount--; | 456 | m_braceCount--; |
@@ -450,10 +474,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
450 | /// </summary> | 474 | /// </summary> |
451 | /// <param name="s">The Statement node.</param> | 475 | /// <param name="s">The Statement node.</param> |
452 | /// <returns>String containing C# code for Statement s.</returns> | 476 | /// <returns>String containing C# code for Statement s.</returns> |
453 | private string GenerateStatement(Statement s) | 477 | private string GenerateStatement(SYMBOL previousSymbol, Statement s) |
454 | { | 478 | { |
455 | string retstr = String.Empty; | 479 | string retstr = String.Empty; |
456 | bool printSemicolon = true; | 480 | bool printSemicolon = true; |
481 | bool transformToBlock = false; | ||
482 | |||
483 | if (m_insertCoopTerminationChecks) | ||
484 | { | ||
485 | // A non-braced single line do while structure cannot contain multiple statements. | ||
486 | // So to insert the termination check we change this to a braced control structure instead. | ||
487 | if (previousSymbol is WhileStatement | ||
488 | || previousSymbol is DoWhileStatement | ||
489 | || previousSymbol is ForLoop) | ||
490 | { | ||
491 | transformToBlock = true; | ||
492 | |||
493 | // FIXME: This will be wrongly indented because the previous for/while/dowhile will have already indented. | ||
494 | retstr += GenerateIndentedLine("{"); | ||
495 | |||
496 | retstr += GenerateIndentedLine(m_coopTerminationCheck); | ||
497 | } | ||
498 | } | ||
457 | 499 | ||
458 | retstr += Indent(); | 500 | retstr += Indent(); |
459 | 501 | ||
@@ -466,12 +508,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
466 | // (MONO) error. | 508 | // (MONO) error. |
467 | if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count)) | 509 | if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count)) |
468 | foreach (SYMBOL kid in s.kids) | 510 | foreach (SYMBOL kid in s.kids) |
469 | retstr += GenerateNode(kid); | 511 | retstr += GenerateNode(s, kid); |
470 | } | 512 | } |
471 | 513 | ||
472 | if (printSemicolon) | 514 | if (printSemicolon) |
473 | retstr += GenerateLine(";"); | 515 | retstr += GenerateLine(";"); |
474 | 516 | ||
517 | if (transformToBlock) | ||
518 | { | ||
519 | // FIXME: This will be wrongly indented because the for/while/dowhile is currently handling the unindent | ||
520 | retstr += GenerateIndentedLine("}"); | ||
521 | } | ||
522 | |||
475 | return retstr; | 523 | return retstr; |
476 | } | 524 | } |
477 | 525 | ||
@@ -487,10 +535,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
487 | List<string> identifiers = new List<string>(); | 535 | List<string> identifiers = new List<string>(); |
488 | checkForMultipleAssignments(identifiers, a); | 536 | checkForMultipleAssignments(identifiers, a); |
489 | 537 | ||
490 | retstr += GenerateNode((SYMBOL) a.kids.Pop()); | 538 | retstr += GenerateNode(a, (SYMBOL) a.kids.Pop()); |
491 | retstr += Generate(String.Format(" {0} ", a.AssignmentType), a); | 539 | retstr += Generate(String.Format(" {0} ", a.AssignmentType), a); |
492 | foreach (SYMBOL kid in a.kids) | 540 | foreach (SYMBOL kid in a.kids) |
493 | retstr += GenerateNode(kid); | 541 | retstr += GenerateNode(a, kid); |
494 | 542 | ||
495 | return retstr; | 543 | return retstr; |
496 | } | 544 | } |
@@ -563,7 +611,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
563 | retstr += Generate("return ", rs); | 611 | retstr += Generate("return ", rs); |
564 | 612 | ||
565 | foreach (SYMBOL kid in rs.kids) | 613 | foreach (SYMBOL kid in rs.kids) |
566 | retstr += GenerateNode(kid); | 614 | retstr += GenerateNode(rs, kid); |
567 | 615 | ||
568 | return retstr; | 616 | return retstr; |
569 | } | 617 | } |
@@ -575,7 +623,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
575 | /// <returns>String containing C# code for JumpLabel jl.</returns> | 623 | /// <returns>String containing C# code for JumpLabel jl.</returns> |
576 | private string GenerateJumpLabel(JumpLabel jl) | 624 | private string GenerateJumpLabel(JumpLabel jl) |
577 | { | 625 | { |
578 | return Generate(String.Format("{0}:", CheckName(jl.LabelName)), jl) + " NoOp();\n"; | 626 | string labelStatement; |
627 | |||
628 | if (m_insertCoopTerminationChecks) | ||
629 | labelStatement = m_coopTerminationCheck + "\n"; | ||
630 | else | ||
631 | labelStatement = "NoOp();\n"; | ||
632 | |||
633 | return Generate(String.Format("{0}: ", CheckName(jl.LabelName)), jl) + labelStatement; | ||
579 | } | 634 | } |
580 | 635 | ||
581 | /// <summary> | 636 | /// <summary> |
@@ -598,14 +653,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
598 | string retstr = String.Empty; | 653 | string retstr = String.Empty; |
599 | 654 | ||
600 | retstr += GenerateIndented("if (", ifs); | 655 | retstr += GenerateIndented("if (", ifs); |
601 | retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); | 656 | retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); |
602 | retstr += GenerateLine(")"); | 657 | retstr += GenerateLine(")"); |
603 | 658 | ||
604 | // CompoundStatement handles indentation itself but we need to do it | 659 | // CompoundStatement handles indentation itself but we need to do it |
605 | // otherwise. | 660 | // otherwise. |
606 | bool indentHere = ifs.kids.Top is Statement; | 661 | bool indentHere = ifs.kids.Top is Statement; |
607 | if (indentHere) m_braceCount++; | 662 | if (indentHere) m_braceCount++; |
608 | retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); | 663 | retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); |
609 | if (indentHere) m_braceCount--; | 664 | if (indentHere) m_braceCount--; |
610 | 665 | ||
611 | if (0 < ifs.kids.Count) // do it again for an else | 666 | if (0 < ifs.kids.Count) // do it again for an else |
@@ -614,7 +669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
614 | 669 | ||
615 | indentHere = ifs.kids.Top is Statement; | 670 | indentHere = ifs.kids.Top is Statement; |
616 | if (indentHere) m_braceCount++; | 671 | if (indentHere) m_braceCount++; |
617 | retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); | 672 | retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); |
618 | if (indentHere) m_braceCount--; | 673 | if (indentHere) m_braceCount--; |
619 | } | 674 | } |
620 | 675 | ||
@@ -641,14 +696,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
641 | string retstr = String.Empty; | 696 | string retstr = String.Empty; |
642 | 697 | ||
643 | retstr += GenerateIndented("while (", ws); | 698 | retstr += GenerateIndented("while (", ws); |
644 | retstr += GenerateNode((SYMBOL) ws.kids.Pop()); | 699 | retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop()); |
645 | retstr += GenerateLine(")"); | 700 | retstr += GenerateLine(")"); |
646 | 701 | ||
647 | // CompoundStatement handles indentation itself but we need to do it | 702 | // CompoundStatement handles indentation itself but we need to do it |
648 | // otherwise. | 703 | // otherwise. |
649 | bool indentHere = ws.kids.Top is Statement; | 704 | bool indentHere = ws.kids.Top is Statement; |
650 | if (indentHere) m_braceCount++; | 705 | if (indentHere) m_braceCount++; |
651 | retstr += GenerateNode((SYMBOL) ws.kids.Pop()); | 706 | retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop()); |
652 | if (indentHere) m_braceCount--; | 707 | if (indentHere) m_braceCount--; |
653 | 708 | ||
654 | return retstr; | 709 | return retstr; |
@@ -669,11 +724,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
669 | // otherwise. | 724 | // otherwise. |
670 | bool indentHere = dws.kids.Top is Statement; | 725 | bool indentHere = dws.kids.Top is Statement; |
671 | if (indentHere) m_braceCount++; | 726 | if (indentHere) m_braceCount++; |
672 | retstr += GenerateNode((SYMBOL) dws.kids.Pop()); | 727 | retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop()); |
673 | if (indentHere) m_braceCount--; | 728 | if (indentHere) m_braceCount--; |
674 | 729 | ||
675 | retstr += GenerateIndented("while (", dws); | 730 | retstr += GenerateIndented("while (", dws); |
676 | retstr += GenerateNode((SYMBOL) dws.kids.Pop()); | 731 | retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop()); |
677 | retstr += GenerateLine(");"); | 732 | retstr += GenerateLine(");"); |
678 | 733 | ||
679 | return retstr; | 734 | return retstr; |
@@ -702,7 +757,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
702 | retstr += Generate("; "); | 757 | retstr += Generate("; "); |
703 | // for (x = 0; x < 10; x++) | 758 | // for (x = 0; x < 10; x++) |
704 | // ^^^^^^ | 759 | // ^^^^^^ |
705 | retstr += GenerateNode((SYMBOL) fl.kids.Pop()); | 760 | retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop()); |
706 | retstr += Generate("; "); | 761 | retstr += Generate("; "); |
707 | // for (x = 0; x < 10; x++) | 762 | // for (x = 0; x < 10; x++) |
708 | // ^^^ | 763 | // ^^^ |
@@ -713,7 +768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
713 | // otherwise. | 768 | // otherwise. |
714 | bool indentHere = fl.kids.Top is Statement; | 769 | bool indentHere = fl.kids.Top is Statement; |
715 | if (indentHere) m_braceCount++; | 770 | if (indentHere) m_braceCount++; |
716 | retstr += GenerateNode((SYMBOL) fl.kids.Pop()); | 771 | retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop()); |
717 | if (indentHere) m_braceCount--; | 772 | if (indentHere) m_braceCount--; |
718 | 773 | ||
719 | return retstr; | 774 | return retstr; |
@@ -758,7 +813,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
758 | while (s is ParenthesisExpression) | 813 | while (s is ParenthesisExpression) |
759 | s = (SYMBOL)s.kids.Pop(); | 814 | s = (SYMBOL)s.kids.Pop(); |
760 | 815 | ||
761 | retstr += GenerateNode(s); | 816 | retstr += GenerateNode(fls, s); |
762 | if (0 < comma--) | 817 | if (0 < comma--) |
763 | retstr += Generate(", "); | 818 | retstr += Generate(", "); |
764 | } | 819 | } |
@@ -779,20 +834,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
779 | { | 834 | { |
780 | // special case handling for logical and/or, see Mantis 3174 | 835 | // special case handling for logical and/or, see Mantis 3174 |
781 | retstr += "((bool)("; | 836 | retstr += "((bool)("; |
782 | retstr += GenerateNode((SYMBOL)be.kids.Pop()); | 837 | retstr += GenerateNode(be, (SYMBOL)be.kids.Pop()); |
783 | retstr += "))"; | 838 | retstr += "))"; |
784 | retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0,1)), be); | 839 | retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0,1)), be); |
785 | retstr += "((bool)("; | 840 | retstr += "((bool)("; |
786 | foreach (SYMBOL kid in be.kids) | 841 | foreach (SYMBOL kid in be.kids) |
787 | retstr += GenerateNode(kid); | 842 | retstr += GenerateNode(be, kid); |
788 | retstr += "))"; | 843 | retstr += "))"; |
789 | } | 844 | } |
790 | else | 845 | else |
791 | { | 846 | { |
792 | retstr += GenerateNode((SYMBOL)be.kids.Pop()); | 847 | retstr += GenerateNode(be, (SYMBOL)be.kids.Pop()); |
793 | retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); | 848 | retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); |
794 | foreach (SYMBOL kid in be.kids) | 849 | foreach (SYMBOL kid in be.kids) |
795 | retstr += GenerateNode(kid); | 850 | retstr += GenerateNode(be, kid); |
796 | } | 851 | } |
797 | 852 | ||
798 | return retstr; | 853 | return retstr; |
@@ -808,7 +863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
808 | string retstr = String.Empty; | 863 | string retstr = String.Empty; |
809 | 864 | ||
810 | retstr += Generate(ue.UnarySymbol, ue); | 865 | retstr += Generate(ue.UnarySymbol, ue); |
811 | retstr += GenerateNode((SYMBOL) ue.kids.Pop()); | 866 | retstr += GenerateNode(ue, (SYMBOL) ue.kids.Pop()); |
812 | 867 | ||
813 | return retstr; | 868 | return retstr; |
814 | } | 869 | } |
@@ -824,7 +879,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
824 | 879 | ||
825 | retstr += Generate("("); | 880 | retstr += Generate("("); |
826 | foreach (SYMBOL kid in pe.kids) | 881 | foreach (SYMBOL kid in pe.kids) |
827 | retstr += GenerateNode(kid); | 882 | retstr += GenerateNode(pe, kid); |
828 | retstr += Generate(")"); | 883 | retstr += Generate(")"); |
829 | 884 | ||
830 | return retstr; | 885 | return retstr; |
@@ -861,7 +916,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
861 | 916 | ||
862 | // we wrap all typecasted statements in parentheses | 917 | // we wrap all typecasted statements in parentheses |
863 | retstr += Generate(String.Format("({0}) (", te.TypecastType), te); | 918 | retstr += Generate(String.Format("({0}) (", te.TypecastType), te); |
864 | retstr += GenerateNode((SYMBOL) te.kids.Pop()); | 919 | retstr += GenerateNode(te, (SYMBOL) te.kids.Pop()); |
865 | retstr += Generate(")"); | 920 | retstr += Generate(")"); |
866 | 921 | ||
867 | return retstr; | 922 | return retstr; |
@@ -931,7 +986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
931 | } | 986 | } |
932 | 987 | ||
933 | foreach (SYMBOL kid in fc.kids) | 988 | foreach (SYMBOL kid in fc.kids) |
934 | retstr += GenerateNode(kid); | 989 | retstr += GenerateNode(fc, kid); |
935 | 990 | ||
936 | retstr += Generate(")"); | 991 | retstr += Generate(")"); |
937 | 992 | ||
@@ -980,11 +1035,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
980 | string retstr = String.Empty; | 1035 | string retstr = String.Empty; |
981 | 1036 | ||
982 | retstr += Generate(String.Format("new {0}(", vc.Type), vc); | 1037 | retstr += Generate(String.Format("new {0}(", vc.Type), vc); |
983 | retstr += GenerateNode((SYMBOL) vc.kids.Pop()); | 1038 | retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); |
984 | retstr += Generate(", "); | 1039 | retstr += Generate(", "); |
985 | retstr += GenerateNode((SYMBOL) vc.kids.Pop()); | 1040 | retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); |
986 | retstr += Generate(", "); | 1041 | retstr += Generate(", "); |
987 | retstr += GenerateNode((SYMBOL) vc.kids.Pop()); | 1042 | retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); |
988 | retstr += Generate(")"); | 1043 | retstr += Generate(")"); |
989 | 1044 | ||
990 | return retstr; | 1045 | return retstr; |
@@ -1000,13 +1055,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
1000 | string retstr = String.Empty; | 1055 | string retstr = String.Empty; |
1001 | 1056 | ||
1002 | retstr += Generate(String.Format("new {0}(", rc.Type), rc); | 1057 | retstr += Generate(String.Format("new {0}(", rc.Type), rc); |
1003 | retstr += GenerateNode((SYMBOL) rc.kids.Pop()); | 1058 | retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); |
1004 | retstr += Generate(", "); | 1059 | retstr += Generate(", "); |
1005 | retstr += GenerateNode((SYMBOL) rc.kids.Pop()); | 1060 | retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); |
1006 | retstr += Generate(", "); | 1061 | retstr += Generate(", "); |
1007 | retstr += GenerateNode((SYMBOL) rc.kids.Pop()); | 1062 | retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); |
1008 | retstr += Generate(", "); | 1063 | retstr += Generate(", "); |
1009 | retstr += GenerateNode((SYMBOL) rc.kids.Pop()); | 1064 | retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); |
1010 | retstr += Generate(")"); | 1065 | retstr += Generate(")"); |
1011 | 1066 | ||
1012 | return retstr; | 1067 | return retstr; |
@@ -1024,7 +1079,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
1024 | retstr += Generate(String.Format("new {0}(", lc.Type), lc); | 1079 | retstr += Generate(String.Format("new {0}(", lc.Type), lc); |
1025 | 1080 | ||
1026 | foreach (SYMBOL kid in lc.kids) | 1081 | foreach (SYMBOL kid in lc.kids) |
1027 | retstr += GenerateNode(kid); | 1082 | retstr += GenerateNode(lc, kid); |
1028 | 1083 | ||
1029 | retstr += Generate(")"); | 1084 | retstr += Generate(")"); |
1030 | 1085 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 03be2ab..9d20c9e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs | |||
@@ -72,6 +72,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
72 | private bool CompileWithDebugInformation; | 72 | private bool CompileWithDebugInformation; |
73 | private Dictionary<string, bool> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase); | 73 | private Dictionary<string, bool> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase); |
74 | private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase); | 74 | private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase); |
75 | private bool m_insertCoopTerminationCalls; | ||
75 | 76 | ||
76 | private string FilePrefix; | 77 | private string FilePrefix; |
77 | private string ScriptEnginesPath = null; | 78 | private string ScriptEnginesPath = null; |
@@ -95,20 +96,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
95 | private Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>> m_lineMaps = | 96 | private Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>> m_lineMaps = |
96 | new Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>>(); | 97 | new Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>>(); |
97 | 98 | ||
99 | public bool in_startup = true; | ||
100 | |||
98 | public Compiler(IScriptEngine scriptEngine) | 101 | public Compiler(IScriptEngine scriptEngine) |
99 | { | 102 | { |
100 | m_scriptEngine = scriptEngine;; | 103 | m_scriptEngine = scriptEngine; |
101 | ScriptEnginesPath = scriptEngine.ScriptEnginePath; | 104 | ScriptEnginesPath = scriptEngine.ScriptEnginePath; |
102 | ReadConfig(); | 105 | ReadConfig(); |
103 | } | 106 | } |
104 | 107 | ||
105 | public bool in_startup = true; | ||
106 | public void ReadConfig() | 108 | public void ReadConfig() |
107 | { | 109 | { |
108 | // Get some config | 110 | // Get some config |
109 | WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false); | 111 | WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false); |
110 | CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); | 112 | CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); |
111 | bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true); | 113 | bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true); |
114 | m_insertCoopTerminationCalls = m_scriptEngine.Config.GetString("ScriptStopStrategy", "abort") == "co-op"; | ||
112 | 115 | ||
113 | // Get file prefix from scriptengine name and make it file system safe: | 116 | // Get file prefix from scriptengine name and make it file system safe: |
114 | FilePrefix = "CommonCompiler"; | 117 | FilePrefix = "CommonCompiler"; |
@@ -386,7 +389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
386 | if (language == enumCompileType.lsl) | 389 | if (language == enumCompileType.lsl) |
387 | { | 390 | { |
388 | // Its LSL, convert it to C# | 391 | // Its LSL, convert it to C# |
389 | LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms); | 392 | LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms, m_insertCoopTerminationCalls); |
390 | compileScript = LSL_Converter.Convert(Script); | 393 | compileScript = LSL_Converter.Convert(Script); |
391 | 394 | ||
392 | // copy converter warnings into our warnings. | 395 | // copy converter warnings into our warnings. |
@@ -411,16 +414,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
411 | { | 414 | { |
412 | case enumCompileType.cs: | 415 | case enumCompileType.cs: |
413 | case enumCompileType.lsl: | 416 | case enumCompileType.lsl: |
414 | compileScript = CreateCSCompilerScript(compileScript); | 417 | compileScript = CreateCSCompilerScript( |
418 | compileScript, | ||
419 | m_scriptEngine.ScriptClassName, | ||
420 | m_scriptEngine.ScriptBaseClassName, | ||
421 | m_scriptEngine.ScriptBaseClassParameters); | ||
415 | break; | 422 | break; |
416 | case enumCompileType.vb: | 423 | case enumCompileType.vb: |
417 | compileScript = CreateVBCompilerScript(compileScript); | 424 | compileScript = CreateVBCompilerScript( |
425 | compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName); | ||
418 | break; | 426 | break; |
419 | // case enumCompileType.js: | 427 | // case enumCompileType.js: |
420 | // compileScript = CreateJSCompilerScript(compileScript); | 428 | // compileScript = CreateJSCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); |
421 | // break; | 429 | // break; |
422 | case enumCompileType.yp: | 430 | case enumCompileType.yp: |
423 | compileScript = CreateYPCompilerScript(compileScript); | 431 | compileScript = CreateYPCompilerScript( |
432 | compileScript, m_scriptEngine.ScriptClassName,m_scriptEngine.ScriptBaseClassName); | ||
424 | break; | 433 | break; |
425 | } | 434 | } |
426 | 435 | ||
@@ -451,43 +460,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
451 | // return compileScript; | 460 | // return compileScript; |
452 | // } | 461 | // } |
453 | 462 | ||
454 | private static string CreateCSCompilerScript(string compileScript) | 463 | private static string CreateCSCompilerScript( |
464 | string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters) | ||
455 | { | 465 | { |
456 | compileScript = String.Empty + | 466 | compileScript = string.Format( |
457 | "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + | 467 | @"using OpenSim.Region.ScriptEngine.Shared; |
458 | String.Empty + "namespace SecondLife { " + | 468 | using System.Collections.Generic; |
459 | String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + | 469 | |
460 | @"public Script() { } " + | 470 | namespace SecondLife |
461 | compileScript + | 471 | {{ |
462 | "} }\r\n"; | 472 | public class {0} : {1} |
473 | {{ | ||
474 | public {0}({2}) : base({3}) {{}} | ||
475 | {4} | ||
476 | }} | ||
477 | }}", | ||
478 | className, | ||
479 | baseClassName, | ||
480 | constructorParameters != null | ||
481 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.ToString())) | ||
482 | : "", | ||
483 | constructorParameters != null | ||
484 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.Name)) | ||
485 | : "", | ||
486 | compileScript); | ||
487 | |||
463 | return compileScript; | 488 | return compileScript; |
464 | } | 489 | } |
465 | 490 | ||
466 | private static string CreateYPCompilerScript(string compileScript) | 491 | private static string CreateYPCompilerScript(string compileScript, string className, string baseClassName) |
467 | { | 492 | { |
468 | compileScript = String.Empty + | 493 | compileScript = String.Empty + |
469 | "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + | 494 | "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + |
470 | "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + | 495 | "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + |
471 | String.Empty + "namespace SecondLife { " + | 496 | String.Empty + "namespace SecondLife { " + |
472 | String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + | 497 | String.Empty + "public class " + className + " : " + baseClassName + " { \r\n" + |
473 | //@"public Script() { } " + | 498 | //@"public Script() { } " + |
474 | @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + | 499 | @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + |
475 | @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + | 500 | @"public " + className + "() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + |
476 | |||
477 | compileScript + | 501 | compileScript + |
478 | "} }\r\n"; | 502 | "} }\r\n"; |
503 | |||
479 | return compileScript; | 504 | return compileScript; |
480 | } | 505 | } |
481 | 506 | ||
482 | private static string CreateVBCompilerScript(string compileScript) | 507 | private static string CreateVBCompilerScript(string compileScript, string className, string baseClassName) |
483 | { | 508 | { |
484 | compileScript = String.Empty + | 509 | compileScript = String.Empty + |
485 | "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + | 510 | "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + |
486 | String.Empty + "NameSpace SecondLife:" + | 511 | String.Empty + "NameSpace SecondLife:" + |
487 | String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass: " + | 512 | String.Empty + "Public Class " + className + ": Inherits " + baseClassName + |
488 | "\r\nPublic Sub New()\r\nEnd Sub: " + | 513 | "\r\nPublic Sub New()\r\nEnd Sub: " + |
489 | compileScript + | 514 | compileScript + |
490 | ":End Class :End Namespace\r\n"; | 515 | ":End Class :End Namespace\r\n"; |
516 | |||
491 | return compileScript; | 517 | return compileScript; |
492 | } | 518 | } |
493 | 519 | ||
@@ -549,6 +575,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
549 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | 575 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, |
550 | "OpenMetaverseTypes.dll")); | 576 | "OpenMetaverseTypes.dll")); |
551 | 577 | ||
578 | if (m_scriptEngine.ScriptReferencedAssemblies != null) | ||
579 | Array.ForEach<string>( | ||
580 | m_scriptEngine.ScriptReferencedAssemblies, | ||
581 | a => parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, a))); | ||
582 | |||
552 | if (lang == enumCompileType.yp) | 583 | if (lang == enumCompileType.yp) |
553 | { | 584 | { |
554 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | 585 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, |
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs index 7763619..77e087c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs | |||
@@ -39,7 +39,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests | |||
39 | /// The generated C# code is compared against the expected C# code. | 39 | /// The generated C# code is compared against the expected C# code. |
40 | /// </summary> | 40 | /// </summary> |
41 | [TestFixture] | 41 | [TestFixture] |
42 | public class CSCodeGeneratorTest | 42 | public class CSCodeGeneratorTest : OpenSimTestCase |
43 | { | 43 | { |
44 | [Test] | 44 | [Test] |
45 | public void TestDefaultState() | 45 | public void TestDefaultState() |
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs index 1fa6954..05a8756 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs | |||
@@ -41,7 +41,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests | |||
41 | /// the LSL source. | 41 | /// the LSL source. |
42 | /// </summary> | 42 | /// </summary> |
43 | [TestFixture] | 43 | [TestFixture] |
44 | public class CompilerTest | 44 | public class CompilerTest : OpenSimTestCase |
45 | { | 45 | { |
46 | private string m_testDir; | 46 | private string m_testDir; |
47 | private CSharpCodeProvider m_CSCodeProvider; | 47 | private CSharpCodeProvider m_CSCodeProvider; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs index 22804f5..e44a106 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs | |||
@@ -82,6 +82,24 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
82 | } | 82 | } |
83 | } | 83 | } |
84 | 84 | ||
85 | /// <summary> | ||
86 | /// Used to signal when the script is stopping in co-operation with the script engine | ||
87 | /// (instead of through Thread.Abort()). | ||
88 | /// </summary> | ||
89 | [Serializable] | ||
90 | public class ScriptCoopStopException : Exception | ||
91 | { | ||
92 | public ScriptCoopStopException() | ||
93 | { | ||
94 | } | ||
95 | |||
96 | protected ScriptCoopStopException( | ||
97 | SerializationInfo info, | ||
98 | StreamingContext context) | ||
99 | { | ||
100 | } | ||
101 | } | ||
102 | |||
85 | public class DetectParams | 103 | public class DetectParams |
86 | { | 104 | { |
87 | public const int AGENT = 1; | 105 | public const int AGENT = 1; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 771db0c..c8ced43 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -94,6 +94,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
94 | private UUID m_CurrentStateHash; | 94 | private UUID m_CurrentStateHash; |
95 | private UUID m_RegionID; | 95 | private UUID m_RegionID; |
96 | 96 | ||
97 | public int DebugLevel { get; set; } | ||
98 | |||
97 | public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> LineMap { get; set; } | 99 | public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> LineMap { get; set; } |
98 | 100 | ||
99 | private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); | 101 | private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); |
@@ -156,6 +158,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
156 | 158 | ||
157 | public UUID AppDomain { get; set; } | 159 | public UUID AppDomain { get; set; } |
158 | 160 | ||
161 | public SceneObjectPart Part { get; private set; } | ||
162 | |||
159 | public string PrimName { get; private set; } | 163 | public string PrimName { get; private set; } |
160 | 164 | ||
161 | public string ScriptName { get; private set; } | 165 | public string ScriptName { get; private set; } |
@@ -174,6 +178,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
174 | 178 | ||
175 | public Queue EventQueue { get; private set; } | 179 | public Queue EventQueue { get; private set; } |
176 | 180 | ||
181 | public long EventsQueued | ||
182 | { | ||
183 | get | ||
184 | { | ||
185 | lock (EventQueue) | ||
186 | return EventQueue.Count; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | public long EventsProcessed { get; private set; } | ||
191 | |||
177 | public int StartParam { get; set; } | 192 | public int StartParam { get; set; } |
178 | 193 | ||
179 | public TaskInventoryItem ScriptTask { get; private set; } | 194 | public TaskInventoryItem ScriptTask { get; private set; } |
@@ -186,66 +201,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
186 | 201 | ||
187 | public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute; | 202 | public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute; |
188 | 203 | ||
204 | private bool m_coopTermination; | ||
205 | |||
206 | private EventWaitHandle m_coopSleepHandle; | ||
207 | |||
189 | public void ClearQueue() | 208 | public void ClearQueue() |
190 | { | 209 | { |
191 | m_TimerQueued = false; | 210 | m_TimerQueued = false; |
192 | EventQueue.Clear(); | 211 | EventQueue.Clear(); |
193 | } | 212 | } |
194 | 213 | ||
195 | public ScriptInstance(IScriptEngine engine, SceneObjectPart part, | 214 | public ScriptInstance( |
196 | UUID itemID, UUID assetID, string assembly, | 215 | IScriptEngine engine, SceneObjectPart part, TaskInventoryItem item, |
197 | AppDomain dom, string primName, string scriptName, | 216 | int startParam, bool postOnRez, |
198 | int startParam, bool postOnRez, StateSource stateSource, | 217 | int maxScriptQueue) |
199 | int maxScriptQueue) | ||
200 | { | 218 | { |
201 | State = "default"; | 219 | State = "default"; |
202 | EventQueue = new Queue(32); | 220 | EventQueue = new Queue(32); |
203 | 221 | ||
204 | Engine = engine; | 222 | Engine = engine; |
205 | LocalID = part.LocalId; | 223 | Part = part; |
206 | ObjectID = part.UUID; | 224 | ScriptTask = item; |
207 | RootLocalID = part.ParentGroup.LocalId; | 225 | |
208 | RootObjectID = part.ParentGroup.UUID; | 226 | // This is currently only here to allow regression tests to get away without specifying any inventory |
209 | ItemID = itemID; | 227 | // item when they are testing script logic that doesn't require an item. |
210 | AssetID = assetID; | 228 | if (ScriptTask != null) |
211 | PrimName = primName; | 229 | { |
212 | ScriptName = scriptName; | 230 | ScriptName = ScriptTask.Name; |
213 | m_Assembly = assembly; | 231 | ItemID = ScriptTask.ItemID; |
232 | AssetID = ScriptTask.AssetID; | ||
233 | } | ||
234 | |||
235 | PrimName = part.ParentGroup.Name; | ||
214 | StartParam = startParam; | 236 | StartParam = startParam; |
215 | m_MaxScriptQueue = maxScriptQueue; | 237 | m_MaxScriptQueue = maxScriptQueue; |
216 | m_stateSource = stateSource; | ||
217 | m_postOnRez = postOnRez; | 238 | m_postOnRez = postOnRez; |
218 | m_AttachedAvatar = part.ParentGroup.AttachedAvatar; | 239 | m_AttachedAvatar = part.ParentGroup.AttachedAvatar; |
219 | m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; | 240 | m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; |
220 | 241 | ||
221 | if (part != null) | 242 | if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") |
222 | { | 243 | { |
223 | part.TaskInventory.LockItemsForRead(true); | 244 | m_coopTermination = true; |
224 | if (part.TaskInventory.ContainsKey(ItemID)) | 245 | m_coopSleepHandle = new AutoResetEvent(false); |
225 | { | ||
226 | ScriptTask = part.TaskInventory[ItemID]; | ||
227 | } | ||
228 | part.TaskInventory.LockItemsForRead(false); | ||
229 | } | 246 | } |
247 | } | ||
248 | |||
249 | /// <summary> | ||
250 | /// Load the script from an assembly into an AppDomain. | ||
251 | /// </summary> | ||
252 | /// <param name='dom'></param> | ||
253 | /// <param name='assembly'></param> | ||
254 | /// <param name='stateSource'></param> | ||
255 | /// <returns>false if load failed, true if suceeded</returns> | ||
256 | public bool Load(AppDomain dom, string assembly, StateSource stateSource) | ||
257 | { | ||
258 | m_Assembly = assembly; | ||
259 | m_stateSource = stateSource; | ||
230 | 260 | ||
231 | ApiManager am = new ApiManager(); | 261 | ApiManager am = new ApiManager(); |
232 | 262 | ||
233 | foreach (string api in am.GetApis()) | 263 | foreach (string api in am.GetApis()) |
234 | { | 264 | { |
235 | m_Apis[api] = am.CreateApi(api); | 265 | m_Apis[api] = am.CreateApi(api); |
236 | m_Apis[api].Initialize(engine, part, ScriptTask); | 266 | m_Apis[api].Initialize(Engine, Part, ScriptTask, m_coopSleepHandle); |
237 | } | 267 | } |
238 | 268 | ||
239 | try | 269 | try |
240 | { | 270 | { |
271 | object[] constructorParams; | ||
272 | |||
273 | Assembly scriptAssembly = dom.Load(Path.GetFileNameWithoutExtension(assembly)); | ||
274 | Type scriptType = scriptAssembly.GetType("SecondLife.XEngineScript"); | ||
275 | |||
276 | if (scriptType != null) | ||
277 | { | ||
278 | constructorParams = new object[] { m_coopSleepHandle }; | ||
279 | } | ||
280 | else if (!m_coopTermination) | ||
281 | { | ||
282 | scriptType = scriptAssembly.GetType("SecondLife.Script"); | ||
283 | constructorParams = null; | ||
284 | } | ||
285 | else | ||
286 | { | ||
287 | m_log.ErrorFormat( | ||
288 | "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. You must remove all existing {6}* script DLL files before using enabling co-op termination" | ||
289 | + ", either by setting DeleteScriptsOnStartup = true in [XEngine] for one run" | ||
290 | + " or by deleting these files manually.", | ||
291 | ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly); | ||
292 | |||
293 | return false; | ||
294 | } | ||
295 | |||
296 | // m_log.DebugFormat( | ||
297 | // "[SCRIPT INSTANCE]: Looking to load {0} from assembly {1} in {2}", | ||
298 | // scriptType.FullName, Path.GetFileNameWithoutExtension(assembly), Engine.World.Name); | ||
299 | |||
241 | if (dom != System.AppDomain.CurrentDomain) | 300 | if (dom != System.AppDomain.CurrentDomain) |
242 | m_Script = (IScript)dom.CreateInstanceAndUnwrap( | 301 | m_Script |
302 | = (IScript)dom.CreateInstanceAndUnwrap( | ||
243 | Path.GetFileNameWithoutExtension(assembly), | 303 | Path.GetFileNameWithoutExtension(assembly), |
244 | "SecondLife.Script"); | 304 | scriptType.FullName, |
305 | false, | ||
306 | BindingFlags.Default, | ||
307 | null, | ||
308 | constructorParams, | ||
309 | null, | ||
310 | null, | ||
311 | null); | ||
245 | else | 312 | else |
246 | m_Script = (IScript)Assembly.Load( | 313 | m_Script |
247 | Path.GetFileNameWithoutExtension(assembly)).CreateInstance( | 314 | = (IScript)scriptAssembly.CreateInstance( |
248 | "SecondLife.Script"); | 315 | scriptType.FullName, |
316 | false, | ||
317 | BindingFlags.Default, | ||
318 | null, | ||
319 | constructorParams, | ||
320 | null, | ||
321 | null); | ||
249 | 322 | ||
250 | //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); | 323 | //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); |
251 | //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); | 324 | //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); |
@@ -254,8 +327,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
254 | catch (Exception e) | 327 | catch (Exception e) |
255 | { | 328 | { |
256 | m_log.ErrorFormat( | 329 | m_log.ErrorFormat( |
257 | "[SCRIPT INSTANCE]: Error loading assembly {0}. Exception {1}{2}", | 330 | "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error loading assembly {6}. Exception {7}{8}", |
258 | assembly, e.Message, e.StackTrace); | 331 | ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly, e.Message, e.StackTrace); |
332 | |||
333 | return false; | ||
259 | } | 334 | } |
260 | 335 | ||
261 | try | 336 | try |
@@ -267,16 +342,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
267 | 342 | ||
268 | // // m_log.Debug("[Script] Script instance created"); | 343 | // // m_log.Debug("[Script] Script instance created"); |
269 | 344 | ||
270 | part.SetScriptEvents(ItemID, | 345 | Part.SetScriptEvents(ItemID, |
271 | (int)m_Script.GetStateEventFlags(State)); | 346 | (int)m_Script.GetStateEventFlags(State)); |
272 | } | 347 | } |
273 | catch (Exception e) | 348 | catch (Exception e) |
274 | { | 349 | { |
275 | m_log.ErrorFormat( | 350 | m_log.ErrorFormat( |
276 | "[SCRIPT INSTANCE]: Error loading script instance from assembly {0}. Exception {1}{2}", | 351 | "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error initializing script instance. Exception {6}{7}", |
277 | assembly, e.Message, e.StackTrace); | 352 | ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, e.Message, e.StackTrace); |
278 | 353 | ||
279 | return; | 354 | return false; |
280 | } | 355 | } |
281 | 356 | ||
282 | m_SaveState = true; | 357 | m_SaveState = true; |
@@ -309,7 +384,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
309 | 384 | ||
310 | // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); | 385 | // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); |
311 | 386 | ||
312 | part.SetScriptEvents(ItemID, | 387 | Part.SetScriptEvents(ItemID, |
313 | (int)m_Script.GetStateEventFlags(State)); | 388 | (int)m_Script.GetStateEventFlags(State)); |
314 | 389 | ||
315 | if (!Running) | 390 | if (!Running) |
@@ -329,15 +404,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
329 | else | 404 | else |
330 | { | 405 | { |
331 | m_log.WarnFormat( | 406 | m_log.WarnFormat( |
332 | "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). Memory limit exceeded", | 407 | "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.", |
333 | savedState, ScriptName, ItemID, PrimName, ObjectID, assembly); | 408 | ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState); |
334 | } | 409 | } |
335 | } | 410 | } |
336 | catch (Exception e) | 411 | catch (Exception e) |
337 | { | 412 | { |
338 | m_log.ErrorFormat( | 413 | m_log.ErrorFormat( |
339 | "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). XML is {6}. Exception {7}{8}", | 414 | "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. XML is {7}. Exception {8}{9}", |
340 | savedState, ScriptName, ItemID, PrimName, ObjectID, assembly, xml, e.Message, e.StackTrace); | 415 | ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState, xml, e.Message, e.StackTrace); |
341 | } | 416 | } |
342 | } | 417 | } |
343 | // else | 418 | // else |
@@ -348,6 +423,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
348 | // presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); | 423 | // presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); |
349 | 424 | ||
350 | // } | 425 | // } |
426 | |||
427 | return true; | ||
351 | } | 428 | } |
352 | 429 | ||
353 | public void Init() | 430 | public void Init() |
@@ -521,9 +598,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
521 | } | 598 | } |
522 | 599 | ||
523 | // Wait for the current event to complete. | 600 | // Wait for the current event to complete. |
524 | if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000))) | 601 | if (!m_InSelfDelete) |
525 | { | 602 | { |
526 | return true; | 603 | if (!m_coopTermination) |
604 | { | ||
605 | // If we're not co-operative terminating then try and wait for the event to complete before stopping | ||
606 | if (workItem.Wait(new TimeSpan((long)timeout * 100000))) | ||
607 | return true; | ||
608 | } | ||
609 | else | ||
610 | { | ||
611 | if (DebugLevel >= 1) | ||
612 | m_log.DebugFormat( | ||
613 | "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}", | ||
614 | ScriptName, ItemID, PrimName, ObjectID); | ||
615 | |||
616 | // This will terminate the event on next handle check by the script. | ||
617 | m_coopSleepHandle.Set(); | ||
618 | |||
619 | // For now, we will wait forever since the event should always cleanly terminate once LSL loop | ||
620 | // checking is implemented. May want to allow a shorter timeout option later. | ||
621 | if (workItem.Wait(TimeSpan.MaxValue)) | ||
622 | { | ||
623 | if (DebugLevel >= 1) | ||
624 | m_log.DebugFormat( | ||
625 | "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}", | ||
626 | ScriptName, ItemID, PrimName, ObjectID); | ||
627 | |||
628 | return true; | ||
629 | } | ||
630 | } | ||
527 | } | 631 | } |
528 | 632 | ||
529 | lock (EventQueue) | 633 | lock (EventQueue) |
@@ -536,11 +640,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
536 | 640 | ||
537 | // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then | 641 | // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then |
538 | // forcibly abort the work item (this aborts the underlying thread). | 642 | // forcibly abort the work item (this aborts the underlying thread). |
643 | // Co-operative termination should never reach this point. | ||
539 | if (!m_InSelfDelete) | 644 | if (!m_InSelfDelete) |
540 | { | 645 | { |
541 | // m_log.ErrorFormat( | 646 | m_log.DebugFormat( |
542 | // "[SCRIPT INSTANCE]: Aborting script {0} {1} in prim {2} {3} {4} {5}", | 647 | "[SCRIPT INSTANCE]: Aborting unstopped script {0} {1} in prim {2}, localID {3}, timeout was {4} ms", |
543 | // ScriptName, ItemID, PrimName, ObjectID, m_InSelfDelete, DateTime.Now.Ticks); | 648 | ScriptName, ItemID, PrimName, LocalID, timeout); |
544 | 649 | ||
545 | workItem.Abort(); | 650 | workItem.Abort(); |
546 | } | 651 | } |
@@ -696,19 +801,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
696 | { | 801 | { |
697 | 802 | ||
698 | // m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); | 803 | // m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); |
804 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); | ||
805 | |||
806 | if (DebugLevel >= 2) | ||
807 | m_log.DebugFormat( | ||
808 | "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", | ||
809 | data.EventName, | ||
810 | ScriptName, | ||
811 | part.Name, | ||
812 | part.LocalId, | ||
813 | part.ParentGroup.Name, | ||
814 | part.ParentGroup.UUID, | ||
815 | part.AbsolutePosition, | ||
816 | part.ParentGroup.Scene.Name); | ||
699 | 817 | ||
700 | m_DetectParams = data.DetectParams; | 818 | m_DetectParams = data.DetectParams; |
701 | 819 | ||
702 | if (data.EventName == "state") // Hardcoded state change | 820 | if (data.EventName == "state") // Hardcoded state change |
703 | { | 821 | { |
704 | // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", | ||
705 | // PrimName, ScriptName, data.Params[0].ToString()); | ||
706 | State = data.Params[0].ToString(); | 822 | State = data.Params[0].ToString(); |
823 | |||
824 | if (DebugLevel >= 1) | ||
825 | m_log.DebugFormat( | ||
826 | "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", | ||
827 | State, | ||
828 | ScriptName, | ||
829 | part.Name, | ||
830 | part.LocalId, | ||
831 | part.ParentGroup.Name, | ||
832 | part.ParentGroup.UUID, | ||
833 | part.AbsolutePosition, | ||
834 | part.ParentGroup.Scene.Name); | ||
835 | |||
707 | AsyncCommandManager.RemoveScript(Engine, | 836 | AsyncCommandManager.RemoveScript(Engine, |
708 | LocalID, ItemID); | 837 | LocalID, ItemID); |
709 | 838 | ||
710 | SceneObjectPart part = Engine.World.GetSceneObjectPart( | ||
711 | LocalID); | ||
712 | if (part != null) | 839 | if (part != null) |
713 | { | 840 | { |
714 | part.SetScriptEvents(ItemID, | 841 | part.SetScriptEvents(ItemID, |
@@ -720,8 +847,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
720 | if (Engine.World.PipeEventsForScript(LocalID) || | 847 | if (Engine.World.PipeEventsForScript(LocalID) || |
721 | data.EventName == "control") // Don't freeze avies! | 848 | data.EventName == "control") // Don't freeze avies! |
722 | { | 849 | { |
723 | SceneObjectPart part = Engine.World.GetSceneObjectPart( | ||
724 | LocalID); | ||
725 | // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", | 850 | // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", |
726 | // PrimName, ScriptName, data.EventName, State); | 851 | // PrimName, ScriptName, data.EventName, State); |
727 | 852 | ||
@@ -763,7 +888,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
763 | m_InEvent = false; | 888 | m_InEvent = false; |
764 | m_CurrentEvent = String.Empty; | 889 | m_CurrentEvent = String.Empty; |
765 | 890 | ||
766 | if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) | 891 | if ((!(e is TargetInvocationException) |
892 | || (!(e.InnerException is SelfDeleteException) | ||
893 | && !(e.InnerException is ScriptDeleteException) | ||
894 | && !(e.InnerException is ScriptCoopStopException))) | ||
895 | && !(e is ThreadAbortException)) | ||
767 | { | 896 | { |
768 | try | 897 | try |
769 | { | 898 | { |
@@ -776,6 +905,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
776 | ChatTypeEnum.DebugChannel, 2147483647, | 905 | ChatTypeEnum.DebugChannel, 2147483647, |
777 | part.AbsolutePosition, | 906 | part.AbsolutePosition, |
778 | part.Name, part.UUID, false); | 907 | part.Name, part.UUID, false); |
908 | |||
909 | |||
910 | m_log.DebugFormat( | ||
911 | "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", | ||
912 | ScriptName, | ||
913 | PrimName, | ||
914 | part.UUID, | ||
915 | part.AbsolutePosition, | ||
916 | part.ParentGroup.Scene.Name, | ||
917 | text.Replace("\n", "\\n"), | ||
918 | e.InnerException); | ||
779 | } | 919 | } |
780 | catch (Exception) | 920 | catch (Exception) |
781 | { | 921 | { |
@@ -802,6 +942,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
802 | if (part != null) | 942 | if (part != null) |
803 | part.Inventory.RemoveInventoryItem(ItemID); | 943 | part.Inventory.RemoveInventoryItem(ItemID); |
804 | } | 944 | } |
945 | else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) | ||
946 | { | ||
947 | if (DebugLevel >= 1) | ||
948 | m_log.DebugFormat( | ||
949 | "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.", | ||
950 | PrimName, ScriptName, data.EventName, State); | ||
951 | } | ||
805 | } | 952 | } |
806 | } | 953 | } |
807 | } | 954 | } |
@@ -810,6 +957,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
810 | // script engine to run the next event. | 957 | // script engine to run the next event. |
811 | lock (EventQueue) | 958 | lock (EventQueue) |
812 | { | 959 | { |
960 | EventsProcessed++; | ||
961 | |||
813 | if (EventQueue.Count > 0 && Running && !ShuttingDown) | 962 | if (EventQueue.Count > 0 && Running && !ShuttingDown) |
814 | { | 963 | { |
815 | m_CurrentWorkItem = Engine.QueueEventHandler(this); | 964 | m_CurrentWorkItem = Engine.QueueEventHandler(this); |
@@ -834,7 +983,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
834 | return (DateTime.Now - m_EventStart).Seconds; | 983 | return (DateTime.Now - m_EventStart).Seconds; |
835 | } | 984 | } |
836 | 985 | ||
837 | public void ResetScript() | 986 | public void ResetScript(int timeout) |
838 | { | 987 | { |
839 | if (m_Script == null) | 988 | if (m_Script == null) |
840 | return; | 989 | return; |
@@ -844,7 +993,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
844 | RemoveState(); | 993 | RemoveState(); |
845 | ReleaseControls(); | 994 | ReleaseControls(); |
846 | 995 | ||
847 | Stop(0); | 996 | Stop(timeout); |
848 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); | 997 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); |
849 | part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; | 998 | part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; |
850 | part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; | 999 | part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; |
@@ -1015,7 +1164,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
1015 | "({0}): {1}", scriptLine - 1, | 1164 | "({0}): {1}", scriptLine - 1, |
1016 | e.InnerException.Message); | 1165 | e.InnerException.Message); |
1017 | 1166 | ||
1018 | System.Console.WriteLine(e.ToString()+"\n"); | ||
1019 | return message; | 1167 | return message; |
1020 | } | 1168 | } |
1021 | } | 1169 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs new file mode 100644 index 0000000..7ea30bf1 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs | |||
@@ -0,0 +1,514 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Threading; | ||
31 | using Nini.Config; | ||
32 | using NUnit.Framework; | ||
33 | using OpenMetaverse; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Region.CoreModules.Scripting.WorldComm; | ||
36 | using OpenSim.Region.Framework.Scenes; | ||
37 | using OpenSim.Region.Framework.Interfaces; | ||
38 | using OpenSim.Region.ScriptEngine.XEngine; | ||
39 | using OpenSim.Tests.Common; | ||
40 | using OpenSim.Tests.Common.Mock; | ||
41 | |||
42 | namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests | ||
43 | { | ||
44 | /// <summary> | ||
45 | /// Test that co-operative script thread termination is working correctly. | ||
46 | /// </summary> | ||
47 | [TestFixture] | ||
48 | public class CoopTerminationTests : OpenSimTestCase | ||
49 | { | ||
50 | private TestScene m_scene; | ||
51 | private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine; | ||
52 | |||
53 | private AutoResetEvent m_chatEvent; | ||
54 | private AutoResetEvent m_stoppedEvent; | ||
55 | |||
56 | private OSChatMessage m_osChatMessageReceived; | ||
57 | |||
58 | /// <summary> | ||
59 | /// Number of chat messages received so far. Reset before each test. | ||
60 | /// </summary> | ||
61 | private int m_chatMessagesReceived; | ||
62 | |||
63 | /// <summary> | ||
64 | /// Number of chat messages expected. m_chatEvent is not fired until this number is reached or exceeded. | ||
65 | /// </summary> | ||
66 | private int m_chatMessagesThreshold; | ||
67 | |||
68 | [SetUp] | ||
69 | public void Init() | ||
70 | { | ||
71 | m_osChatMessageReceived = null; | ||
72 | m_chatMessagesReceived = 0; | ||
73 | m_chatMessagesThreshold = 0; | ||
74 | m_chatEvent = new AutoResetEvent(false); | ||
75 | m_stoppedEvent = new AutoResetEvent(false); | ||
76 | |||
77 | //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); | ||
78 | // Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); | ||
79 | m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine(); | ||
80 | |||
81 | IniConfigSource configSource = new IniConfigSource(); | ||
82 | |||
83 | IConfig startupConfig = configSource.AddConfig("Startup"); | ||
84 | startupConfig.Set("DefaultScriptEngine", "XEngine"); | ||
85 | |||
86 | IConfig xEngineConfig = configSource.AddConfig("XEngine"); | ||
87 | xEngineConfig.Set("Enabled", "true"); | ||
88 | xEngineConfig.Set("StartDelay", "0"); | ||
89 | |||
90 | // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call | ||
91 | // to AssemblyResolver.OnAssemblyResolve fails. | ||
92 | xEngineConfig.Set("AppDomainLoading", "false"); | ||
93 | |||
94 | xEngineConfig.Set("ScriptStopStrategy", "co-op"); | ||
95 | |||
96 | // Make sure loops aren't actually being terminated by a script delay wait. | ||
97 | xEngineConfig.Set("ScriptDelayFactor", 0); | ||
98 | |||
99 | // This is really just set for debugging the test. | ||
100 | xEngineConfig.Set("WriteScriptSourceToDebugFile", true); | ||
101 | |||
102 | // Set to false if we need to debug test so the old scripts don't get wiped before each separate test | ||
103 | // xEngineConfig.Set("DeleteScriptsOnStartup", false); | ||
104 | |||
105 | // This is not currently used at all for co-op termination. Bumping up to demonstrate that co-op termination | ||
106 | // has an effect - without it tests will fail due to a 120 second wait for the event to finish. | ||
107 | xEngineConfig.Set("WaitForEventCompletionOnScriptStop", 120000); | ||
108 | |||
109 | m_scene = new SceneHelpers().SetupScene("My Test", TestHelpers.ParseTail(0x9999), 1000, 1000, configSource); | ||
110 | SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); | ||
111 | m_scene.StartScripts(); | ||
112 | } | ||
113 | |||
114 | /// <summary> | ||
115 | /// Test co-operative termination on derez of an object containing a script with a long-running event. | ||
116 | /// </summary> | ||
117 | /// <remarks> | ||
118 | /// TODO: Actually compiling the script is incidental to this test. Really want a way to compile test scripts | ||
119 | /// within the build itself. | ||
120 | /// </remarks> | ||
121 | [Test] | ||
122 | public void TestStopOnLongSleep() | ||
123 | { | ||
124 | TestHelpers.InMethod(); | ||
125 | // TestHelpers.EnableLogging(); | ||
126 | |||
127 | string script = | ||
128 | @"default | ||
129 | { | ||
130 | state_entry() | ||
131 | { | ||
132 | llSay(0, ""Thin Lizzy""); | ||
133 | llSleep(60); | ||
134 | } | ||
135 | }"; | ||
136 | |||
137 | TestStop(script); | ||
138 | } | ||
139 | |||
140 | [Test] | ||
141 | public void TestNoStopOnSingleStatementForLoop() | ||
142 | { | ||
143 | TestHelpers.InMethod(); | ||
144 | // TestHelpers.EnableLogging(); | ||
145 | |||
146 | string script = | ||
147 | @"default | ||
148 | { | ||
149 | state_entry() | ||
150 | { | ||
151 | integer i = 0; | ||
152 | for (i = 0; i <= 1; i++) llSay(0, ""Iter "" + (string)i); | ||
153 | } | ||
154 | }"; | ||
155 | |||
156 | TestSingleStatementNoStop(script); | ||
157 | } | ||
158 | |||
159 | [Test] | ||
160 | public void TestStopOnLongSingleStatementForLoop() | ||
161 | { | ||
162 | TestHelpers.InMethod(); | ||
163 | // TestHelpers.EnableLogging(); | ||
164 | |||
165 | string script = | ||
166 | @"default | ||
167 | { | ||
168 | state_entry() | ||
169 | { | ||
170 | integer i = 0; | ||
171 | llSay(0, ""Thin Lizzy""); | ||
172 | |||
173 | for (i = 0; i < 2147483647; i++) llSay(0, ""Iter "" + (string)i); | ||
174 | } | ||
175 | }"; | ||
176 | |||
177 | TestStop(script); | ||
178 | } | ||
179 | |||
180 | [Test] | ||
181 | public void TestStopOnLongCompoundStatementForLoop() | ||
182 | { | ||
183 | TestHelpers.InMethod(); | ||
184 | // TestHelpers.EnableLogging(); | ||
185 | |||
186 | string script = | ||
187 | @"default | ||
188 | { | ||
189 | state_entry() | ||
190 | { | ||
191 | integer i = 0; | ||
192 | llSay(0, ""Thin Lizzy""); | ||
193 | |||
194 | for (i = 0; i < 2147483647; i++) | ||
195 | { | ||
196 | llSay(0, ""Iter "" + (string)i); | ||
197 | } | ||
198 | } | ||
199 | }"; | ||
200 | |||
201 | TestStop(script); | ||
202 | } | ||
203 | |||
204 | [Test] | ||
205 | public void TestNoStopOnSingleStatementWhileLoop() | ||
206 | { | ||
207 | TestHelpers.InMethod(); | ||
208 | // TestHelpers.EnableLogging(); | ||
209 | |||
210 | string script = | ||
211 | @"default | ||
212 | { | ||
213 | state_entry() | ||
214 | { | ||
215 | integer i = 0; | ||
216 | while (i < 2) llSay(0, ""Iter "" + (string)i++); | ||
217 | } | ||
218 | }"; | ||
219 | |||
220 | TestSingleStatementNoStop(script); | ||
221 | } | ||
222 | |||
223 | [Test] | ||
224 | public void TestStopOnLongSingleStatementWhileLoop() | ||
225 | { | ||
226 | TestHelpers.InMethod(); | ||
227 | // TestHelpers.EnableLogging(); | ||
228 | |||
229 | string script = | ||
230 | @"default | ||
231 | { | ||
232 | state_entry() | ||
233 | { | ||
234 | integer i = 0; | ||
235 | llSay(0, ""Thin Lizzy""); | ||
236 | |||
237 | while (1 == 1) | ||
238 | llSay(0, ""Iter "" + (string)i++); | ||
239 | } | ||
240 | }"; | ||
241 | |||
242 | TestStop(script); | ||
243 | } | ||
244 | |||
245 | [Test] | ||
246 | public void TestStopOnLongCompoundStatementWhileLoop() | ||
247 | { | ||
248 | TestHelpers.InMethod(); | ||
249 | // TestHelpers.EnableLogging(); | ||
250 | |||
251 | string script = | ||
252 | @"default | ||
253 | { | ||
254 | state_entry() | ||
255 | { | ||
256 | integer i = 0; | ||
257 | llSay(0, ""Thin Lizzy""); | ||
258 | |||
259 | while (1 == 1) | ||
260 | { | ||
261 | llSay(0, ""Iter "" + (string)i++); | ||
262 | } | ||
263 | } | ||
264 | }"; | ||
265 | |||
266 | TestStop(script); | ||
267 | } | ||
268 | |||
269 | [Test] | ||
270 | public void TestNoStopOnSingleStatementDoWhileLoop() | ||
271 | { | ||
272 | TestHelpers.InMethod(); | ||
273 | // TestHelpers.EnableLogging(); | ||
274 | |||
275 | string script = | ||
276 | @"default | ||
277 | { | ||
278 | state_entry() | ||
279 | { | ||
280 | integer i = 0; | ||
281 | |||
282 | do llSay(0, ""Iter "" + (string)i++); | ||
283 | while (i < 2); | ||
284 | } | ||
285 | }"; | ||
286 | |||
287 | TestSingleStatementNoStop(script); | ||
288 | } | ||
289 | |||
290 | [Test] | ||
291 | public void TestStopOnLongSingleStatementDoWhileLoop() | ||
292 | { | ||
293 | TestHelpers.InMethod(); | ||
294 | // TestHelpers.EnableLogging(); | ||
295 | |||
296 | string script = | ||
297 | @"default | ||
298 | { | ||
299 | state_entry() | ||
300 | { | ||
301 | integer i = 0; | ||
302 | llSay(0, ""Thin Lizzy""); | ||
303 | |||
304 | do llSay(0, ""Iter "" + (string)i++); | ||
305 | while (1 == 1); | ||
306 | } | ||
307 | }"; | ||
308 | |||
309 | TestStop(script); | ||
310 | } | ||
311 | |||
312 | [Test] | ||
313 | public void TestStopOnLongCompoundStatementDoWhileLoop() | ||
314 | { | ||
315 | TestHelpers.InMethod(); | ||
316 | // TestHelpers.EnableLogging(); | ||
317 | |||
318 | string script = | ||
319 | @"default | ||
320 | { | ||
321 | state_entry() | ||
322 | { | ||
323 | integer i = 0; | ||
324 | llSay(0, ""Thin Lizzy""); | ||
325 | |||
326 | do | ||
327 | { | ||
328 | llSay(0, ""Iter "" + (string)i++); | ||
329 | } while (1 == 1); | ||
330 | } | ||
331 | }"; | ||
332 | |||
333 | TestStop(script); | ||
334 | } | ||
335 | |||
336 | [Test] | ||
337 | public void TestStopOnInfiniteJumpLoop() | ||
338 | { | ||
339 | TestHelpers.InMethod(); | ||
340 | // TestHelpers.EnableLogging(); | ||
341 | |||
342 | string script = | ||
343 | @"default | ||
344 | { | ||
345 | state_entry() | ||
346 | { | ||
347 | integer i = 0; | ||
348 | llSay(0, ""Thin Lizzy""); | ||
349 | |||
350 | @p1; | ||
351 | llSay(0, ""Iter "" + (string)i++); | ||
352 | jump p1; | ||
353 | } | ||
354 | }"; | ||
355 | |||
356 | TestStop(script); | ||
357 | } | ||
358 | |||
359 | // Disabling for now as these are not particularly useful tests (since they fail due to stack overflow before | ||
360 | // termination can even be tried. | ||
361 | // [Test] | ||
362 | public void TestStopOnInfiniteUserFunctionCallLoop() | ||
363 | { | ||
364 | TestHelpers.InMethod(); | ||
365 | // TestHelpers.EnableLogging(); | ||
366 | |||
367 | string script = | ||
368 | @" | ||
369 | integer i = 0; | ||
370 | |||
371 | ufn1() | ||
372 | { | ||
373 | llSay(0, ""Iter ufn1() "" + (string)i++); | ||
374 | ufn1(); | ||
375 | } | ||
376 | |||
377 | default | ||
378 | { | ||
379 | state_entry() | ||
380 | { | ||
381 | integer i = 0; | ||
382 | llSay(0, ""Thin Lizzy""); | ||
383 | |||
384 | ufn1(); | ||
385 | } | ||
386 | }"; | ||
387 | |||
388 | TestStop(script); | ||
389 | } | ||
390 | |||
391 | // Disabling for now as these are not particularly useful tests (since they fail due to stack overflow before | ||
392 | // termination can even be tried. | ||
393 | // [Test] | ||
394 | public void TestStopOnInfiniteManualEventCallLoop() | ||
395 | { | ||
396 | TestHelpers.InMethod(); | ||
397 | // TestHelpers.EnableLogging(); | ||
398 | |||
399 | string script = | ||
400 | @"default | ||
401 | { | ||
402 | state_entry() | ||
403 | { | ||
404 | integer i = 0; | ||
405 | llSay(0, ""Thin Lizzy""); | ||
406 | |||
407 | llSay(0, ""Iter"" + (string)i++); | ||
408 | default_event_state_entry(); | ||
409 | } | ||
410 | }"; | ||
411 | |||
412 | TestStop(script); | ||
413 | } | ||
414 | |||
415 | private SceneObjectPart CreateScript(string script, string itemName, UUID userId) | ||
416 | { | ||
417 | // UUID objectId = TestHelpers.ParseTail(0x100); | ||
418 | // UUID itemId = TestHelpers.ParseTail(0x3); | ||
419 | |||
420 | SceneObjectGroup so | ||
421 | = SceneHelpers.CreateSceneObject(1, userId, string.Format("Object for {0}", itemName), 0x100); | ||
422 | m_scene.AddNewSceneObject(so, true); | ||
423 | |||
424 | InventoryItemBase itemTemplate = new InventoryItemBase(); | ||
425 | // itemTemplate.ID = itemId; | ||
426 | itemTemplate.Name = itemName; | ||
427 | itemTemplate.Folder = so.UUID; | ||
428 | itemTemplate.InvType = (int)InventoryType.LSL; | ||
429 | |||
430 | m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; | ||
431 | |||
432 | return m_scene.RezNewScript(userId, itemTemplate, script); | ||
433 | } | ||
434 | |||
435 | private void TestSingleStatementNoStop(string script) | ||
436 | { | ||
437 | // In these tests we expect to see at least 2 chat messages to confirm that the loop is working properly. | ||
438 | m_chatMessagesThreshold = 2; | ||
439 | |||
440 | UUID userId = TestHelpers.ParseTail(0x1); | ||
441 | // UUID objectId = TestHelpers.ParseTail(0x100); | ||
442 | // UUID itemId = TestHelpers.ParseTail(0x3); | ||
443 | string itemName = "TestNoStop"; | ||
444 | |||
445 | SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId); | ||
446 | TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); | ||
447 | |||
448 | // Wait for the script to start the event before we try stopping it. | ||
449 | m_chatEvent.WaitOne(60000); | ||
450 | |||
451 | if (m_osChatMessageReceived == null) | ||
452 | Assert.Fail("Script did not start"); | ||
453 | else | ||
454 | Assert.That(m_chatMessagesReceived, Is.EqualTo(2)); | ||
455 | |||
456 | bool running; | ||
457 | TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); | ||
458 | Assert.That( | ||
459 | SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True); | ||
460 | Assert.That(running, Is.True); | ||
461 | } | ||
462 | |||
463 | private void TestStop(string script) | ||
464 | { | ||
465 | // In these tests we're only interested in the first message to confirm that the script has started. | ||
466 | m_chatMessagesThreshold = 1; | ||
467 | |||
468 | UUID userId = TestHelpers.ParseTail(0x1); | ||
469 | // UUID objectId = TestHelpers.ParseTail(0x100); | ||
470 | // UUID itemId = TestHelpers.ParseTail(0x3); | ||
471 | string itemName = "TestStop"; | ||
472 | |||
473 | SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId); | ||
474 | TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); | ||
475 | |||
476 | // Wait for the script to start the event before we try stopping it. | ||
477 | m_chatEvent.WaitOne(60000); | ||
478 | |||
479 | if (m_osChatMessageReceived != null) | ||
480 | Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message); | ||
481 | else | ||
482 | Assert.Fail("Script did not start"); | ||
483 | |||
484 | // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script | ||
485 | // executes llSay() but has not started the next statement before we try to stop it. | ||
486 | Thread.Sleep(1000); | ||
487 | |||
488 | // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually | ||
489 | // stopped. This kind of multi-threading is far from ideal in a regression test. | ||
490 | new Thread(() => { m_xEngine.StopScript(rezzedItem.ItemID); m_stoppedEvent.Set(); }).Start(); | ||
491 | |||
492 | if (!m_stoppedEvent.WaitOne(30000)) | ||
493 | Assert.Fail("Script did not co-operatively stop."); | ||
494 | |||
495 | bool running; | ||
496 | TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName); | ||
497 | Assert.That( | ||
498 | SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True); | ||
499 | Assert.That(running, Is.False); | ||
500 | } | ||
501 | |||
502 | private void OnChatFromWorld(object sender, OSChatMessage oscm) | ||
503 | { | ||
504 | Console.WriteLine("Got chat [{0}]", oscm.Message); | ||
505 | m_osChatMessageReceived = oscm; | ||
506 | |||
507 | if (++m_chatMessagesReceived >= m_chatMessagesThreshold) | ||
508 | { | ||
509 | m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld; | ||
510 | m_chatEvent.Set(); | ||
511 | } | ||
512 | } | ||
513 | } | ||
514 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index c9c4753..2e61fb8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | |||
@@ -633,19 +633,44 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
633 | 633 | ||
634 | public LSL_Types.Vector3 GetVector3Item(int itemIndex) | 634 | public LSL_Types.Vector3 GetVector3Item(int itemIndex) |
635 | { | 635 | { |
636 | if(m_data[itemIndex] is LSL_Types.Vector3) | 636 | if (m_data[itemIndex] is LSL_Types.Vector3) |
637 | { | ||
637 | return (LSL_Types.Vector3)m_data[itemIndex]; | 638 | return (LSL_Types.Vector3)m_data[itemIndex]; |
639 | } | ||
640 | else if(m_data[itemIndex] is OpenMetaverse.Vector3) | ||
641 | { | ||
642 | return new LSL_Types.Vector3( | ||
643 | (OpenMetaverse.Vector3)m_data[itemIndex]); | ||
644 | } | ||
638 | else | 645 | else |
646 | { | ||
639 | throw new InvalidCastException(string.Format( | 647 | throw new InvalidCastException(string.Format( |
640 | "{0} expected but {1} given", | 648 | "{0} expected but {1} given", |
641 | typeof(LSL_Types.Vector3).Name, | 649 | typeof(LSL_Types.Vector3).Name, |
642 | m_data[itemIndex] != null ? | 650 | m_data[itemIndex] != null ? |
643 | m_data[itemIndex].GetType().Name : "null")); | 651 | m_data[itemIndex].GetType().Name : "null")); |
652 | } | ||
644 | } | 653 | } |
645 | 654 | ||
646 | public LSL_Types.Quaternion GetQuaternionItem(int itemIndex) | 655 | public LSL_Types.Quaternion GetQuaternionItem(int itemIndex) |
647 | { | 656 | { |
648 | return (LSL_Types.Quaternion)m_data[itemIndex]; | 657 | if (m_data[itemIndex] is LSL_Types.Quaternion) |
658 | { | ||
659 | return (LSL_Types.Quaternion)m_data[itemIndex]; | ||
660 | } | ||
661 | else if(m_data[itemIndex] is OpenMetaverse.Quaternion) | ||
662 | { | ||
663 | return new LSL_Types.Quaternion( | ||
664 | (OpenMetaverse.Quaternion)m_data[itemIndex]); | ||
665 | } | ||
666 | else | ||
667 | { | ||
668 | throw new InvalidCastException(string.Format( | ||
669 | "{0} expected but {1} given", | ||
670 | typeof(LSL_Types.Quaternion).Name, | ||
671 | m_data[itemIndex] != null ? | ||
672 | m_data[itemIndex].GetType().Name : "null")); | ||
673 | } | ||
649 | } | 674 | } |
650 | 675 | ||
651 | public LSL_Types.key GetKeyItem(int itemIndex) | 676 | public LSL_Types.key GetKeyItem(int itemIndex) |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index c73e22f..6dd6c17 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs | |||
@@ -41,6 +41,7 @@ using OpenSim.Region.OptionalModules.World.NPC; | |||
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.ScriptEngine.Shared; | 42 | using OpenSim.Region.ScriptEngine.Shared; |
43 | using OpenSim.Region.ScriptEngine.Shared.Api; | 43 | using OpenSim.Region.ScriptEngine.Shared.Api; |
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
44 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | 47 | using OpenSim.Tests.Common.Mock; |
@@ -51,14 +52,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
51 | /// Tests for inventory functions in LSL | 52 | /// Tests for inventory functions in LSL |
52 | /// </summary> | 53 | /// </summary> |
53 | [TestFixture] | 54 | [TestFixture] |
54 | public class LSL_ApiInventoryTests | 55 | public class LSL_ApiInventoryTests : OpenSimTestCase |
55 | { | 56 | { |
56 | protected Scene m_scene; | 57 | protected Scene m_scene; |
57 | protected XEngine.XEngine m_engine; | 58 | protected XEngine.XEngine m_engine; |
58 | 59 | ||
59 | [SetUp] | 60 | [SetUp] |
60 | public void SetUp() | 61 | public override void SetUp() |
61 | { | 62 | { |
63 | base.SetUp(); | ||
64 | |||
62 | IConfigSource initConfigSource = new IniConfigSource(); | 65 | IConfigSource initConfigSource = new IniConfigSource(); |
63 | IConfig config = initConfigSource.AddConfig("XEngine"); | 66 | IConfig config = initConfigSource.AddConfig("XEngine"); |
64 | config.Set("Enabled", "true"); | 67 | config.Set("Enabled", "true"); |
@@ -91,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
91 | TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); | 94 | TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); |
92 | 95 | ||
93 | LSL_Api api = new LSL_Api(); | 96 | LSL_Api api = new LSL_Api(); |
94 | api.Initialize(m_engine, so1.RootPart, null); | 97 | api.Initialize(m_engine, so1.RootPart, null, null); |
95 | 98 | ||
96 | // Create a second object | 99 | // Create a second object |
97 | SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); | 100 | SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); |
@@ -124,7 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
124 | SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); | 127 | SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); |
125 | m_scene.AddSceneObject(so1); | 128 | m_scene.AddSceneObject(so1); |
126 | LSL_Api api = new LSL_Api(); | 129 | LSL_Api api = new LSL_Api(); |
127 | api.Initialize(m_engine, so1.RootPart, null); | 130 | api.Initialize(m_engine, so1.RootPart, null, null); |
128 | 131 | ||
129 | // Create an object embedded inside the first | 132 | // Create an object embedded inside the first |
130 | UUID itemId = TestHelpers.ParseTail(0x20); | 133 | UUID itemId = TestHelpers.ParseTail(0x20); |
@@ -134,7 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
134 | SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); | 137 | SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); |
135 | m_scene.AddSceneObject(so2); | 138 | m_scene.AddSceneObject(so2); |
136 | LSL_Api api2 = new LSL_Api(); | 139 | LSL_Api api2 = new LSL_Api(); |
137 | api2.Initialize(m_engine, so2.RootPart, null); | 140 | api2.Initialize(m_engine, so2.RootPart, null, null); |
138 | 141 | ||
139 | // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** | 142 | // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** |
140 | api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); | 143 | api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index 2565ae7..5b57bbe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs | |||
@@ -41,6 +41,7 @@ using OpenSim.Region.OptionalModules.World.NPC; | |||
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.ScriptEngine.Shared; | 42 | using OpenSim.Region.ScriptEngine.Shared; |
43 | using OpenSim.Region.ScriptEngine.Shared.Api; | 43 | using OpenSim.Region.ScriptEngine.Shared.Api; |
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
44 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
45 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
46 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
@@ -56,14 +57,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
56 | /// OpenSim.Region.Framework.Scenes.Tests.SceneObjectLinkingTests. | 57 | /// OpenSim.Region.Framework.Scenes.Tests.SceneObjectLinkingTests. |
57 | /// </remarks> | 58 | /// </remarks> |
58 | [TestFixture] | 59 | [TestFixture] |
59 | public class LSL_ApiLinkingTests | 60 | public class LSL_ApiLinkingTests : OpenSimTestCase |
60 | { | 61 | { |
61 | protected Scene m_scene; | 62 | protected Scene m_scene; |
62 | protected XEngine.XEngine m_engine; | 63 | protected XEngine.XEngine m_engine; |
63 | 64 | ||
64 | [SetUp] | 65 | [SetUp] |
65 | public void SetUp() | 66 | public override void SetUp() |
66 | { | 67 | { |
68 | base.SetUp(); | ||
69 | |||
67 | IConfigSource initConfigSource = new IniConfigSource(); | 70 | IConfigSource initConfigSource = new IniConfigSource(); |
68 | IConfig config = initConfigSource.AddConfig("XEngine"); | 71 | IConfig config = initConfigSource.AddConfig("XEngine"); |
69 | config.Set("Enabled", "true"); | 72 | config.Set("Enabled", "true"); |
@@ -102,7 +105,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
102 | m_scene.AddSceneObject(grp2); | 105 | m_scene.AddSceneObject(grp2); |
103 | 106 | ||
104 | LSL_Api apiGrp1 = new LSL_Api(); | 107 | LSL_Api apiGrp1 = new LSL_Api(); |
105 | apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item); | 108 | apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item, null); |
106 | 109 | ||
107 | apiGrp1.llCreateLink(grp2.UUID.ToString(), ScriptBaseClass.TRUE); | 110 | apiGrp1.llCreateLink(grp2.UUID.ToString(), ScriptBaseClass.TRUE); |
108 | 111 | ||
@@ -129,7 +132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
129 | grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; | 132 | grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; |
130 | 133 | ||
131 | LSL_Api apiGrp1 = new LSL_Api(); | 134 | LSL_Api apiGrp1 = new LSL_Api(); |
132 | apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item); | 135 | apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item, null); |
133 | 136 | ||
134 | apiGrp1.llBreakLink(2); | 137 | apiGrp1.llBreakLink(2); |
135 | 138 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs index dd23be8..60de5cb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs | |||
@@ -34,6 +34,7 @@ using OpenSim.Region.ScriptEngine.Shared; | |||
34 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
35 | using Nini.Config; | 35 | using Nini.Config; |
36 | using OpenSim.Region.ScriptEngine.Shared.Api; | 36 | using OpenSim.Region.ScriptEngine.Shared.Api; |
37 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
37 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 38 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
38 | using OpenMetaverse; | 39 | using OpenMetaverse; |
39 | using OpenSim.Tests.Common.Mock; | 40 | using OpenSim.Tests.Common.Mock; |
@@ -46,13 +47,15 @@ using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | |||
46 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 47 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
47 | { | 48 | { |
48 | [TestFixture] | 49 | [TestFixture] |
49 | public class LSL_ApiListTests | 50 | public class LSL_ApiListTests : OpenSimTestCase |
50 | { | 51 | { |
51 | private LSL_Api m_lslApi; | 52 | private LSL_Api m_lslApi; |
52 | 53 | ||
53 | [SetUp] | 54 | [SetUp] |
54 | public void SetUp() | 55 | public override void SetUp() |
55 | { | 56 | { |
57 | base.SetUp(); | ||
58 | |||
56 | IConfigSource initConfigSource = new IniConfigSource(); | 59 | IConfigSource initConfigSource = new IniConfigSource(); |
57 | IConfig config = initConfigSource.AddConfig("XEngine"); | 60 | IConfig config = initConfigSource.AddConfig("XEngine"); |
58 | config.Set("Enabled", "true"); | 61 | config.Set("Enabled", "true"); |
@@ -65,7 +68,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
65 | engine.AddRegion(scene); | 68 | engine.AddRegion(scene); |
66 | 69 | ||
67 | m_lslApi = new LSL_Api(); | 70 | m_lslApi = new LSL_Api(); |
68 | m_lslApi.Initialize(engine, part, null); | 71 | m_lslApi.Initialize(engine, part, null, null); |
69 | } | 72 | } |
70 | 73 | ||
71 | [Test] | 74 | [Test] |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index c41d1e7..e97ae06 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs | |||
@@ -33,6 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; | |||
33 | using OpenSim.Region.Framework.Scenes; | 33 | using OpenSim.Region.Framework.Scenes; |
34 | using Nini.Config; | 34 | using Nini.Config; |
35 | using OpenSim.Region.ScriptEngine.Shared.Api; | 35 | using OpenSim.Region.ScriptEngine.Shared.Api; |
36 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
36 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 37 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
37 | using OpenMetaverse; | 38 | using OpenMetaverse; |
38 | using System; | 39 | using System; |
@@ -66,7 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
66 | engine.AddRegion(scene); | 67 | engine.AddRegion(scene); |
67 | 68 | ||
68 | m_lslApi = new LSL_Api(); | 69 | m_lslApi = new LSL_Api(); |
69 | m_lslApi.Initialize(engine, part, null); | 70 | m_lslApi.Initialize(engine, part, null, null); |
70 | } | 71 | } |
71 | 72 | ||
72 | [Test] | 73 | [Test] |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs index 3ed2562..c8c7f82 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs | |||
@@ -33,7 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; | |||
33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
34 | { | 34 | { |
35 | [TestFixture] | 35 | [TestFixture] |
36 | public class LSL_TypesTestLSLFloat | 36 | public class LSL_TypesTestLSLFloat : OpenSimTestCase |
37 | { | 37 | { |
38 | // Used for testing equality of two floats. | 38 | // Used for testing equality of two floats. |
39 | private double _lowPrecisionTolerance = 0.000001; | 39 | private double _lowPrecisionTolerance = 0.000001; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs index 8d1169a..c664108 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs | |||
@@ -33,7 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; | |||
33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
34 | { | 34 | { |
35 | [TestFixture] | 35 | [TestFixture] |
36 | public class LSL_TypesTestLSLInteger | 36 | public class LSL_TypesTestLSLInteger : OpenSimTestCase |
37 | { | 37 | { |
38 | private Dictionary<double, int> m_doubleIntSet; | 38 | private Dictionary<double, int> m_doubleIntSet; |
39 | private Dictionary<string, int> m_stringIntSet; | 39 | private Dictionary<string, int> m_stringIntSet; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs index c4ca1a8..8550f2d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs | |||
@@ -33,7 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; | |||
33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
34 | { | 34 | { |
35 | [TestFixture] | 35 | [TestFixture] |
36 | public class LSL_TypesTestLSLString | 36 | public class LSL_TypesTestLSLString : OpenSimTestCase |
37 | { | 37 | { |
38 | private Dictionary<double, string> m_doubleStringSet; | 38 | private Dictionary<double, string> m_doubleStringSet; |
39 | 39 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs index b81225f..71b88bc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs | |||
@@ -36,7 +36,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
36 | /// Tests the LSL_Types.list class. | 36 | /// Tests the LSL_Types.list class. |
37 | /// </summary> | 37 | /// </summary> |
38 | [TestFixture] | 38 | [TestFixture] |
39 | public class LSL_TypesTestList | 39 | public class LSL_TypesTestList : OpenSimTestCase |
40 | { | 40 | { |
41 | /// <summary> | 41 | /// <summary> |
42 | /// Tests concatenating a string to a list. | 42 | /// Tests concatenating a string to a list. |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs index ebf8001..0c838af 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs | |||
@@ -36,7 +36,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
36 | /// Tests for Vector3 | 36 | /// Tests for Vector3 |
37 | /// </summary> | 37 | /// </summary> |
38 | [TestFixture] | 38 | [TestFixture] |
39 | public class LSL_TypesTestVector3 | 39 | public class LSL_TypesTestVector3 : OpenSimTestCase |
40 | { | 40 | { |
41 | [Test] | 41 | [Test] |
42 | public void TestDotProduct() | 42 | public void TestDotProduct() |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index c401794..c88bad5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs | |||
@@ -41,6 +41,7 @@ using OpenSim.Region.OptionalModules.World.NPC; | |||
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.ScriptEngine.Shared; | 42 | using OpenSim.Region.ScriptEngine.Shared; |
43 | using OpenSim.Region.ScriptEngine.Shared.Api; | 43 | using OpenSim.Region.ScriptEngine.Shared.Api; |
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
44 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | 47 | using OpenSim.Tests.Common.Mock; |
@@ -51,14 +52,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
51 | /// Tests for OSSL_Api | 52 | /// Tests for OSSL_Api |
52 | /// </summary> | 53 | /// </summary> |
53 | [TestFixture] | 54 | [TestFixture] |
54 | public class OSSL_ApiAppearanceTest | 55 | public class OSSL_ApiAppearanceTest : OpenSimTestCase |
55 | { | 56 | { |
56 | protected Scene m_scene; | 57 | protected Scene m_scene; |
57 | protected XEngine.XEngine m_engine; | 58 | protected XEngine.XEngine m_engine; |
58 | 59 | ||
59 | [SetUp] | 60 | [SetUp] |
60 | public void SetUp() | 61 | public override void SetUp() |
61 | { | 62 | { |
63 | base.SetUp(); | ||
64 | |||
62 | IConfigSource initConfigSource = new IniConfigSource(); | 65 | IConfigSource initConfigSource = new IniConfigSource(); |
63 | IConfig config = initConfigSource.AddConfig("XEngine"); | 66 | IConfig config = initConfigSource.AddConfig("XEngine"); |
64 | config.Set("Enabled", "true"); | 67 | config.Set("Enabled", "true"); |
@@ -91,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
91 | m_scene.AddSceneObject(so); | 94 | m_scene.AddSceneObject(so); |
92 | 95 | ||
93 | OSSL_Api osslApi = new OSSL_Api(); | 96 | OSSL_Api osslApi = new OSSL_Api(); |
94 | osslApi.Initialize(m_engine, part, null); | 97 | osslApi.Initialize(m_engine, part, null, null); |
95 | 98 | ||
96 | string notecardName = "appearanceNc"; | 99 | string notecardName = "appearanceNc"; |
97 | 100 | ||
@@ -132,7 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
132 | m_scene.AddSceneObject(so); | 135 | m_scene.AddSceneObject(so); |
133 | 136 | ||
134 | OSSL_Api osslApi = new OSSL_Api(); | 137 | OSSL_Api osslApi = new OSSL_Api(); |
135 | osslApi.Initialize(m_engine, part, null); | 138 | osslApi.Initialize(m_engine, part, null, null); |
136 | 139 | ||
137 | string notecardName = "appearanceNc"; | 140 | string notecardName = "appearanceNc"; |
138 | 141 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs index 5ed1f3d..b2803a1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs | |||
@@ -41,6 +41,7 @@ using OpenSim.Region.CoreModules.Framework.InventoryAccess; | |||
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.ScriptEngine.Shared; | 42 | using OpenSim.Region.ScriptEngine.Shared; |
43 | using OpenSim.Region.ScriptEngine.Shared.Api; | 43 | using OpenSim.Region.ScriptEngine.Shared.Api; |
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
44 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | 47 | using OpenSim.Tests.Common.Mock; |
@@ -98,9 +99,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
98 | SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); | 99 | SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); |
99 | TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); | 100 | TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); |
100 | 101 | ||
101 | new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); | 102 | new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); |
102 | OSSL_Api osslApi = new OSSL_Api(); | 103 | OSSL_Api osslApi = new OSSL_Api(); |
103 | osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); | 104 | osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); |
104 | 105 | ||
105 | // SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ua1.PrincipalID); | 106 | // SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ua1.PrincipalID); |
106 | 107 | ||
@@ -144,9 +145,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
144 | SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); | 145 | SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); |
145 | TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); | 146 | TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); |
146 | 147 | ||
147 | new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); | 148 | new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); |
148 | OSSL_Api osslApi = new OSSL_Api(); | 149 | OSSL_Api osslApi = new OSSL_Api(); |
149 | osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); | 150 | osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); |
150 | 151 | ||
151 | // Create an object embedded inside the first | 152 | // Create an object embedded inside the first |
152 | TaskInventoryHelpers.AddNotecard( | 153 | TaskInventoryHelpers.AddNotecard( |
@@ -192,12 +193,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
192 | SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); | 193 | SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); |
193 | TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); | 194 | TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); |
194 | 195 | ||
195 | new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); | 196 | new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); |
196 | OSSL_Api osslApi = new OSSL_Api(); | 197 | OSSL_Api osslApi = new OSSL_Api(); |
197 | osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); | 198 | osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); |
198 | 199 | ||
199 | // Create an object embedded inside the first | 200 | // Create an object embedded inside the first |
200 | TaskInventoryHelpers.AddSceneObject(m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, ua1.PrincipalID); | 201 | TaskInventoryHelpers.AddSceneObject( |
202 | m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, ua1.PrincipalID); | ||
201 | 203 | ||
202 | ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, ua2); | 204 | ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, ua2); |
203 | 205 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index b49bcc2..1f8a6e5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | |||
@@ -42,6 +42,7 @@ using OpenSim.Region.OptionalModules.World.NPC; | |||
42 | using OpenSim.Region.Framework.Scenes; | 42 | using OpenSim.Region.Framework.Scenes; |
43 | using OpenSim.Region.ScriptEngine.Shared; | 43 | using OpenSim.Region.ScriptEngine.Shared; |
44 | using OpenSim.Region.ScriptEngine.Shared.Api; | 44 | using OpenSim.Region.ScriptEngine.Shared.Api; |
45 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 46 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
46 | using OpenSim.Services.Interfaces; | 47 | using OpenSim.Services.Interfaces; |
47 | using OpenSim.Tests.Common; | 48 | using OpenSim.Tests.Common; |
@@ -99,7 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
99 | m_scene.AddSceneObject(so); | 100 | m_scene.AddSceneObject(so); |
100 | 101 | ||
101 | OSSL_Api osslApi = new OSSL_Api(); | 102 | OSSL_Api osslApi = new OSSL_Api(); |
102 | osslApi.Initialize(m_engine, part, null); | 103 | osslApi.Initialize(m_engine, part, null, null); |
103 | 104 | ||
104 | string notecardName = "appearanceNc"; | 105 | string notecardName = "appearanceNc"; |
105 | osslApi.osOwnerSaveAppearance(notecardName); | 106 | osslApi.osOwnerSaveAppearance(notecardName); |
@@ -125,14 +126,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
125 | m_scene.AddSceneObject(so); | 126 | m_scene.AddSceneObject(so); |
126 | 127 | ||
127 | OSSL_Api osslApi = new OSSL_Api(); | 128 | OSSL_Api osslApi = new OSSL_Api(); |
128 | osslApi.Initialize(m_engine, so.RootPart, null); | 129 | osslApi.Initialize(m_engine, so.RootPart, null, null); |
129 | 130 | ||
130 | string npcRaw; | ||
131 | bool gotExpectedException = false; | 131 | bool gotExpectedException = false; |
132 | try | 132 | try |
133 | { | 133 | { |
134 | npcRaw | 134 | osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), "not existing notecard name"); |
135 | = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), "not existing notecard name"); | ||
136 | } | 135 | } |
137 | catch (ScriptException) | 136 | catch (ScriptException) |
138 | { | 137 | { |
@@ -162,7 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
162 | m_scene.AddSceneObject(so); | 161 | m_scene.AddSceneObject(so); |
163 | 162 | ||
164 | OSSL_Api osslApi = new OSSL_Api(); | 163 | OSSL_Api osslApi = new OSSL_Api(); |
165 | osslApi.Initialize(m_engine, part, null); | 164 | osslApi.Initialize(m_engine, part, null, null); |
166 | 165 | ||
167 | string notecardName = "appearanceNc"; | 166 | string notecardName = "appearanceNc"; |
168 | osslApi.osOwnerSaveAppearance(notecardName); | 167 | osslApi.osOwnerSaveAppearance(notecardName); |
@@ -196,7 +195,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
196 | m_scene.AddSceneObject(so); | 195 | m_scene.AddSceneObject(so); |
197 | 196 | ||
198 | OSSL_Api osslApi = new OSSL_Api(); | 197 | OSSL_Api osslApi = new OSSL_Api(); |
199 | osslApi.Initialize(m_engine, part, null); | 198 | osslApi.Initialize(m_engine, part, null, null); |
200 | 199 | ||
201 | osslApi.osOwnerSaveAppearance(firstAppearanceNcName); | 200 | osslApi.osOwnerSaveAppearance(firstAppearanceNcName); |
202 | 201 | ||
@@ -234,7 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
234 | m_scene.AddSceneObject(so); | 233 | m_scene.AddSceneObject(so); |
235 | 234 | ||
236 | OSSL_Api osslApi = new OSSL_Api(); | 235 | OSSL_Api osslApi = new OSSL_Api(); |
237 | osslApi.Initialize(m_engine, part, null); | 236 | osslApi.Initialize(m_engine, part, null, null); |
238 | 237 | ||
239 | osslApi.osOwnerSaveAppearance(firstAppearanceNcName); | 238 | osslApi.osOwnerSaveAppearance(firstAppearanceNcName); |
240 | 239 | ||
@@ -286,10 +285,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
286 | m_scene.AddSceneObject(otherSo); | 285 | m_scene.AddSceneObject(otherSo); |
287 | 286 | ||
288 | OSSL_Api osslApi = new OSSL_Api(); | 287 | OSSL_Api osslApi = new OSSL_Api(); |
289 | osslApi.Initialize(m_engine, part, null); | 288 | osslApi.Initialize(m_engine, part, null, null); |
290 | 289 | ||
291 | OSSL_Api otherOsslApi = new OSSL_Api(); | 290 | OSSL_Api otherOsslApi = new OSSL_Api(); |
292 | otherOsslApi.Initialize(m_engine, otherPart, null); | 291 | otherOsslApi.Initialize(m_engine, otherPart, null, null); |
293 | 292 | ||
294 | string notecardName = "appearanceNc"; | 293 | string notecardName = "appearanceNc"; |
295 | osslApi.osOwnerSaveAppearance(notecardName); | 294 | osslApi.osOwnerSaveAppearance(notecardName); |
@@ -333,7 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
333 | m_scene.AddSceneObject(so); | 332 | m_scene.AddSceneObject(so); |
334 | 333 | ||
335 | OSSL_Api osslApi = new OSSL_Api(); | 334 | OSSL_Api osslApi = new OSSL_Api(); |
336 | osslApi.Initialize(m_engine, part, null); | 335 | osslApi.Initialize(m_engine, part, null, null); |
337 | 336 | ||
338 | string notecardName = "appearanceNc"; | 337 | string notecardName = "appearanceNc"; |
339 | osslApi.osOwnerSaveAppearance(notecardName); | 338 | osslApi.osOwnerSaveAppearance(notecardName); |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs new file mode 100644 index 0000000..f4211c8 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs | |||
@@ -0,0 +1,61 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Runtime.Remoting; | ||
30 | using System.Runtime.Remoting.Lifetime; | ||
31 | using System.Security.Permissions; | ||
32 | using System.Threading; | ||
33 | using System.Reflection; | ||
34 | using System.Collections; | ||
35 | using System.Collections.Generic; | ||
36 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
37 | using OpenSim.Region.ScriptEngine.Shared; | ||
38 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
39 | |||
40 | namespace OpenSim.Region.ScriptEngine.XEngine.ScriptBase | ||
41 | { | ||
42 | public class XEngineScriptBase : ScriptBaseClass | ||
43 | { | ||
44 | /// <summary> | ||
45 | /// Used for script sleeps when we are using co-operative script termination. | ||
46 | /// </summary> | ||
47 | /// <remarks>null if co-operative script termination is not active</remarks> | ||
48 | WaitHandle m_coopSleepHandle; | ||
49 | |||
50 | public XEngineScriptBase(WaitHandle coopSleepHandle) : base() | ||
51 | { | ||
52 | m_coopSleepHandle = coopSleepHandle; | ||
53 | } | ||
54 | |||
55 | public void opensim_reserved_CheckForCoopTermination() | ||
56 | { | ||
57 | if (m_coopSleepHandle != null && m_coopSleepHandle.WaitOne(0)) | ||
58 | throw new ScriptCoopStopException(); | ||
59 | } | ||
60 | } | ||
61 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index 9405075..0ff2da3 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs | |||
@@ -52,7 +52,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
52 | { | 52 | { |
53 | myScriptEngine = _ScriptEngine; | 53 | myScriptEngine = _ScriptEngine; |
54 | 54 | ||
55 | m_log.Info("[XEngine] Hooking up to server events"); | 55 | // m_log.Info("[XEngine] Hooking up to server events"); |
56 | myScriptEngine.World.EventManager.OnAttach += attach; | 56 | myScriptEngine.World.EventManager.OnAttach += attach; |
57 | myScriptEngine.World.EventManager.OnObjectGrab += touch_start; | 57 | myScriptEngine.World.EventManager.OnObjectGrab += touch_start; |
58 | myScriptEngine.World.EventManager.OnObjectGrabbing += touch; | 58 | myScriptEngine.World.EventManager.OnObjectGrabbing += touch; |
@@ -62,6 +62,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
62 | myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; | 62 | myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; |
63 | myScriptEngine.World.EventManager.OnScriptAtRotTargetEvent += at_rot_target; | 63 | myScriptEngine.World.EventManager.OnScriptAtRotTargetEvent += at_rot_target; |
64 | myScriptEngine.World.EventManager.OnScriptNotAtRotTargetEvent += not_at_rot_target; | 64 | myScriptEngine.World.EventManager.OnScriptNotAtRotTargetEvent += not_at_rot_target; |
65 | myScriptEngine.World.EventManager.OnScriptMovingStartEvent += moving_start; | ||
66 | myScriptEngine.World.EventManager.OnScriptMovingEndEvent += moving_end; | ||
65 | myScriptEngine.World.EventManager.OnScriptControlEvent += control; | 67 | myScriptEngine.World.EventManager.OnScriptControlEvent += control; |
66 | myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start; | 68 | myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start; |
67 | myScriptEngine.World.EventManager.OnScriptColliding += collision; | 69 | myScriptEngine.World.EventManager.OnScriptColliding += collision; |
@@ -69,7 +71,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
69 | myScriptEngine.World.EventManager.OnScriptLandColliderStart += land_collision_start; | 71 | myScriptEngine.World.EventManager.OnScriptLandColliderStart += land_collision_start; |
70 | myScriptEngine.World.EventManager.OnScriptLandColliding += land_collision; | 72 | myScriptEngine.World.EventManager.OnScriptLandColliding += land_collision; |
71 | myScriptEngine.World.EventManager.OnScriptLandColliderEnd += land_collision_end; | 73 | myScriptEngine.World.EventManager.OnScriptLandColliderEnd += land_collision_end; |
72 | IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>(); | 74 | IMoneyModule money = myScriptEngine.World.RequestModuleInterface<IMoneyModule>(); |
73 | if (money != null) | 75 | if (money != null) |
74 | { | 76 | { |
75 | money.OnObjectPaid+=HandleObjectPaid; | 77 | money.OnObjectPaid+=HandleObjectPaid; |
@@ -419,14 +421,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
419 | // dataserver: not handled here | 421 | // dataserver: not handled here |
420 | // link_message: not handled here | 422 | // link_message: not handled here |
421 | 423 | ||
422 | public void moving_start(uint localID, UUID itemID) | 424 | public void moving_start(uint localID) |
423 | { | 425 | { |
424 | myScriptEngine.PostObjectEvent(localID, new EventParams( | 426 | myScriptEngine.PostObjectEvent(localID, new EventParams( |
425 | "moving_start",new object[0], | 427 | "moving_start",new object[0], |
426 | new DetectParams[0])); | 428 | new DetectParams[0])); |
427 | } | 429 | } |
428 | 430 | ||
429 | public void moving_end(uint localID, UUID itemID) | 431 | public void moving_end(uint localID) |
430 | { | 432 | { |
431 | myScriptEngine.PostObjectEvent(localID, new EventParams( | 433 | myScriptEngine.PostObjectEvent(localID, new EventParams( |
432 | "moving_end",new object[0], | 434 | "moving_end",new object[0], |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs b/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs new file mode 100644 index 0000000..efb854d --- /dev/null +++ b/OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs | |||
@@ -0,0 +1,126 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using OpenSim.Framework; | ||
31 | using OpenSim.Framework.Console; | ||
32 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
33 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
34 | using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; | ||
35 | |||
36 | namespace OpenSim.Region.ScriptEngine.XEngine | ||
37 | { | ||
38 | public class ScriptEngineConsoleCommands | ||
39 | { | ||
40 | IScriptEngine m_engine; | ||
41 | |||
42 | public ScriptEngineConsoleCommands(IScriptEngine engine) | ||
43 | { | ||
44 | m_engine = engine; | ||
45 | } | ||
46 | |||
47 | public void RegisterCommands() | ||
48 | { | ||
49 | MainConsole.Instance.Commands.AddCommand( | ||
50 | "Scripts", false, "show script sensors", "show script sensors", "Show script sensors information", | ||
51 | HandleShowSensors); | ||
52 | |||
53 | MainConsole.Instance.Commands.AddCommand( | ||
54 | "Scripts", false, "show script timers", "show script timers", "Show script sensors information", | ||
55 | HandleShowTimers); | ||
56 | } | ||
57 | |||
58 | private bool IsSceneSelected() | ||
59 | { | ||
60 | return MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_engine.World; | ||
61 | } | ||
62 | |||
63 | private void HandleShowSensors(string module, string[] cmdparams) | ||
64 | { | ||
65 | if (!IsSceneSelected()) | ||
66 | return; | ||
67 | |||
68 | SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(m_engine); | ||
69 | |||
70 | if (sr == null) | ||
71 | { | ||
72 | MainConsole.Instance.Output("Plugin not yet initialized"); | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | List<SensorRepeat.SensorInfo> sensorInfo = sr.GetSensorInfo(); | ||
77 | |||
78 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
79 | cdt.AddColumn("Part name", 40); | ||
80 | cdt.AddColumn("Script item ID", 36); | ||
81 | cdt.AddColumn("Type", 4); | ||
82 | cdt.AddColumn("Interval", 8); | ||
83 | cdt.AddColumn("Range", 8); | ||
84 | cdt.AddColumn("Arc", 8); | ||
85 | |||
86 | foreach (SensorRepeat.SensorInfo s in sensorInfo) | ||
87 | { | ||
88 | cdt.AddRow(s.host.Name, s.itemID, s.type, s.interval, s.range, s.arc); | ||
89 | } | ||
90 | |||
91 | MainConsole.Instance.Output(cdt.ToString()); | ||
92 | MainConsole.Instance.OutputFormat("Total: {0}", sensorInfo.Count); | ||
93 | } | ||
94 | |||
95 | private void HandleShowTimers(string module, string[] cmdparams) | ||
96 | { | ||
97 | if (!IsSceneSelected()) | ||
98 | return; | ||
99 | |||
100 | Timer timerPlugin = AsyncCommandManager.GetTimerPlugin(m_engine); | ||
101 | |||
102 | if (timerPlugin == null) | ||
103 | { | ||
104 | MainConsole.Instance.Output("Plugin not yet initialized"); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | List<Timer.TimerInfo> timersInfo = timerPlugin.GetTimersInfo(); | ||
109 | |||
110 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
111 | cdt.AddColumn("Part local ID", 13); | ||
112 | cdt.AddColumn("Script item ID", 36); | ||
113 | cdt.AddColumn("Interval", 10); | ||
114 | cdt.AddColumn("Next", 8); | ||
115 | |||
116 | foreach (Timer.TimerInfo t in timersInfo) | ||
117 | { | ||
118 | // Convert from 100 ns ticks back to seconds | ||
119 | cdt.AddRow(t.localID, t.itemID, (double)t.interval / 10000000, t.next); | ||
120 | } | ||
121 | |||
122 | MainConsole.Instance.Output(cdt.ToString()); | ||
123 | MainConsole.Instance.OutputFormat("Total: {0}", timersInfo.Count); | ||
124 | } | ||
125 | } | ||
126 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs index f331658..5abfe9a 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs | |||
@@ -44,7 +44,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests | |||
44 | /// XEngine tests. | 44 | /// XEngine tests. |
45 | /// </summary> | 45 | /// </summary> |
46 | [TestFixture] | 46 | [TestFixture] |
47 | public class XEngineTest | 47 | public class XEngineTest : OpenSimTestCase |
48 | { | 48 | { |
49 | private TestScene m_scene; | 49 | private TestScene m_scene; |
50 | private XEngine m_xEngine; | 50 | private XEngine m_xEngine; |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 9f05666..17243ab 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -31,6 +31,7 @@ using System.Collections.Generic; | |||
31 | using System.Diagnostics; //for [DebuggerNonUserCode] | 31 | using System.Diagnostics; //for [DebuggerNonUserCode] |
32 | using System.Globalization; | 32 | using System.Globalization; |
33 | using System.IO; | 33 | using System.IO; |
34 | using System.Linq; | ||
34 | using System.Reflection; | 35 | using System.Reflection; |
35 | using System.Security; | 36 | using System.Security; |
36 | using System.Security.Policy; | 37 | using System.Security.Policy; |
@@ -46,13 +47,14 @@ using OpenSim.Framework; | |||
46 | using OpenSim.Framework.Console; | 47 | using OpenSim.Framework.Console; |
47 | using OpenSim.Region.Framework.Scenes; | 48 | using OpenSim.Region.Framework.Scenes; |
48 | using OpenSim.Region.Framework.Interfaces; | 49 | using OpenSim.Region.Framework.Interfaces; |
50 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
49 | using OpenSim.Region.ScriptEngine.Shared; | 51 | using OpenSim.Region.ScriptEngine.Shared; |
50 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
51 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; | 52 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; |
52 | using OpenSim.Region.ScriptEngine.Shared.Instance; | 53 | using OpenSim.Region.ScriptEngine.Shared.Instance; |
53 | using OpenSim.Region.ScriptEngine.Shared.Api; | 54 | using OpenSim.Region.ScriptEngine.Shared.Api; |
54 | using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; | 55 | using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; |
55 | using OpenSim.Region.ScriptEngine.Interfaces; | 56 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
57 | using OpenSim.Region.ScriptEngine.XEngine.ScriptBase; | ||
56 | using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; | 58 | using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; |
57 | 59 | ||
58 | using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; | 60 | using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; |
@@ -107,6 +109,24 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
107 | private IXmlRpcRouter m_XmlRpcRouter; | 109 | private IXmlRpcRouter m_XmlRpcRouter; |
108 | private int m_EventLimit; | 110 | private int m_EventLimit; |
109 | private bool m_KillTimedOutScripts; | 111 | private bool m_KillTimedOutScripts; |
112 | |||
113 | /// <summary> | ||
114 | /// Number of milliseconds we will wait for a script event to complete on script stop before we forcibly abort | ||
115 | /// its thread. | ||
116 | /// </summary> | ||
117 | /// <remarks> | ||
118 | /// It appears that if a script thread is aborted whilst it is holding ReaderWriterLockSlim (possibly the write | ||
119 | /// lock) then the lock is not properly released. This causes mono 2.6, 2.10 and possibly | ||
120 | /// later to crash, sometimes with symptoms such as a leap to 100% script usage and a vm thead dump showing | ||
121 | /// all threads waiting on release of ReaderWriterLockSlim write thread which none of the threads listed | ||
122 | /// actually hold. | ||
123 | /// | ||
124 | /// Pausing for event completion reduces the risk of this happening. However, it may be that aborting threads | ||
125 | /// is not a mono issue per se but rather a risky activity in itself in an AppDomain that is not immediately | ||
126 | /// shutting down. | ||
127 | /// </remarks> | ||
128 | private int m_WaitForEventCompletionOnScriptStop = 1000; | ||
129 | |||
110 | private string m_ScriptEnginesPath = null; | 130 | private string m_ScriptEnginesPath = null; |
111 | 131 | ||
112 | private ExpiringCache<UUID, bool> m_runFlags = new ExpiringCache<UUID, bool>(); | 132 | private ExpiringCache<UUID, bool> m_runFlags = new ExpiringCache<UUID, bool>(); |
@@ -218,11 +238,21 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
218 | } | 238 | } |
219 | } | 239 | } |
220 | 240 | ||
241 | private ScriptEngineConsoleCommands m_consoleCommands; | ||
242 | |||
221 | public string ScriptEngineName | 243 | public string ScriptEngineName |
222 | { | 244 | { |
223 | get { return "XEngine"; } | 245 | get { return "XEngine"; } |
224 | } | 246 | } |
225 | 247 | ||
248 | public string ScriptClassName { get; private set; } | ||
249 | |||
250 | public string ScriptBaseClassName { get; private set; } | ||
251 | |||
252 | public ParameterInfo[] ScriptBaseClassParameters { get; private set; } | ||
253 | |||
254 | public string[] ScriptReferencedAssemblies { get; private set; } | ||
255 | |||
226 | public Scene World | 256 | public Scene World |
227 | { | 257 | { |
228 | get { return m_Scene; } | 258 | get { return m_Scene; } |
@@ -277,21 +307,35 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
277 | 307 | ||
278 | m_ScriptConfig = configSource.Configs["XEngine"]; | 308 | m_ScriptConfig = configSource.Configs["XEngine"]; |
279 | m_ConfigSource = configSource; | 309 | m_ConfigSource = configSource; |
310 | |||
311 | string rawScriptStopStrategy = m_ScriptConfig.GetString("ScriptStopStrategy", "abort"); | ||
312 | |||
313 | m_log.InfoFormat("[XEngine]: Script stop strategy is {0}", rawScriptStopStrategy); | ||
314 | |||
315 | if (rawScriptStopStrategy == "co-op") | ||
316 | { | ||
317 | ScriptClassName = "XEngineScript"; | ||
318 | ScriptBaseClassName = typeof(XEngineScriptBase).FullName; | ||
319 | ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters(); | ||
320 | ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) }; | ||
321 | } | ||
322 | else | ||
323 | { | ||
324 | ScriptClassName = "Script"; | ||
325 | ScriptBaseClassName = typeof(ScriptBaseClass).FullName; | ||
326 | } | ||
327 | |||
328 | // Console.WriteLine("ASSEMBLY NAME: {0}", ScriptReferencedAssemblies[0]); | ||
280 | } | 329 | } |
281 | 330 | ||
282 | public void AddRegion(Scene scene) | 331 | public void AddRegion(Scene scene) |
283 | { | 332 | { |
284 | if (m_ScriptConfig == null) | 333 | if (m_ScriptConfig == null) |
285 | return; | 334 | return; |
335 | |||
286 | m_ScriptFailCount = 0; | 336 | m_ScriptFailCount = 0; |
287 | m_ScriptErrorMessage = String.Empty; | 337 | m_ScriptErrorMessage = String.Empty; |
288 | 338 | ||
289 | if (m_ScriptConfig == null) | ||
290 | { | ||
291 | // m_log.ErrorFormat("[XEngine] No script configuration found. Scripts disabled"); | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | m_Enabled = m_ScriptConfig.GetBoolean("Enabled", true); | 339 | m_Enabled = m_ScriptConfig.GetBoolean("Enabled", true); |
296 | 340 | ||
297 | if (!m_Enabled) | 341 | if (!m_Enabled) |
@@ -316,6 +360,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
316 | m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); | 360 | m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); |
317 | m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); | 361 | m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); |
318 | m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; | 362 | m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; |
363 | m_WaitForEventCompletionOnScriptStop | ||
364 | = m_ScriptConfig.GetInt("WaitForEventCompletionOnScriptStop", m_WaitForEventCompletionOnScriptStop); | ||
365 | |||
319 | m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); | 366 | m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); |
320 | 367 | ||
321 | m_Prio = ThreadPriority.BelowNormal; | 368 | m_Prio = ThreadPriority.BelowNormal; |
@@ -364,48 +411,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
364 | OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved; | 411 | OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved; |
365 | } | 412 | } |
366 | 413 | ||
414 | m_consoleCommands = new ScriptEngineConsoleCommands(this); | ||
415 | m_consoleCommands.RegisterCommands(); | ||
416 | |||
367 | MainConsole.Instance.Commands.AddCommand( | 417 | MainConsole.Instance.Commands.AddCommand( |
368 | "Scripts", false, "xengine status", "xengine status", "Show status information", | 418 | "Scripts", false, "xengine status", "xengine status", "Show status information", |
369 | "Show status information on the script engine.", | 419 | "Show status information on the script engine.", |
370 | HandleShowStatus); | 420 | HandleShowStatus); |
371 | 421 | ||
372 | MainConsole.Instance.Commands.AddCommand( | 422 | MainConsole.Instance.Commands.AddCommand( |
373 | "Scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information", | 423 | "Scripts", false, "scripts show", "scripts show [<script-item-uuid>+]", "Show script information", |
374 | "Show information on all scripts known to the script engine." | 424 | "Show information on all scripts known to the script engine.\n" |
375 | + "If a <script-item-uuid> is given then only information on that script will be shown.", | 425 | + "If one or more <script-item-uuid>s are given then only information on that script will be shown.", |
376 | HandleShowScripts); | 426 | HandleShowScripts); |
377 | 427 | ||
378 | MainConsole.Instance.Commands.AddCommand( | 428 | MainConsole.Instance.Commands.AddCommand( |
379 | "Scripts", false, "show scripts", "show scripts [<script-item-uuid>]", "Show script information", | 429 | "Scripts", false, "show scripts", "show scripts [<script-item-uuid>+]", "Show script information", |
380 | "Synonym for scripts show command", HandleShowScripts); | 430 | "Synonym for scripts show command", HandleShowScripts); |
381 | 431 | ||
382 | MainConsole.Instance.Commands.AddCommand( | 432 | MainConsole.Instance.Commands.AddCommand( |
383 | "Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts", | 433 | "Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>+]", "Suspends all running scripts", |
384 | "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" | 434 | "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" |
385 | + " script that is currently processing an event.\n" | 435 | + " script that is currently processing an event.\n" |
386 | + "Suspended scripts will continue to accumulate events but won't process them.\n" | 436 | + "Suspended scripts will continue to accumulate events but won't process them.\n" |
387 | + "If a <script-item-uuid> is given then only that script will be suspended. Otherwise, all suitable scripts are suspended.", | 437 | + "If one or more <script-item-uuid>s are given then only that script will be suspended. Otherwise, all suitable scripts are suspended.", |
388 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); | 438 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); |
389 | 439 | ||
390 | MainConsole.Instance.Commands.AddCommand( | 440 | MainConsole.Instance.Commands.AddCommand( |
391 | "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts", | 441 | "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>+]", "Resumes all suspended scripts", |
392 | "Resumes all currently suspended scripts.\n" | 442 | "Resumes all currently suspended scripts.\n" |
393 | + "Resumed scripts will process all events accumulated whilst suspended." | 443 | + "Resumed scripts will process all events accumulated whilst suspended.\n" |
394 | + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", | 444 | + "If one or more <script-item-uuid>s are given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", |
395 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); | 445 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); |
396 | 446 | ||
397 | MainConsole.Instance.Commands.AddCommand( | 447 | MainConsole.Instance.Commands.AddCommand( |
398 | "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts", | 448 | "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>+]", "Stops all running scripts", |
399 | "Stops all running scripts." | 449 | "Stops all running scripts.\n" |
400 | + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", | 450 | + "If one or more <script-item-uuid>s are given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", |
401 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); | 451 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); |
402 | 452 | ||
403 | MainConsole.Instance.Commands.AddCommand( | 453 | MainConsole.Instance.Commands.AddCommand( |
404 | "Scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts", | 454 | "Scripts", false, "scripts start", "scripts start [<script-item-uuid>+]", "Starts all stopped scripts", |
405 | "Starts all stopped scripts." | 455 | "Starts all stopped scripts.\n" |
406 | + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.", | 456 | + "If one or more <script-item-uuid>s are given then only that script will be started. Otherwise, all suitable scripts are started.", |
407 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); | 457 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); |
408 | 458 | ||
459 | MainConsole.Instance.Commands.AddCommand( | ||
460 | "Scripts", false, "debug scripts log", "debug scripts log <item-id> <log-level>", "Extra debug logging for a script", | ||
461 | "Activates or deactivates extra debug logging for the given script.\n" | ||
462 | + "Level == 0, deactivate extra debug logging.\n" | ||
463 | + "Level >= 1, log state changes.\n" | ||
464 | + "Level >= 2, log event invocations.\n", | ||
465 | HandleDebugScriptLogCommand); | ||
466 | |||
409 | // MainConsole.Instance.Commands.AddCommand( | 467 | // MainConsole.Instance.Commands.AddCommand( |
410 | // "Debug", false, "debug xengine", "debug xengine [<level>]", | 468 | // "Debug", false, "debug xengine", "debug xengine [<level>]", |
411 | // "Turn on detailed xengine debugging.", | 469 | // "Turn on detailed xengine debugging.", |
@@ -414,6 +472,41 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
414 | // HandleDebugLevelCommand); | 472 | // HandleDebugLevelCommand); |
415 | } | 473 | } |
416 | 474 | ||
475 | private void HandleDebugScriptLogCommand(string module, string[] args) | ||
476 | { | ||
477 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) | ||
478 | return; | ||
479 | |||
480 | if (args.Length != 5) | ||
481 | { | ||
482 | MainConsole.Instance.Output("Usage: debug script log <item-id> <log-level>"); | ||
483 | return; | ||
484 | } | ||
485 | |||
486 | UUID itemId; | ||
487 | |||
488 | if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, args[3], out itemId)) | ||
489 | return; | ||
490 | |||
491 | int newLevel; | ||
492 | |||
493 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out newLevel)) | ||
494 | return; | ||
495 | |||
496 | IScriptInstance si; | ||
497 | |||
498 | lock (m_Scripts) | ||
499 | { | ||
500 | // XXX: We can't give the user feedback on a bad item id because this may apply to a different script | ||
501 | // engine | ||
502 | if (!m_Scripts.TryGetValue(itemId, out si)) | ||
503 | return; | ||
504 | } | ||
505 | |||
506 | si.DebugLevel = newLevel; | ||
507 | MainConsole.Instance.OutputFormat("Set debug level of {0} {1} to {2}", si.ScriptName, si.ItemID, newLevel); | ||
508 | } | ||
509 | |||
417 | /// <summary> | 510 | /// <summary> |
418 | /// Change debug level | 511 | /// Change debug level |
419 | /// </summary> | 512 | /// </summary> |
@@ -445,9 +538,21 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
445 | /// </summary> | 538 | /// </summary> |
446 | /// <param name="cmdparams"></param> | 539 | /// <param name="cmdparams"></param> |
447 | /// <param name="instance"></param> | 540 | /// <param name="instance"></param> |
448 | /// <returns>true if we're okay to proceed, false if not.</returns> | 541 | /// <param name="comparer">Basis on which to sort output. Can be null if no sort needs to take place</param> |
449 | private void HandleScriptsAction(string[] cmdparams, Action<IScriptInstance> action) | 542 | private void HandleScriptsAction(string[] cmdparams, Action<IScriptInstance> action) |
450 | { | 543 | { |
544 | HandleScriptsAction<object>(cmdparams, action, null); | ||
545 | } | ||
546 | |||
547 | /// <summary> | ||
548 | /// Parse the raw item id into a script instance from the command params if it's present. | ||
549 | /// </summary> | ||
550 | /// <param name="cmdparams"></param> | ||
551 | /// <param name="instance"></param> | ||
552 | /// <param name="keySelector">Basis on which to sort output. Can be null if no sort needs to take place</param> | ||
553 | private void HandleScriptsAction<TKey>( | ||
554 | string[] cmdparams, Action<IScriptInstance> action, Func<IScriptInstance, TKey> keySelector) | ||
555 | { | ||
451 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) | 556 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) |
452 | return; | 557 | return; |
453 | 558 | ||
@@ -458,35 +563,42 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
458 | 563 | ||
459 | if (cmdparams.Length == 2) | 564 | if (cmdparams.Length == 2) |
460 | { | 565 | { |
461 | foreach (IScriptInstance instance in m_Scripts.Values) | 566 | IEnumerable<IScriptInstance> scripts = m_Scripts.Values; |
567 | |||
568 | if (keySelector != null) | ||
569 | scripts = scripts.OrderBy<IScriptInstance, TKey>(keySelector); | ||
570 | |||
571 | foreach (IScriptInstance instance in scripts) | ||
462 | action(instance); | 572 | action(instance); |
463 | 573 | ||
464 | return; | 574 | return; |
465 | } | 575 | } |
466 | 576 | ||
467 | rawItemId = cmdparams[2]; | 577 | for (int i = 2; i < cmdparams.Length; i++) |
468 | |||
469 | if (!UUID.TryParse(rawItemId, out itemId)) | ||
470 | { | ||
471 | MainConsole.Instance.OutputFormat("Error - {0} is not a valid UUID", rawItemId); | ||
472 | return; | ||
473 | } | ||
474 | |||
475 | if (itemId != UUID.Zero) | ||
476 | { | 578 | { |
477 | IScriptInstance instance = GetInstance(itemId); | 579 | rawItemId = cmdparams[i]; |
478 | if (instance == null) | 580 | |
581 | if (!UUID.TryParse(rawItemId, out itemId)) | ||
479 | { | 582 | { |
480 | // Commented out for now since this will cause false reports on simulators with more than | 583 | MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); |
481 | // one scene where the current command line set region is 'root' (which causes commands to | 584 | continue; |
482 | // go to both regions... (sigh) | ||
483 | // MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId); | ||
484 | return; | ||
485 | } | 585 | } |
486 | else | 586 | |
587 | if (itemId != UUID.Zero) | ||
487 | { | 588 | { |
488 | action(instance); | 589 | IScriptInstance instance = GetInstance(itemId); |
489 | return; | 590 | if (instance == null) |
591 | { | ||
592 | // Commented out for now since this will cause false reports on simulators with more than | ||
593 | // one scene where the current command line set region is 'root' (which causes commands to | ||
594 | // go to both regions... (sigh) | ||
595 | // MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId); | ||
596 | continue; | ||
597 | } | ||
598 | else | ||
599 | { | ||
600 | action(instance); | ||
601 | } | ||
490 | } | 602 | } |
491 | } | 603 | } |
492 | } | 604 | } |
@@ -505,9 +617,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
505 | StringBuilder sb = new StringBuilder(); | 617 | StringBuilder sb = new StringBuilder(); |
506 | sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName); | 618 | sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName); |
507 | 619 | ||
620 | long scriptsLoaded, eventsQueued = 0, eventsProcessed = 0; | ||
621 | |||
508 | lock (m_Scripts) | 622 | lock (m_Scripts) |
509 | sb.AppendFormat("Scripts loaded : {0}\n", m_Scripts.Count); | 623 | { |
624 | scriptsLoaded = m_Scripts.Count; | ||
510 | 625 | ||
626 | foreach (IScriptInstance si in m_Scripts.Values) | ||
627 | { | ||
628 | eventsQueued += si.EventsQueued; | ||
629 | eventsProcessed += si.EventsProcessed; | ||
630 | } | ||
631 | } | ||
632 | |||
633 | sb.AppendFormat("Scripts loaded : {0}\n", scriptsLoaded); | ||
511 | sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); | 634 | sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); |
512 | sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); | 635 | sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); |
513 | sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads); | 636 | sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads); |
@@ -516,6 +639,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
516 | sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads); | 639 | sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads); |
517 | sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks); | 640 | sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks); |
518 | // sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); | 641 | // sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); |
642 | sb.AppendFormat("Events queued : {0}\n", eventsQueued); | ||
643 | sb.AppendFormat("Events processed : {0}\n", eventsProcessed); | ||
519 | 644 | ||
520 | SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this); | 645 | SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this); |
521 | sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0); | 646 | sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0); |
@@ -546,7 +671,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
546 | } | 671 | } |
547 | } | 672 | } |
548 | 673 | ||
549 | HandleScriptsAction(cmdparams, HandleShowScript); | 674 | HandleScriptsAction<long>(cmdparams, HandleShowScript, si => si.EventsProcessed); |
550 | } | 675 | } |
551 | 676 | ||
552 | private void HandleShowScript(IScriptInstance instance) | 677 | private void HandleShowScript(IScriptInstance instance) |
@@ -572,15 +697,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
572 | } | 697 | } |
573 | 698 | ||
574 | StringBuilder sb = new StringBuilder(); | 699 | StringBuilder sb = new StringBuilder(); |
575 | Queue eq = instance.EventQueue; | ||
576 | 700 | ||
577 | sb.AppendFormat("Script name : {0}\n", instance.ScriptName); | 701 | sb.AppendFormat("Script name : {0}\n", instance.ScriptName); |
578 | sb.AppendFormat("Status : {0}\n", status); | 702 | sb.AppendFormat("Status : {0}\n", status); |
579 | 703 | sb.AppendFormat("Queued events : {0}\n", instance.EventsQueued); | |
580 | lock (eq) | 704 | sb.AppendFormat("Processed events : {0}\n", instance.EventsProcessed); |
581 | sb.AppendFormat("Queued events : {0}\n", eq.Count); | ||
582 | |||
583 | sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); | 705 | sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); |
706 | sb.AppendFormat("Asset UUID : {0}\n", instance.AssetID); | ||
584 | sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); | 707 | sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); |
585 | sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID); | 708 | sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID); |
586 | sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition); | 709 | sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition); |
@@ -1079,7 +1202,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1079 | } | 1202 | } |
1080 | 1203 | ||
1081 | m_log.DebugFormat( | 1204 | m_log.DebugFormat( |
1082 | "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 1205 | "[XEngine]: Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", |
1083 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 1206 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, |
1084 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 1207 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
1085 | 1208 | ||
@@ -1089,8 +1212,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1089 | 1212 | ||
1090 | string assembly = ""; | 1213 | string assembly = ""; |
1091 | 1214 | ||
1092 | CultureInfo USCulture = new CultureInfo("en-US"); | 1215 | Culture.SetCurrentCulture(); |
1093 | Thread.CurrentThread.CurrentCulture = USCulture; | ||
1094 | 1216 | ||
1095 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap; | 1217 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap; |
1096 | 1218 | ||
@@ -1101,6 +1223,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1101 | lock (m_AddingAssemblies) | 1223 | lock (m_AddingAssemblies) |
1102 | { | 1224 | { |
1103 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap); | 1225 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap); |
1226 | |||
1104 | if (!m_AddingAssemblies.ContainsKey(assembly)) { | 1227 | if (!m_AddingAssemblies.ContainsKey(assembly)) { |
1105 | m_AddingAssemblies[assembly] = 1; | 1228 | m_AddingAssemblies[assembly] = 1; |
1106 | } else { | 1229 | } else { |
@@ -1150,7 +1273,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1150 | } | 1273 | } |
1151 | catch (Exception e) | 1274 | catch (Exception e) |
1152 | { | 1275 | { |
1153 | // m_log.ErrorFormat("[XEngine]: Exception when rezzing script {0}{1}", e.Message, e.StackTrace); | 1276 | // m_log.ErrorFormat( |
1277 | // "[XEngine]: Exception when rezzing script with item ID {0}, {1}{2}", | ||
1278 | // itemID, e.Message, e.StackTrace); | ||
1154 | 1279 | ||
1155 | // try | 1280 | // try |
1156 | // { | 1281 | // { |
@@ -1229,13 +1354,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1229 | sandbox = AppDomain.CurrentDomain; | 1354 | sandbox = AppDomain.CurrentDomain; |
1230 | } | 1355 | } |
1231 | 1356 | ||
1232 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 1357 | if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) |
1233 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 1358 | return false; |
1234 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1235 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1236 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1237 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1238 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1239 | 1359 | ||
1240 | m_AppDomains[appDomain] = sandbox; | 1360 | m_AppDomains[appDomain] = sandbox; |
1241 | 1361 | ||
@@ -1256,12 +1376,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1256 | m_DomainScripts[appDomain].Add(itemID); | 1376 | m_DomainScripts[appDomain].Add(itemID); |
1257 | 1377 | ||
1258 | instance = new ScriptInstance(this, part, | 1378 | instance = new ScriptInstance(this, part, |
1259 | itemID, assetID, assembly, | 1379 | item, |
1260 | m_AppDomains[appDomain], | 1380 | startParam, postOnRez, |
1261 | part.ParentGroup.RootPart.Name, | 1381 | m_MaxScriptQueue); |
1262 | item.Name, startParam, postOnRez, | ||
1263 | stateSource, m_MaxScriptQueue); | ||
1264 | 1382 | ||
1383 | instance.Load(m_AppDomains[appDomain], assembly, stateSource); | ||
1265 | // m_log.DebugFormat( | 1384 | // m_log.DebugFormat( |
1266 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | 1385 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
1267 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | 1386 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, |
@@ -1347,9 +1466,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1347 | lockScriptsForWrite(false); | 1466 | lockScriptsForWrite(false); |
1348 | instance.ClearQueue(); | 1467 | instance.ClearQueue(); |
1349 | 1468 | ||
1350 | // Give the script some time to finish processing its last event. Simply aborting the script thread can | 1469 | instance.Stop(m_WaitForEventCompletionOnScriptStop); |
1351 | // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort. | ||
1352 | instance.Stop(1000); | ||
1353 | 1470 | ||
1354 | // bool objectRemoved = false; | 1471 | // bool objectRemoved = false; |
1355 | 1472 | ||
@@ -1477,7 +1594,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1477 | m_MaxScriptQueue = maxScriptQueue; | 1594 | m_MaxScriptQueue = maxScriptQueue; |
1478 | 1595 | ||
1479 | STPStartInfo startInfo = new STPStartInfo(); | 1596 | STPStartInfo startInfo = new STPStartInfo(); |
1480 | startInfo.IdleTimeout = idleTimeout*1000; // convert to seconds as stated in .ini | 1597 | startInfo.ThreadPoolName = "XEngine"; |
1598 | startInfo.IdleTimeout = idleTimeout * 1000; // convert to seconds as stated in .ini | ||
1481 | startInfo.MaxWorkerThreads = maxThreads; | 1599 | startInfo.MaxWorkerThreads = maxThreads; |
1482 | startInfo.MinWorkerThreads = minThreads; | 1600 | startInfo.MinWorkerThreads = minThreads; |
1483 | startInfo.ThreadPriority = threadPriority;; | 1601 | startInfo.ThreadPriority = threadPriority;; |
@@ -1504,8 +1622,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1504 | /// <returns></returns> | 1622 | /// <returns></returns> |
1505 | private object ProcessEventHandler(object parms) | 1623 | private object ProcessEventHandler(object parms) |
1506 | { | 1624 | { |
1507 | CultureInfo USCulture = new CultureInfo("en-US"); | 1625 | Culture.SetCurrentCulture(); |
1508 | Thread.CurrentThread.CurrentCulture = USCulture; | ||
1509 | 1626 | ||
1510 | IScriptInstance instance = (ScriptInstance) parms; | 1627 | IScriptInstance instance = (ScriptInstance) parms; |
1511 | 1628 | ||
@@ -1693,7 +1810,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1693 | { | 1810 | { |
1694 | IScriptInstance instance = GetInstance(itemID); | 1811 | IScriptInstance instance = GetInstance(itemID); |
1695 | if (instance != null) | 1812 | if (instance != null) |
1696 | instance.ResetScript(); | 1813 | instance.ResetScript(m_WaitForEventCompletionOnScriptStop); |
1697 | } | 1814 | } |
1698 | 1815 | ||
1699 | public void StartScript(UUID itemID) | 1816 | public void StartScript(UUID itemID) |
@@ -1708,14 +1825,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1708 | public void StopScript(UUID itemID) | 1825 | public void StopScript(UUID itemID) |
1709 | { | 1826 | { |
1710 | IScriptInstance instance = GetInstance(itemID); | 1827 | IScriptInstance instance = GetInstance(itemID); |
1828 | |||
1711 | if (instance != null) | 1829 | if (instance != null) |
1712 | { | 1830 | { |
1713 | // Give the script some time to finish processing its last event. Simply aborting the script thread can | 1831 | instance.Stop(m_WaitForEventCompletionOnScriptStop); |
1714 | // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort. | ||
1715 | instance.Stop(1000); | ||
1716 | } | 1832 | } |
1717 | else | 1833 | else |
1718 | { | 1834 | { |
1835 | // m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name); | ||
1719 | m_runFlags.AddOrUpdate(itemID, false, 240); | 1836 | m_runFlags.AddOrUpdate(itemID, false, 240); |
1720 | } | 1837 | } |
1721 | } | 1838 | } |