aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs43
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs73
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs834
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs79
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs150
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs80
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs52
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs30
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs147
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs84
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs18
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs256
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs513
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs31
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs249
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs270
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs18
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Api/Runtime/XEngineScriptBase.cs61
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/ScriptEngineConsoleCommands.cs126
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs (renamed from OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs)2
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs271
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs6
48 files changed, 2812 insertions, 744 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
28using System; 28using System;
29using System.Threading;
29using OpenMetaverse; 30using OpenMetaverse;
30using OpenSim.Framework; 31using OpenSim.Framework;
31using OpenSim.Region.Framework.Scenes; 32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Region.ScriptEngine.Shared;
32 34
33namespace OpenSim.Region.ScriptEngine.Interfaces 35namespace 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
28using log4net;
29using System; 28using System;
30using OpenSim.Region.ScriptEngine.Shared; 29using System.Reflection;
30using OpenSim.Framework;
31using OpenSim.Region.Framework.Scenes; 31using OpenSim.Region.Framework.Scenes;
32using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim.Region.ScriptEngine.Interfaces; 33using OpenSim.Region.ScriptEngine.Interfaces;
34using OpenSim.Region.ScriptEngine.Shared;
36using Amib.Threading; 35using Amib.Threading;
37using OpenSim.Framework; 36using log4net;
37using Nini.Config;
38using OpenMetaverse;
38 39
39namespace OpenSim.Region.ScriptEngine.Interfaces 40namespace 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..35ae44c 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -28,9 +28,11 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Threading;
31using OpenMetaverse; 32using OpenMetaverse;
32using log4net; 33using log4net;
33using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Framework.Scenes;
34using OpenSim.Region.ScriptEngine.Shared; 36using OpenSim.Region.ScriptEngine.Shared;
35using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
36 38
@@ -50,7 +52,12 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
50 { 52 {
51 bool Cancel(); 53 bool Cancel();
52 void Abort(); 54 void Abort();
53 bool Wait(TimeSpan t); 55
56 /// <summary>
57 /// Wait for the work item to complete.
58 /// </summary>
59 /// <param name='t'>The number of milliseconds to wait. Must be >= -1 (Timeout.Infinite).</param>
60 bool Wait(int t);
54 } 61 }
55 62
56 /// <summary> 63 /// <summary>
@@ -59,6 +66,18 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
59 public interface IScriptInstance 66 public interface IScriptInstance
60 { 67 {
61 /// <summary> 68 /// <summary>
69 /// Debug level for this script instance.
70 /// </summary>
71 /// <remarks>
72 /// Level == 0, no extra data is logged.
73 /// Level >= 1, state changes are logged.
74 /// Level >= 2, event firing is logged.
75 /// <value>
76 /// The debug level.
77 /// </value>
78 int DebugLevel { get; set; }
79
80 /// <summary>
62 /// Is the script currently running? 81 /// Is the script currently running?
63 /// </summary> 82 /// </summary>
64 bool Running { get; set; } 83 bool Running { get; set; }
@@ -93,6 +112,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
93 /// </summary> 112 /// </summary>
94 long MeasurementPeriodExecutionTime { get; } 113 long MeasurementPeriodExecutionTime { get; }
95 114
115 /// <summary>
116 /// Scene part in which this script instance is contained.
117 /// </summary>
118 SceneObjectPart Part { get; }
119
96 IScriptEngine Engine { get; } 120 IScriptEngine Engine { get; }
97 UUID AppDomain { get; set; } 121 UUID AppDomain { get; set; }
98 string PrimName { get; } 122 string PrimName { get; }
@@ -112,8 +136,24 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
112 136
113 uint LocalID { get; } 137 uint LocalID { get; }
114 UUID AssetID { get; } 138 UUID AssetID { get; }
139
140 /// <summary>
141 /// Inventory item containing the script used.
142 /// </summary>
143 TaskInventoryItem ScriptTask { get; }
144
115 Queue EventQueue { get; } 145 Queue EventQueue { get; }
116 146
147 /// <summary>
148 /// Number of events queued for processing.
149 /// </summary>
150 long EventsQueued { get; }
151
152 /// <summary>
153 /// Number of events processed by this script instance.
154 /// </summary>
155 long EventsProcessed { get; }
156
117 void ClearQueue(); 157 void ClearQueue();
118 int StartParam { get; set; } 158 int StartParam { get; set; }
119 159
@@ -125,7 +165,13 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
125 /// <summary> 165 /// <summary>
126 /// Stop the script instance. 166 /// Stop the script instance.
127 /// </summary> 167 /// </summary>
168 /// <remarks>
169 /// This must not be called by a thread that is in the process of handling an event for this script. Otherwise
170 /// there is a danger that it will self-abort and not complete the reset.
171 /// </remarks>
128 /// <param name="timeout"></param> 172 /// <param name="timeout"></param>
173 /// How many milliseconds we will wait for an existing script event to finish before
174 /// forcibly aborting that event.
129 /// <returns>true if the script was successfully stopped, false otherwise</returns> 175 /// <returns>true if the script was successfully stopped, false otherwise</returns>
130 bool Stop(int timeout); 176 bool Stop(int timeout);
131 177
@@ -147,8 +193,31 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
147 object EventProcessor(); 193 object EventProcessor();
148 194
149 int EventTime(); 195 int EventTime();
150 void ResetScript(); 196
197 /// <summary>
198 /// Reset the script.
199 /// </summary>
200 /// <remarks>
201 /// This must not be called by a thread that is in the process of handling an event for this script. Otherwise
202 /// there is a danger that it will self-abort and not complete the reset. Such a thread must call
203 /// ApiResetScript() instead.
204 /// </remarks>
205 /// <param name='timeout'>
206 /// How many milliseconds we will wait for an existing script event to finish before
207 /// forcibly aborting that event prior to script reset.
208 /// </param>
209 void ResetScript(int timeout);
210
211 /// <summary>
212 /// Reset the script.
213 /// </summary>
214 /// <remarks>
215 /// This must not be called by any thread other than the one executing the scripts current event. This is
216 /// because there is no wait or abort logic if another thread is in the middle of processing a script event.
217 /// Such an external thread should use ResetScript() instead.
218 /// </remarks>
151 void ApiResetScript(); 219 void ApiResetScript();
220
152 Dictionary<string, object> GetVars(); 221 Dictionary<string, object> GetVars();
153 void SetVars(Dictionary<string, object> vars); 222 void SetVars(Dictionary<string, object> vars);
154 DetectParams GetDetectParams(int idx); 223 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
28using System; 28using System;
29using System.Threading;
29using System.Reflection; 30using System.Reflection;
30using System.Collections; 31using System.Collections;
31using System.Collections.Generic; 32using 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..bc35272 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -48,6 +48,7 @@ using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization; 49using OpenSim.Region.Framework.Scenes.Serialization;
50using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
51using OpenSim.Region.Framework.Scenes.Scripting;
51using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
52using OpenSim.Region.ScriptEngine.Shared; 53using OpenSim.Region.ScriptEngine.Shared;
53using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 54using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
@@ -70,6 +71,8 @@ using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
71using System.Reflection; 72using System.Reflection;
72using Timer = System.Timers.Timer; 73using Timer = System.Timers.Timer;
74using System.Linq;
75using PermissionMask = OpenSim.Framework.PermissionMask;
73 76
74namespace OpenSim.Region.ScriptEngine.Shared.Api 77namespace OpenSim.Region.ScriptEngine.Shared.Api
75{ 78{
@@ -87,10 +90,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
87 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 90 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
88 { 91 {
89 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 92 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
93
90 protected IScriptEngine m_ScriptEngine; 94 protected IScriptEngine m_ScriptEngine;
91 protected SceneObjectPart m_host; 95 protected SceneObjectPart m_host;
92 96
93 /// <summary> 97 /// <summary>
98 /// Used for script sleeps when we are using co-operative script termination.
99 /// </summary>
100 /// <remarks>null if co-operative script termination is not active</remarks>
101 WaitHandle m_coopSleepHandle;
102
103 /// <summary>
94 /// The item that hosts this script 104 /// The item that hosts this script
95 /// </summary> 105 /// </summary>
96 protected TaskInventoryItem m_item; 106 protected TaskInventoryItem m_item;
@@ -100,6 +110,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
100 protected float m_ScriptDelayFactor = 1.0f; 110 protected float m_ScriptDelayFactor = 1.0f;
101 protected float m_ScriptDistanceFactor = 1.0f; 111 protected float m_ScriptDistanceFactor = 1.0f;
102 protected float m_MinTimerInterval = 0.5f; 112 protected float m_MinTimerInterval = 0.5f;
113 protected float m_recoilScaleFactor = 0.0f;
103 114
104 protected DateTime m_timer = DateTime.Now; 115 protected DateTime m_timer = DateTime.Now;
105 protected bool m_waitingForScriptAnswer = false; 116 protected bool m_waitingForScriptAnswer = false;
@@ -140,34 +151,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
140 {"TURNLEFT", "Turning Left"}, 151 {"TURNLEFT", "Turning Left"},
141 {"TURNRIGHT", "Turning Right"} 152 {"TURNRIGHT", "Turning Right"}
142 }; 153 };
154 //An array of HTTP/1.1 headers that are not allowed to be used
155 //as custom headers by llHTTPRequest.
156 private string[] HttpStandardHeaders =
157 {
158 "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language",
159 "Accept-Ranges", "Age", "Allow", "Authorization", "Cache-Control",
160 "Connection", "Content-Encoding", "Content-Language",
161 "Content-Length", "Content-Location", "Content-MD5",
162 "Content-Range", "Content-Type", "Date", "ETag", "Expect",
163 "Expires", "From", "Host", "If-Match", "If-Modified-Since",
164 "If-None-Match", "If-Range", "If-Unmodified-Since", "Last-Modified",
165 "Location", "Max-Forwards", "Pragma", "Proxy-Authenticate",
166 "Proxy-Authorization", "Range", "Referer", "Retry-After", "Server",
167 "TE", "Trailer", "Transfer-Encoding", "Upgrade", "User-Agent",
168 "Vary", "Via", "Warning", "WWW-Authenticate"
169 };
143 170
144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 171 public void Initialize(
172 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
145 { 173 {
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; 174 m_lastSayShoutCheck = DateTime.UtcNow;
153 175
154 m_ScriptEngine = ScriptEngine; 176 m_ScriptEngine = scriptEngine;
155 m_host = host; 177 m_host = host;
156 m_item = item; 178 m_item = item;
157 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); 179 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
180 m_coopSleepHandle = coopSleepHandle;
158 181
159 LoadLimits(); // read script limits from config. 182 LoadConfig();
160 183
161 m_TransferModule = 184 m_TransferModule =
162 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); 185 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>();
163 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 186 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
164 m_SoundModule = m_ScriptEngine.World.RequestModuleInterface<ISoundModule>(); 187 m_SoundModule = m_ScriptEngine.World.RequestModuleInterface<ISoundModule>();
165 188
166 AsyncCommands = new AsyncCommandManager(ScriptEngine); 189 AsyncCommands = new AsyncCommandManager(m_ScriptEngine);
167 } 190 }
168 191
169 /* load configuration items that affect script, object and run-time behavior. */ 192 /// <summary>
170 private void LoadLimits() 193 /// Load configuration items that affect script, object and run-time behavior. */
194 /// </summary>
195 private void LoadConfig()
171 { 196 {
172 m_ScriptDelayFactor = 197 m_ScriptDelayFactor =
173 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 198 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -181,12 +206,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
181 m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); 206 m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255);
182 if (m_notecardLineReadCharsMax > 65535) 207 if (m_notecardLineReadCharsMax > 65535)
183 m_notecardLineReadCharsMax = 65535; 208 m_notecardLineReadCharsMax = 65535;
209
184 // load limits for particular subsystems. 210 // load limits for particular subsystems.
185 IConfig SMTPConfig; 211 IConfig SMTPConfig;
186 if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) { 212 if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) {
187 // there's an smtp config, so load in the snooze time. 213 // there's an smtp config, so load in the snooze time.
188 EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); 214 EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME);
189 } 215 }
216
217 // Rezzing an object with a velocity can create recoil. This feature seems to have been
218 // removed from recent versions of SL. The code computes recoil (vel*mass) and scales
219 // it by this factor. May be zero to turn off recoil all together.
220 m_recoilScaleFactor = m_ScriptEngine.Config.GetFloat("RecoilScaleFactor", m_recoilScaleFactor);
190 } 221 }
191 222
192 public override Object InitializeLifetimeService() 223 public override Object InitializeLifetimeService()
@@ -207,7 +238,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
207 delay = (int)((float)delay * m_ScriptDelayFactor); 238 delay = (int)((float)delay * m_ScriptDelayFactor);
208 if (delay == 0) 239 if (delay == 0)
209 return; 240 return;
210 System.Threading.Thread.Sleep(delay); 241
242 Sleep(delay);
243 }
244
245 protected virtual void Sleep(int delay)
246 {
247 if (m_coopSleepHandle == null)
248 System.Threading.Thread.Sleep(delay);
249 else
250 CheckForCoopTermination(delay);
251 }
252
253 /// <summary>
254 /// Check for co-operative termination.
255 /// </summary>
256 /// <param name='delay'>If called with 0, then just the check is performed with no wait.</param>
257 protected virtual void CheckForCoopTermination(int delay)
258 {
259 if (m_coopSleepHandle.WaitOne(delay))
260 throw new ScriptCoopStopException();
211 } 261 }
212 262
213 public Scene World 263 public Scene World
@@ -339,6 +389,80 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
339 } 389 }
340 } 390 }
341 391
392 /// <summary>
393 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
394 /// </summary>
395 /// <remarks>
396 /// If there are any ScenePresence's in the linkset (i.e. because they are sat upon one of the prims), then
397 /// these are counted as extra entities that correspond to linknums beyond the number of prims in the linkset.
398 /// The ScenePresences receive linknums in the order in which they sat.
399 /// </remarks>
400 /// <returns>
401 /// The link entity. null if not found.
402 /// </returns>
403 /// <param name='linknum'>
404 /// Can be either a non-negative integer or ScriptBaseClass.LINK_THIS (-4).
405 /// If ScriptBaseClass.LINK_THIS then the entity containing the script is returned.
406 /// If the linkset has one entity and a linknum of zero is given, then the single entity is returned. If any
407 /// positive integer is given in this case then null is returned.
408 /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number
409 /// of entities, then the entity which corresponds to that linknum is returned.
410 /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then
411 /// null is returned.
412 /// </param>
413 public ISceneEntity GetLinkEntity(int linknum)
414 {
415 if (linknum < 0)
416 {
417 if (linknum == ScriptBaseClass.LINK_THIS)
418 return m_host;
419 else
420 return null;
421 }
422
423 int actualPrimCount = m_host.ParentGroup.PrimCount;
424 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
425 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
426
427 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
428 // prim that has any avatars sat upon it (in which case the root prim is link 1).
429 if (linknum == 0)
430 {
431 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
432 return m_host;
433
434 return null;
435 }
436 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
437 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
438 else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1)
439 {
440 if (sittingAvatarIds.Count > 0)
441 return m_host.ParentGroup.RootPart;
442 else
443 return null;
444 }
445 else if (linknum <= adjustedPrimCount)
446 {
447 if (linknum <= actualPrimCount)
448 {
449 return m_host.ParentGroup.GetLinkNumPart(linknum);
450 }
451 else
452 {
453 ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]);
454 if (sp != null)
455 return sp;
456 else
457 return null;
458 }
459 }
460 else
461 {
462 return null;
463 }
464 }
465
342 public List<SceneObjectPart> GetLinkParts(int linkType) 466 public List<SceneObjectPart> GetLinkParts(int linkType)
343 { 467 {
344 return GetLinkParts(m_host, linkType); 468 return GetLinkParts(m_host, linkType);
@@ -392,79 +516,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
392 } 516 }
393 } 517 }
394 518
395 protected UUID InventoryKey(string name, int type)
396 {
397 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
398
399 if (item != null && item.Type == type)
400 return item.AssetID;
401 else
402 return UUID.Zero;
403 }
404
405 /// <summary>
406 /// accepts a valid UUID, -or- a name of an inventory item.
407 /// Returns a valid UUID or UUID.Zero if key invalid and item not found
408 /// in prim inventory.
409 /// </summary>
410 /// <param name="k"></param>
411 /// <returns></returns>
412 protected UUID KeyOrName(string k)
413 {
414 UUID key;
415
416 // if we can parse the string as a key, use it.
417 // else try to locate the name in inventory of object. found returns key,
418 // not found returns UUID.Zero
419 if (!UUID.TryParse(k, out key))
420 {
421 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k);
422
423 if (item != null)
424 key = item.AssetID;
425 else
426 key = UUID.Zero;
427 }
428
429 return key;
430 }
431
432 /// <summary>
433 /// Return the UUID of the asset matching the specified key or name
434 /// and asset type.
435 /// </summary>
436 /// <param name="k"></param>
437 /// <param name="type"></param>
438 /// <returns></returns>
439 protected UUID KeyOrName(string k, AssetType type)
440 {
441 UUID key;
442
443 if (!UUID.TryParse(k, out key))
444 {
445 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k);
446 if (item != null && item.Type == (int)type)
447 key = item.AssetID;
448 }
449 else
450 {
451 lock (m_host.TaskInventory)
452 {
453 foreach (KeyValuePair<UUID, TaskInventoryItem> item in m_host.TaskInventory)
454 {
455 if (item.Value.Type == (int)type && item.Value.Name == k)
456 {
457 key = item.Value.ItemID;
458 break;
459 }
460 }
461 }
462 }
463
464
465 return key;
466 }
467
468 //These are the implementations of the various ll-functions used by the LSL scripts. 519 //These are the implementations of the various ll-functions used by the LSL scripts.
469 public LSL_Float llSin(double f) 520 public LSL_Float llSin(double f)
470 { 521 {
@@ -1483,19 +1534,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1483 return 0; 1534 return 0;
1484 1535
1485 case ScriptBaseClass.STATUS_ROTATE_X: 1536 case ScriptBaseClass.STATUS_ROTATE_X:
1486 if (m_host.GetAxisRotation(2) == 2) 1537 // if (m_host.GetAxisRotation(2) != 0)
1538 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0)
1487 return 1; 1539 return 1;
1488 else 1540 else
1489 return 0; 1541 return 0;
1490 1542
1491 case ScriptBaseClass.STATUS_ROTATE_Y: 1543 case ScriptBaseClass.STATUS_ROTATE_Y:
1492 if (m_host.GetAxisRotation(4) == 4) 1544 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0)
1493 return 1; 1545 return 1;
1494 else 1546 else
1495 return 0; 1547 return 0;
1496 1548
1497 case ScriptBaseClass.STATUS_ROTATE_Z: 1549 case ScriptBaseClass.STATUS_ROTATE_Z:
1498 if (m_host.GetAxisRotation(8) == 8) 1550 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0)
1499 return 1; 1551 return 1;
1500 else 1552 else
1501 return 0; 1553 return 0;
@@ -1715,7 +1767,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 if (tex.FaceTextures[i] != null) 1767 if (tex.FaceTextures[i] != null)
1716 { 1768 {
1717 tex.FaceTextures[i].Shiny = sval; 1769 tex.FaceTextures[i].Shiny = sval;
1718 tex.FaceTextures[i].Bump = bump;; 1770 tex.FaceTextures[i].Bump = bump;
1719 } 1771 }
1720 tex.DefaultTexture.Shiny = sval; 1772 tex.DefaultTexture.Shiny = sval;
1721 tex.DefaultTexture.Bump = bump; 1773 tex.DefaultTexture.Bump = bump;
@@ -1838,7 +1890,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1838 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 1890 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
1839 tex.DefaultTexture.RGBA = texcolor; 1891 tex.DefaultTexture.RGBA = texcolor;
1840 } 1892 }
1841 1893
1842 part.UpdateTextureEntry(tex.GetBytes()); 1894 part.UpdateTextureEntry(tex.GetBytes());
1843 return; 1895 return;
1844 } 1896 }
@@ -1875,10 +1927,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 part.Shape.FlexiForceX = (float)Force.x; 1927 part.Shape.FlexiForceX = (float)Force.x;
1876 part.Shape.FlexiForceY = (float)Force.y; 1928 part.Shape.FlexiForceY = (float)Force.y;
1877 part.Shape.FlexiForceZ = (float)Force.z; 1929 part.Shape.FlexiForceZ = (float)Force.z;
1878 part.Shape.PathCurve = 0x80; 1930 part.Shape.PathCurve = (byte)Extrusion.Flexible;
1879 part.ParentGroup.HasGroupChanged = true;
1880 part.ScheduleFullUpdate();
1881 } 1931 }
1932 else
1933 {
1934 // Other values not set, they do not seem to be sent to the viewer
1935 // Setting PathCurve appears to be what actually toggles the check box and turns Flexi on and off
1936 part.Shape.PathCurve = (byte)Extrusion.Straight;
1937 part.Shape.FlexiEntry = false;
1938 }
1939 part.ParentGroup.HasGroupChanged = true;
1940 part.ScheduleFullUpdate();
1882 } 1941 }
1883 1942
1884 /// <summary> 1943 /// <summary>
@@ -1954,7 +2013,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1954 rgb.x = texcolor.R; 2013 rgb.x = texcolor.R;
1955 rgb.y = texcolor.G; 2014 rgb.y = texcolor.G;
1956 rgb.z = texcolor.B; 2015 rgb.z = texcolor.B;
1957 2016
1958 return rgb; 2017 return rgb;
1959 } 2018 }
1960 else 2019 else
@@ -1996,12 +2055,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1996 2055
1997 UUID textureID = new UUID(); 2056 UUID textureID = new UUID();
1998 2057
1999 textureID = InventoryKey(texture, (int)AssetType.Texture); 2058 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
2000 if (textureID == UUID.Zero) 2059 if (textureID == UUID.Zero)
2001 { 2060 {
2002 if (!UUID.TryParse(texture, out textureID)) 2061 if (!UUID.TryParse(texture, out textureID))
2003 return; 2062 return;
2004 } 2063 }
2005 2064
2006 Primitive.TextureEntry tex = part.Shape.Textures; 2065 Primitive.TextureEntry tex = part.Shape.Textures;
2007 2066
@@ -2207,7 +2266,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2207 // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. 2266 // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND.
2208 // 2267 //
2209 // This workaround is to prevent silent failure of this function. 2268 // This workaround is to prevent silent failure of this function.
2210 // According to the specification on the SL Wiki, providing a position outside of the 2269 // According to the specification on the SL Wiki, providing a position outside of the
2211 if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) 2270 if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize)
2212 { 2271 {
2213 return 0; 2272 return 0;
@@ -2442,7 +2501,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2442 { 2501 {
2443 return llGetRootRotation(); 2502 return llGetRootRotation();
2444 } 2503 }
2445 2504
2446 m_host.AddScriptLPS(1); 2505 m_host.AddScriptLPS(1);
2447 Quaternion q = m_host.GetWorldRotation(); 2506 Quaternion q = m_host.GetWorldRotation();
2448 2507
@@ -2474,14 +2533,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2474 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 2533 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2475 q = avatar.CameraRotation; // Mouselook 2534 q = avatar.CameraRotation; // Mouselook
2476 else 2535 else
2477 q = avatar.Rotation; // Currently infrequently updated so may be inaccurate 2536 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate
2478 } 2537 }
2479 else 2538 else
2480 q = part.ParentGroup.GroupRotation; // Likely never get here but just in case 2539 q = part.ParentGroup.GroupRotation; // Likely never get here but just in case
2481 } 2540 }
2482 else 2541 else
2483 q = part.ParentGroup.GroupRotation; // just the group rotation 2542 q = part.ParentGroup.GroupRotation; // just the group rotation
2484 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2543
2544 return new LSL_Rotation(q);
2485 } 2545 }
2486 2546
2487 q = part.GetWorldRotation(); 2547 q = part.GetWorldRotation();
@@ -2605,8 +2665,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2605 public LSL_Vector llGetTorque() 2665 public LSL_Vector llGetTorque()
2606 { 2666 {
2607 m_host.AddScriptLPS(1); 2667 m_host.AddScriptLPS(1);
2608 Vector3 torque = m_host.ParentGroup.GetTorque(); 2668
2609 return new LSL_Vector(torque.X,torque.Y,torque.Z); 2669 return new LSL_Vector(m_host.ParentGroup.GetTorque());
2610 } 2670 }
2611 2671
2612 public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local) 2672 public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local)
@@ -2639,13 +2699,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2639 vel = m_host.ParentGroup.RootPart.Velocity; 2699 vel = m_host.ParentGroup.RootPart.Velocity;
2640 } 2700 }
2641 2701
2642 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2702 return new LSL_Vector(vel);
2643 } 2703 }
2644 2704
2645 public LSL_Vector llGetAccel() 2705 public LSL_Vector llGetAccel()
2646 { 2706 {
2647 m_host.AddScriptLPS(1); 2707 m_host.AddScriptLPS(1);
2648 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2708
2709 return new LSL_Vector(m_host.Acceleration);
2649 } 2710 }
2650 2711
2651 public void llSetAngularVelocity(LSL_Vector avel, int local) 2712 public void llSetAngularVelocity(LSL_Vector avel, int local)
@@ -2712,7 +2773,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2712 if (m_SoundModule != null) 2773 if (m_SoundModule != null)
2713 { 2774 {
2714 m_SoundModule.SendSound(m_host.UUID, 2775 m_SoundModule.SendSound(m_host.UUID,
2715 KeyOrName(sound, AssetType.Sound), volume, false, 0, 2776 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0,
2716 0, false, false); 2777 0, false, false);
2717 } 2778 }
2718 } 2779 }
@@ -2722,7 +2783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2722 m_host.AddScriptLPS(1); 2783 m_host.AddScriptLPS(1);
2723 if (m_SoundModule != null) 2784 if (m_SoundModule != null)
2724 { 2785 {
2725 m_SoundModule.LoopSound(m_host.UUID, KeyOrName(sound), 2786 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2726 volume, 20, false); 2787 volume, 20, false);
2727 } 2788 }
2728 } 2789 }
@@ -2732,7 +2793,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2732 m_host.AddScriptLPS(1); 2793 m_host.AddScriptLPS(1);
2733 if (m_SoundModule != null) 2794 if (m_SoundModule != null)
2734 { 2795 {
2735 m_SoundModule.LoopSound(m_host.UUID, KeyOrName(sound), 2796 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2736 volume, 20, true); 2797 volume, 20, true);
2737 } 2798 }
2738 } 2799 }
@@ -2754,7 +2815,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2754 if (m_SoundModule != null) 2815 if (m_SoundModule != null)
2755 { 2816 {
2756 m_SoundModule.SendSound(m_host.UUID, 2817 m_SoundModule.SendSound(m_host.UUID,
2757 KeyOrName(sound, AssetType.Sound), volume, false, 0, 2818 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0,
2758 0, true, false); 2819 0, true, false);
2759 } 2820 }
2760 } 2821 }
@@ -2766,7 +2827,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2766 if (m_SoundModule != null) 2827 if (m_SoundModule != null)
2767 { 2828 {
2768 m_SoundModule.SendSound(m_host.UUID, 2829 m_SoundModule.SendSound(m_host.UUID,
2769 KeyOrName(sound, AssetType.Sound), volume, true, 0, 0, 2830 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, true, 0, 0,
2770 false, false); 2831 false, false);
2771 } 2832 }
2772 } 2833 }
@@ -2783,7 +2844,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2783 { 2844 {
2784 m_host.AddScriptLPS(1); 2845 m_host.AddScriptLPS(1);
2785 if (m_SoundModule != null) 2846 if (m_SoundModule != null)
2786 m_SoundModule.PreloadSound(m_host.UUID, KeyOrName(sound), 0); 2847 m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0);
2787 ScriptSleep(1000); 2848 ScriptSleep(1000);
2788 } 2849 }
2789 2850
@@ -3141,11 +3202,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3141 3202
3142 PhysicsActor pa = new_group.RootPart.PhysActor; 3203 PhysicsActor pa = new_group.RootPart.PhysActor;
3143 3204
3205 //Recoil.
3144 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3206 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
3145 { 3207 {
3146 float groupmass = new_group.GetMass(); 3208 float groupmass = new_group.GetMass();
3147 vel *= -groupmass; 3209 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
3148 llApplyImpulse(vel, 0); 3210 if (recoil != Vector3.Zero)
3211 {
3212 llApplyImpulse(recoil, 0);
3213 }
3149 } 3214 }
3150 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3215 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3151 return; 3216 return;
@@ -3220,7 +3285,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3220 { 3285 {
3221// m_log.Info("llSleep snoozing " + sec + "s."); 3286// m_log.Info("llSleep snoozing " + sec + "s.");
3222 m_host.AddScriptLPS(1); 3287 m_host.AddScriptLPS(1);
3223 Thread.Sleep((int)(sec * 1000)); 3288
3289 Sleep((int)(sec * 1000));
3224 } 3290 }
3225 3291
3226 public LSL_Float llGetMass() 3292 public LSL_Float llGetMass()
@@ -3268,7 +3334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3268 3334
3269 if (!UUID.TryParse(id, out objectID)) 3335 if (!UUID.TryParse(id, out objectID))
3270 objectID = UUID.Zero; 3336 objectID = UUID.Zero;
3271 3337
3272 if (objectID == UUID.Zero && name == "") 3338 if (objectID == UUID.Zero && name == "")
3273 return; 3339 return;
3274 3340
@@ -3322,7 +3388,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3322 /// <summary> 3388 /// <summary>
3323 /// Attach the object containing this script to the avatar that owns it. 3389 /// Attach the object containing this script to the avatar that owns it.
3324 /// </summary> 3390 /// </summary>
3325 /// <param name='attachment'>The attachment point (e.g. ATTACH_CHEST)</param> 3391 /// <param name='attachmentPoint'>
3392 /// The attachment point (e.g. <see cref="OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass.ATTACH_CHEST">ATTACH_CHEST</see>)
3393 /// </param>
3326 /// <returns>true if the attach suceeded, false if it did not</returns> 3394 /// <returns>true if the attach suceeded, false if it did not</returns>
3327 public bool AttachToAvatar(int attachmentPoint) 3395 public bool AttachToAvatar(int attachmentPoint)
3328 { 3396 {
@@ -3332,7 +3400,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3332 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3400 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3333 3401
3334 if (attachmentsModule != null) 3402 if (attachmentsModule != null)
3335 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false); 3403 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3336 else 3404 else
3337 return false; 3405 return false;
3338 } 3406 }
@@ -3473,20 +3541,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3473 msg.offline = (byte)0; //offline; 3541 msg.offline = (byte)0; //offline;
3474 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID; 3542 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3475 msg.Position = new Vector3(m_host.AbsolutePosition); 3543 msg.Position = new Vector3(m_host.AbsolutePosition);
3476 msg.RegionID = World.RegionInfo.RegionID.Guid; 3544 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3477 msg.binaryBucket 3545
3546 Vector3 pos = m_host.AbsolutePosition;
3547 msg.binaryBucket
3478 = Util.StringToBytes256( 3548 = Util.StringToBytes256(
3479 "{0}/{1}/{2}/{3}", 3549 "{0}/{1}/{2}/{3}",
3480 World.RegionInfo.RegionName, 3550 World.RegionInfo.RegionName,
3481 (int)Math.Floor(m_host.AbsolutePosition.X), 3551 (int)Math.Floor(pos.X),
3482 (int)Math.Floor(m_host.AbsolutePosition.Y), 3552 (int)Math.Floor(pos.Y),
3483 (int)Math.Floor(m_host.AbsolutePosition.Z)); 3553 (int)Math.Floor(pos.Z));
3484 3554
3485 if (m_TransferModule != null) 3555 if (m_TransferModule != null)
3486 { 3556 {
3487 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 3557 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
3488 } 3558 }
3489 3559
3490 ScriptSleep(2000); 3560 ScriptSleep(2000);
3491 } 3561 }
3492 3562
@@ -3611,7 +3681,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3611 public void llRotLookAt(LSL_Rotation target, double strength, double damping) 3681 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3612 { 3682 {
3613 m_host.AddScriptLPS(1); 3683 m_host.AddScriptLPS(1);
3614 3684
3615 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3685 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3616 // set the rotation of the object, copy that behavior 3686 // set the rotation of the object, copy that behavior
3617 PhysicsActor pa = m_host.PhysActor; 3687 PhysicsActor pa = m_host.PhysActor;
@@ -3653,7 +3723,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3653 if (presence != null) 3723 if (presence != null)
3654 { 3724 {
3655 // Do NOT try to parse UUID, animations cannot be triggered by ID 3725 // Do NOT try to parse UUID, animations cannot be triggered by ID
3656 UUID animID = InventoryKey(anim, (int)AssetType.Animation); 3726 UUID animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation);
3657 if (animID == UUID.Zero) 3727 if (animID == UUID.Zero)
3658 presence.Animator.AddAnimation(anim, m_host.UUID); 3728 presence.Animator.AddAnimation(anim, m_host.UUID);
3659 else 3729 else
@@ -3675,12 +3745,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3675 3745
3676 if (presence != null) 3746 if (presence != null)
3677 { 3747 {
3678 UUID animID = KeyOrName(anim); 3748 UUID animID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, anim);
3679 3749
3680 if (animID == UUID.Zero) 3750 if (animID == UUID.Zero)
3681 presence.Animator.RemoveAnimation(anim); 3751 presence.Animator.RemoveAnimation(anim);
3682 else 3752 else
3683 presence.Animator.RemoveAnimation(animID); 3753 presence.Animator.RemoveAnimation(animID, true);
3684 } 3754 }
3685 } 3755 }
3686 } 3756 }
@@ -3753,21 +3823,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3753 } 3823 }
3754 else 3824 else
3755 { 3825 {
3756 bool sitting = false; 3826 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 { 3827 {
3772 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3828 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3773 implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3829 implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
@@ -3809,7 +3865,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3809 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3865 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
3810 if (npcModule != null && npcModule.IsNPC(agentID, World)) 3866 if (npcModule != null && npcModule.IsNPC(agentID, World))
3811 { 3867 {
3812 if (agentID == m_host.ParentGroup.OwnerID || npcModule.GetOwner(agentID) == m_host.ParentGroup.OwnerID) 3868 if (npcModule.CheckPermissions(agentID, m_host.OwnerID))
3813 { 3869 {
3814 lock (m_host.TaskInventory) 3870 lock (m_host.TaskInventory)
3815 { 3871 {
@@ -4184,62 +4240,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4184 public LSL_String llGetLinkName(int linknum) 4240 public LSL_String llGetLinkName(int linknum)
4185 { 4241 {
4186 m_host.AddScriptLPS(1); 4242 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
4191 // parse for sitting avatare-names
4192 List<String> nametable = new List<String>();
4193 World.ForEachRootScenePresence(delegate(ScenePresence presence)
4194 {
4195 SceneObjectPart sitPart = presence.ParentPart;
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;
4209 // LinkNumber > of Real PrimSet = AvatarName
4210 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
4211 return nametable[totalprims - linknum];
4212 }
4213 4243
4214 // Single prim 4244 ISceneEntity entity = GetLinkEntity(linknum);
4215 if (m_host.LinkNum == 0)
4216 {
4217 if (linknum == 0 || linknum == ScriptBaseClass.LINK_ROOT)
4218 return m_host.Name;
4219 else
4220 return UUID.Zero.ToString();
4221 }
4222 4245
4223 // Link set 4246 if (entity != null)
4224 SceneObjectPart part = null; 4247 return entity.Name;
4225 if (m_host.LinkNum == 1) // this is the Root prim
4226 {
4227 if (linknum < 0)
4228 part = m_host.ParentGroup.GetLinkNumPart(2);
4229 else
4230 part = m_host.ParentGroup.GetLinkNumPart(linknum);
4231 }
4232 else // this is a child prim
4233 {
4234 if (linknum < 2)
4235 part = m_host.ParentGroup.GetLinkNumPart(1);
4236 else
4237 part = m_host.ParentGroup.GetLinkNumPart(linknum);
4238 }
4239 if (part != null)
4240 return part.Name;
4241 else 4248 else
4242 return UUID.Zero.ToString(); 4249 return ScriptBaseClass.NULL_KEY;
4243 } 4250 }
4244 4251
4245 public LSL_Integer llGetInventoryNumber(int type) 4252 public LSL_Integer llGetInventoryNumber(int type)
@@ -4604,8 +4611,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4604 if (presence.UserLevel >= 200) return; 4611 if (presence.UserLevel >= 200) return;
4605 4612
4606 // agent must be over the owners land 4613 // agent must be over the owners land
4607 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4614 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4608 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4609 { 4615 {
4610 if (!World.TeleportClientHome(agentId, presence.ControllingClient)) 4616 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4611 { 4617 {
@@ -4621,6 +4627,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4621 } 4627 }
4622 } 4628 }
4623 } 4629 }
4630
4624 ScriptSleep(5000); 4631 ScriptSleep(5000);
4625 } 4632 }
4626 4633
@@ -4641,8 +4648,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4641 destination = World.RegionInfo.RegionName; 4648 destination = World.RegionInfo.RegionName;
4642 4649
4643 // agent must be over the owners land 4650 // agent must be over the owners land
4644 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4651 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4645 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4646 { 4652 {
4647 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4653 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4648 } 4654 }
@@ -4673,8 +4679,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4673 if (presence.GodLevel >= 200) return; 4679 if (presence.GodLevel >= 200) return;
4674 4680
4675 // agent must be over the owners land 4681 // agent must be over the owners land
4676 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4682 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4677 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4678 { 4683 {
4679 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4684 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4680 } 4685 }
@@ -4691,7 +4696,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4691 4696
4692 private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt) 4697 private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt)
4693 { 4698 {
4694 UUID assetID = KeyOrName(destination); 4699 UUID assetID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, destination);
4695 4700
4696 // The destinaion is not an asset ID and also doesn't name a landmark. 4701 // The destinaion is not an asset ID and also doesn't name a landmark.
4697 // Use it as a sim name 4702 // Use it as a sim name
@@ -4724,7 +4729,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4724 UUID av = new UUID(); 4729 UUID av = new UUID();
4725 if (!UUID.TryParse(agent,out av)) 4730 if (!UUID.TryParse(agent,out av))
4726 { 4731 {
4727 //LSLError("First parameter to llDialog needs to be a key");
4728 return; 4732 return;
4729 } 4733 }
4730 4734
@@ -4765,7 +4769,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4765 return; 4769 return;
4766 } 4770 }
4767 // TODO: Parameter check logic required. 4771 // TODO: Parameter check logic required.
4768 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4772 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4769 m_host.CollisionSoundVolume = (float)impact_volume; 4773 m_host.CollisionSoundVolume = (float)impact_volume;
4770 m_host.CollisionSoundType = 1; 4774 m_host.CollisionSoundType = 1;
4771 } 4775 }
@@ -4890,7 +4894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4890 { 4894 {
4891 if (pushrestricted) 4895 if (pushrestricted)
4892 { 4896 {
4893 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); 4897 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4894 4898
4895 // We didn't find the parcel but region is push restricted so assume it is NOT ok 4899 // We didn't find the parcel but region is push restricted so assume it is NOT ok
4896 if (targetlandObj == null) 4900 if (targetlandObj == null)
@@ -4905,7 +4909,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4905 } 4909 }
4906 else 4910 else
4907 { 4911 {
4908 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); 4912 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4909 if (targetlandObj == null) 4913 if (targetlandObj == null)
4910 { 4914 {
4911 // We didn't find the parcel but region isn't push restricted so assume it's ok 4915 // We didn't find the parcel but region isn't push restricted so assume it's ok
@@ -4935,6 +4939,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4935 } 4939 }
4936 } 4940 }
4937 } 4941 }
4942
4938 if (pushAllowed) 4943 if (pushAllowed)
4939 { 4944 {
4940 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4945 float distance = (PusheePos - m_host.AbsolutePosition).Length();
@@ -4964,17 +4969,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4964 applied_linear_impulse *= scaling_factor; 4969 applied_linear_impulse *= scaling_factor;
4965 4970
4966 } 4971 }
4972
4967 if (pusheeIsAvatar) 4973 if (pusheeIsAvatar)
4968 { 4974 {
4969 if (pusheeav != null) 4975 if (pusheeav != null)
4970 { 4976 {
4971 if (pusheeav.PhysicsActor != null) 4977 PhysicsActor pa = pusheeav.PhysicsActor;
4978
4979 if (pa != null)
4972 { 4980 {
4973 if (local != 0) 4981 if (local != 0)
4974 { 4982 {
4975 applied_linear_impulse *= m_host.GetWorldRotation(); 4983 applied_linear_impulse *= m_host.GetWorldRotation();
4976 } 4984 }
4977 pusheeav.PhysicsActor.AddForce(applied_linear_impulse, true); 4985
4986 pa.AddForce(applied_linear_impulse, true);
4978 } 4987 }
4979 } 4988 }
4980 } 4989 }
@@ -5324,8 +5333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5324 public LSL_Vector llGetCenterOfMass() 5333 public LSL_Vector llGetCenterOfMass()
5325 { 5334 {
5326 m_host.AddScriptLPS(1); 5335 m_host.AddScriptLPS(1);
5327 Vector3 center = m_host.GetCenterOfMass(); 5336
5328 return new LSL_Vector(center.X,center.Y,center.Z); 5337 return new LSL_Vector(m_host.GetCenterOfMass());
5329 } 5338 }
5330 5339
5331 public LSL_List llListSort(LSL_List src, int stride, int ascending) 5340 public LSL_List llListSort(LSL_List src, int stride, int ascending)
@@ -5466,7 +5475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5466 // SL spits out an empty string for types other than key & string 5475 // SL spits out an empty string for types other than key & string
5467 // At the time of patching, LSL_Key is currently LSL_String, 5476 // At the time of patching, LSL_Key is currently LSL_String,
5468 // so the OR check may be a little redundant, but it's being done 5477 // so the OR check may be a little redundant, but it's being done
5469 // for completion and should LSL_Key ever be implemented 5478 // for completion and should LSL_Key ever be implemented
5470 // as it's own struct 5479 // as it's own struct
5471 else if (!(src.Data[index] is LSL_String || 5480 else if (!(src.Data[index] is LSL_String ||
5472 src.Data[index] is LSL_Key || 5481 src.Data[index] is LSL_Key ||
@@ -5603,8 +5612,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5603 { 5612 {
5604 m_host.AddScriptLPS(1); 5613 m_host.AddScriptLPS(1);
5605 5614
5606 return string.Join(", ", 5615 return string.Join(", ",
5607 (new List<object>(src.Data)).ConvertAll<string>(o => 5616 (new List<object>(src.Data)).ConvertAll<string>(o =>
5608 { 5617 {
5609 return o.ToString(); 5618 return o.ToString();
5610 }).ToArray()); 5619 }).ToArray());
@@ -5852,9 +5861,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5852 } 5861 }
5853 5862
5854 /// <summary> 5863 /// <summary>
5855 /// Insert the list identified by <src> into the 5864 /// Insert the list identified by <paramref name="src"/> into the
5856 /// list designated by <dest> such that the first 5865 /// list designated by <paramref name="dest"/> such that the first
5857 /// new element has the index specified by <index> 5866 /// new element has the index specified by <paramref name="index"/>
5858 /// </summary> 5867 /// </summary>
5859 5868
5860 public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index) 5869 public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index)
@@ -6182,12 +6191,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6182 } 6191 }
6183 6192
6184 ILandObject land; 6193 ILandObject land;
6185 Vector3 pos;
6186 UUID id = UUID.Zero; 6194 UUID id = UUID.Zero;
6195
6187 if (parcel || parcelOwned) 6196 if (parcel || parcelOwned)
6188 { 6197 {
6189 pos = m_host.ParentGroup.RootPart.GetWorldPosition(); 6198 land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition());
6190 land = World.LandChannel.GetLandObject(pos.X, pos.Y);
6191 if (land == null) 6199 if (land == null)
6192 { 6200 {
6193 id = UUID.Zero; 6201 id = UUID.Zero;
@@ -6213,20 +6221,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6213 { 6221 {
6214 if (!regionWide) 6222 if (!regionWide)
6215 { 6223 {
6216 pos = ssp.AbsolutePosition; 6224 land = World.LandChannel.GetLandObject(ssp.AbsolutePosition);
6217 land = World.LandChannel.GetLandObject(pos.X, pos.Y);
6218 if (land != null) 6225 if (land != null)
6219 { 6226 {
6220 if (parcelOwned && land.LandData.OwnerID == id || 6227 if (parcelOwned && land.LandData.OwnerID == id ||
6221 parcel && land.LandData.GlobalID == id) 6228 parcel && land.LandData.GlobalID == id)
6222 { 6229 {
6223 result.Add(ssp.UUID.ToString()); 6230 result.Add(new LSL_Key(ssp.UUID.ToString()));
6224 } 6231 }
6225 } 6232 }
6226 } 6233 }
6227 else 6234 else
6228 { 6235 {
6229 result.Add(ssp.UUID.ToString()); 6236 result.Add(new LSL_Key(ssp.UUID.ToString()));
6230 } 6237 }
6231 } 6238 }
6232 // Maximum of 100 results 6239 // Maximum of 100 results
@@ -6330,7 +6337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6330 if (m_SoundModule != null) 6337 if (m_SoundModule != null)
6331 { 6338 {
6332 m_SoundModule.TriggerSoundLimited(m_host.UUID, 6339 m_SoundModule.TriggerSoundLimited(m_host.UUID,
6333 KeyOrName(sound, AssetType.Sound), volume, 6340 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume,
6334 bottom_south_west, top_north_east); 6341 bottom_south_west, top_north_east);
6335 } 6342 }
6336 } 6343 }
@@ -6345,14 +6352,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6345 if (presence != null) 6352 if (presence != null)
6346 { 6353 {
6347 // agent must be over the owners land 6354 // agent must be over the owners land
6348 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); 6355 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition);
6349 if (land == null) 6356 if (land == null)
6350 return; 6357 return;
6351 6358
6352 if (m_host.OwnerID == land.LandData.OwnerID) 6359 if (m_host.OwnerID == land.LandData.OwnerID)
6353 { 6360 {
6354 Vector3 pos = World.GetNearestAllowedPosition(presence, land); 6361 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6355 presence.TeleportWithMomentum(pos, null); 6362 presence.TeleportWithMomentum(p, null);
6356 presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); 6363 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
6357 } 6364 }
6358 } 6365 }
@@ -6374,19 +6381,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6374 ScenePresence presence = World.GetScenePresence(key); 6381 ScenePresence presence = World.GetScenePresence(key);
6375 if (presence != null) // object is an avatar 6382 if (presence != null) // object is an avatar
6376 { 6383 {
6377 if (m_host.OwnerID 6384 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
6378 == World.LandChannel.GetLandObject(
6379 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
6380 return 1; 6385 return 1;
6381 } 6386 }
6382 else // object is not an avatar 6387 else // object is not an avatar
6383 { 6388 {
6384 SceneObjectPart obj = World.GetSceneObjectPart(key); 6389 SceneObjectPart obj = World.GetSceneObjectPart(key);
6390
6385 if (obj != null) 6391 if (obj != null)
6386 if (m_host.OwnerID 6392 {
6387 == World.LandChannel.GetLandObject( 6393 if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID)
6388 obj.AbsolutePosition.X, obj.AbsolutePosition.Y).LandData.OwnerID)
6389 return 1; 6394 return 1;
6395 }
6390 } 6396 }
6391 } 6397 }
6392 6398
@@ -6494,8 +6500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6494 // if the land is group owned and the object is group owned by the same group 6500 // if the land is group owned and the object is group owned by the same group
6495 // or 6501 // or
6496 // if the object is owned by a person with estate access. 6502 // if the object is owned by a person with estate access.
6497 6503 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition);
6498 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y);
6499 if (parcel != null) 6504 if (parcel != null)
6500 { 6505 {
6501 if (m_host.OwnerID == parcel.LandData.OwnerID || 6506 if (m_host.OwnerID == parcel.LandData.OwnerID ||
@@ -6507,14 +6512,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6507 } 6512 }
6508 } 6513 }
6509 } 6514 }
6510
6511 } 6515 }
6512
6513 } 6516 }
6514 6517
6515 public LSL_Vector llGroundSlope(LSL_Vector offset) 6518 public LSL_Vector llGroundSlope(LSL_Vector offset)
6516 { 6519 {
6517 m_host.AddScriptLPS(1); 6520 m_host.AddScriptLPS(1);
6521
6518 //Get the slope normal. This gives us the equation of the plane tangent to the slope. 6522 //Get the slope normal. This gives us the equation of the plane tangent to the slope.
6519 LSL_Vector vsn = llGroundNormal(offset); 6523 LSL_Vector vsn = llGroundNormal(offset);
6520 6524
@@ -6525,7 +6529,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6525 vsl.Normalize(); 6529 vsl.Normalize();
6526 //Normalization might be overkill here 6530 //Normalization might be overkill here
6527 6531
6528 return new LSL_Vector(vsl.X, vsl.Y, vsl.Z); 6532 vsn.x = vsl.X;
6533 vsn.y = vsl.Y;
6534 vsn.z = vsl.Z;
6535
6536 return vsn;
6529 } 6537 }
6530 6538
6531 public LSL_Vector llGroundNormal(LSL_Vector offset) 6539 public LSL_Vector llGroundNormal(LSL_Vector offset)
@@ -6575,7 +6583,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6575 //I believe the crossproduct of two normalized vectors is a normalized vector so 6583 //I believe the crossproduct of two normalized vectors is a normalized vector so
6576 //this normalization may be overkill 6584 //this normalization may be overkill
6577 6585
6578 return new LSL_Vector(vsn.X, vsn.Y, vsn.Z); 6586 return new LSL_Vector(vsn);
6579 } 6587 }
6580 6588
6581 public LSL_Vector llGroundContour(LSL_Vector offset) 6589 public LSL_Vector llGroundContour(LSL_Vector offset)
@@ -6687,6 +6695,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6687 ps.BurstSpeedMax = 1.0f; 6695 ps.BurstSpeedMax = 1.0f;
6688 ps.BurstRate = 0.1f; 6696 ps.BurstRate = 0.1f;
6689 ps.PartMaxAge = 10.0f; 6697 ps.PartMaxAge = 10.0f;
6698 ps.BurstPartCount = 1;
6690 return ps; 6699 return ps;
6691 } 6700 }
6692 6701
@@ -6710,8 +6719,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6710 6719
6711 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) 6720 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6712 { 6721 {
6713
6714
6715 if (rules.Length == 0) 6722 if (rules.Length == 0)
6716 { 6723 {
6717 part.RemoveParticleSystem(); 6724 part.RemoveParticleSystem();
@@ -6802,7 +6809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6802 break; 6809 break;
6803 6810
6804 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE: 6811 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE:
6805 prules.Texture = KeyOrName(rules.GetLSLStringItem(i + 1)); 6812 prules.Texture = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, rules.GetLSLStringItem(i + 1));
6806 break; 6813 break;
6807 6814
6808 case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE: 6815 case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE:
@@ -6947,7 +6954,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6947 m_host.OwnerID, m_host.Name, destID, 6954 m_host.OwnerID, m_host.Name, destID,
6948 (byte)InstantMessageDialog.TaskInventoryOffered, 6955 (byte)InstantMessageDialog.TaskInventoryOffered,
6949 false, string.Format("'{0}'", category), 6956 false, string.Format("'{0}'", category),
6950// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 6957// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06
6951// false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z), 6958// false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z),
6952 folderID, false, pos, 6959 folderID, false, pos,
6953 bucket, false); 6960 bucket, false);
@@ -7066,12 +7073,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7066 public LSL_String llAvatarOnLinkSitTarget(int linknum) 7073 public LSL_String llAvatarOnLinkSitTarget(int linknum)
7067 { 7074 {
7068 m_host.AddScriptLPS(1); 7075 m_host.AddScriptLPS(1);
7069 if(linknum == ScriptBaseClass.LINK_SET || 7076 if(linknum == ScriptBaseClass.LINK_SET ||
7070 linknum == ScriptBaseClass.LINK_ALL_CHILDREN || 7077 linknum == ScriptBaseClass.LINK_ALL_CHILDREN ||
7071 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); 7078 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString();
7072 7079
7073 List<SceneObjectPart> parts = GetLinkParts(linknum); 7080 List<SceneObjectPart> parts = GetLinkParts(linknum);
7074 if (parts.Count == 0) return UUID.Zero.ToString(); 7081 if (parts.Count == 0) return UUID.Zero.ToString();
7075 return parts[0].SitTargetAvatar.ToString(); 7082 return parts[0].SitTargetAvatar.ToString();
7076 } 7083 }
7077 7084
@@ -7080,7 +7087,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7080 { 7087 {
7081 m_host.AddScriptLPS(1); 7088 m_host.AddScriptLPS(1);
7082 UUID key; 7089 UUID key;
7083 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 7090 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
7091
7084 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 7092 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
7085 { 7093 {
7086 int expires = 0; 7094 int expires = 0;
@@ -7222,20 +7230,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7222 } 7230 }
7223 if (buttons.Length > 12) 7231 if (buttons.Length > 12)
7224 { 7232 {
7225 LSLError("No more than 12 buttons can be shown"); 7233 ShoutError("button list too long, must be 12 or fewer entries");
7226 return;
7227 } 7234 }
7228 string[] buts = new string[buttons.Length]; 7235 int length = buttons.Length;
7229 for (int i = 0; i < buttons.Length; i++) 7236 if (length > 12)
7237 length = 12;
7238
7239 string[] buts = new string[length];
7240 for (int i = 0; i < length; i++)
7230 { 7241 {
7231 if (buttons.Data[i].ToString() == String.Empty) 7242 if (buttons.Data[i].ToString() == String.Empty)
7232 { 7243 {
7233 LSLError("button label cannot be blank"); 7244 ShoutError("button label cannot be blank");
7234 return; 7245 return;
7235 } 7246 }
7236 if (buttons.Data[i].ToString().Length > 24) 7247 if (buttons.Data[i].ToString().Length > 24)
7237 { 7248 {
7238 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters"); 7249 ShoutError("button label cannot be longer than 24 characters");
7239 return; 7250 return;
7240 } 7251 }
7241 buts[i] = buttons.Data[i].ToString(); 7252 buts[i] = buttons.Data[i].ToString();
@@ -7371,6 +7382,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7371 public void llCloseRemoteDataChannel(string channel) 7382 public void llCloseRemoteDataChannel(string channel)
7372 { 7383 {
7373 m_host.AddScriptLPS(1); 7384 m_host.AddScriptLPS(1);
7385
7386 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>();
7387 if (xmlRpcRouter != null)
7388 {
7389 xmlRpcRouter.UnRegisterReceiver(channel, m_item.ItemID);
7390 }
7391
7374 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 7392 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
7375 if (xmlrpcMod != null) 7393 if (xmlrpcMod != null)
7376 xmlrpcMod.CloseXMLRPCChannel((UUID)channel); 7394 xmlrpcMod.CloseXMLRPCChannel((UUID)channel);
@@ -7450,7 +7468,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7450 hollow = 0.70f; 7468 hollow = 0.70f;
7451 } 7469 }
7452 } 7470 }
7453 // Otherwise, hollow is limited to 95%. 7471 // Otherwise, hollow is limited to 95%.
7454 else 7472 else
7455 { 7473 {
7456 if (hollow > 0.95f) 7474 if (hollow > 0.95f)
@@ -7744,9 +7762,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7744 UUID sculptId; 7762 UUID sculptId;
7745 7763
7746 if (!UUID.TryParse(map, out sculptId)) 7764 if (!UUID.TryParse(map, out sculptId))
7747 { 7765 sculptId = ScriptUtils.GetAssetIdFromItemName(m_host, map, (int)AssetType.Texture);
7748 sculptId = InventoryKey(map, (int)AssetType.Texture);
7749 }
7750 7766
7751 if (sculptId == UUID.Zero) 7767 if (sculptId == UUID.Zero)
7752 return; 7768 return;
@@ -7843,7 +7859,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7843 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType; 7859 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7844 physdata.Density = part.Density; 7860 physdata.Density = part.Density;
7845 physdata.Friction = part.Friction; 7861 physdata.Friction = part.Friction;
7846 physdata.Bounce = part.Bounciness; 7862 physdata.Bounce = part.Restitution;
7847 physdata.GravitationModifier = part.GravityModifier; 7863 physdata.GravitationModifier = part.GravityModifier;
7848 7864
7849 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0) 7865 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
@@ -8236,7 +8252,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8236 8252
8237 ExtraPhysicsData physdata = new ExtraPhysicsData(); 8253 ExtraPhysicsData physdata = new ExtraPhysicsData();
8238 physdata.Density = part.Density; 8254 physdata.Density = part.Density;
8239 physdata.Bounce = part.Bounciness; 8255 physdata.Bounce = part.Restitution;
8240 physdata.GravitationModifier = part.GravityModifier; 8256 physdata.GravitationModifier = part.GravityModifier;
8241 physdata.PhysShapeType = (PhysShapeType)shape_type; 8257 physdata.PhysShapeType = (PhysShapeType)shape_type;
8242 8258
@@ -8509,7 +8525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8509 { 8525 {
8510 m_host.AddScriptLPS(1); 8526 m_host.AddScriptLPS(1);
8511 8527
8512 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 8528 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8513 8529
8514 if (land.LandData.OwnerID != m_host.OwnerID) 8530 if (land.LandData.OwnerID != m_host.OwnerID)
8515 return; 8531 return;
@@ -8523,7 +8539,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8523 { 8539 {
8524 m_host.AddScriptLPS(1); 8540 m_host.AddScriptLPS(1);
8525 8541
8526 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 8542 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8527 8543
8528 if (land.LandData.OwnerID != m_host.OwnerID) 8544 if (land.LandData.OwnerID != m_host.OwnerID)
8529 return String.Empty; 8545 return String.Empty;
@@ -8534,8 +8550,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8534 public LSL_Vector llGetRootPosition() 8550 public LSL_Vector llGetRootPosition()
8535 { 8551 {
8536 m_host.AddScriptLPS(1); 8552 m_host.AddScriptLPS(1);
8537 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition.X, m_host.ParentGroup.AbsolutePosition.Y, 8553
8538 m_host.ParentGroup.AbsolutePosition.Z); 8554 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8539 } 8555 }
8540 8556
8541 /// <summary> 8557 /// <summary>
@@ -8558,13 +8574,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8558 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 8574 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
8559 q = avatar.CameraRotation; // Mouselook 8575 q = avatar.CameraRotation; // Mouselook
8560 else 8576 else
8561 q = avatar.Rotation; // Currently infrequently updated so may be inaccurate 8577 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate
8562 else 8578 else
8563 q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case 8579 q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case
8564 } 8580 }
8565 else 8581 else
8566 q = m_host.ParentGroup.GroupRotation; // just the group rotation 8582 q = m_host.ParentGroup.GroupRotation; // just the group rotation
8567 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 8583
8584 return new LSL_Rotation(q);
8568 } 8585 }
8569 8586
8570 public LSL_String llGetObjectDesc() 8587 public LSL_String llGetObjectDesc()
@@ -8731,8 +8748,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8731 8748
8732 public LSL_Vector llGetGeometricCenter() 8749 public LSL_Vector llGetGeometricCenter()
8733 { 8750 {
8734 Vector3 tmp = m_host.GetGeometricCenter(); 8751 return new LSL_Vector(m_host.GetGeometricCenter());
8735 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
8736 } 8752 }
8737 8753
8738 public LSL_List llGetPrimitiveParams(LSL_List rules) 8754 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -8839,9 +8855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8839 break; 8855 break;
8840 8856
8841 case (int)ScriptBaseClass.PRIM_SIZE: 8857 case (int)ScriptBaseClass.PRIM_SIZE:
8842 res.Add(new LSL_Vector(part.Scale.X, 8858 res.Add(new LSL_Vector(part.Scale));
8843 part.Scale.Y,
8844 part.Scale.Z));
8845 break; 8859 break;
8846 8860
8847 case (int)ScriptBaseClass.PRIM_ROTATION: 8861 case (int)ScriptBaseClass.PRIM_ROTATION:
@@ -8909,16 +8923,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8909 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); 8923 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
8910 8924
8911 // float revolutions 8925 // float revolutions
8912 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); 8926 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d);
8913 // Slightly inaccurate, because an unsigned byte is being used to represent 8927 // Slightly inaccurate, because an unsigned byte is being used to represent
8914 // the entire range of floating-point values from 1.0 through 4.0 (which is how 8928 // the entire range of floating-point values from 1.0 through 4.0 (which is how
8915 // SL does it). 8929 // SL does it).
8916 // 8930 //
8917 // Using these formulas to store and retrieve PathRevolutions, it is not 8931 // Using these formulas to store and retrieve PathRevolutions, it is not
8918 // possible to use all values between 1.00 and 4.00. For instance, you can't 8932 // possible to use all values between 1.00 and 4.00. For instance, you can't
8919 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you 8933 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you
8920 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them 8934 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them
8921 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar 8935 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar
8922 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. 8936 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11.
8923 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value 8937 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
8924 // such as 1.10. So, SL must store and retreive the actual user input rather 8938 // such as 1.10. So, SL must store and retreive the actual user input rather
@@ -9202,9 +9216,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9202 case (int)ScriptBaseClass.PRIM_DESC: 9216 case (int)ScriptBaseClass.PRIM_DESC:
9203 res.Add(new LSL_String(part.Description)); 9217 res.Add(new LSL_String(part.Description));
9204 break; 9218 break;
9205
9206 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9219 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9207 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9220 res.Add(new LSL_Rotation(part.RotationOffset));
9208 break; 9221 break;
9209 9222
9210 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9223 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
@@ -10236,6 +10249,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10236 return UUID.Zero.ToString(); 10249 return UUID.Zero.ToString();
10237 } 10250 }
10238 } 10251 }
10252
10239 public LSL_String llRequestURL() 10253 public LSL_String llRequestURL()
10240 { 10254 {
10241 m_host.AddScriptLPS(1); 10255 m_host.AddScriptLPS(1);
@@ -10387,7 +10401,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10387 10401
10388 // according to the docs, this command only works if script owner and land owner are the same 10402 // according to the docs, this command only works if script owner and land owner are the same
10389 // lets add estate owners and gods, too, and use the generic permission check. 10403 // lets add estate owners and gods, too, and use the generic permission check.
10390 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10404 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10391 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 10405 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return;
10392 10406
10393 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 10407 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
@@ -10710,22 +10724,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10710 m_host.AddScriptLPS(1); 10724 m_host.AddScriptLPS(1);
10711 10725
10712 if (m_item.PermsGranter == UUID.Zero) 10726 if (m_item.PermsGranter == UUID.Zero)
10713 return new LSL_Vector(); 10727 return Vector3.Zero;
10714 10728
10715 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10729 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10716 { 10730 {
10717 ShoutError("No permissions to track the camera"); 10731 ShoutError("No permissions to track the camera");
10718 return new LSL_Vector(); 10732 return Vector3.Zero;
10719 } 10733 }
10720 10734
10721// ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10735// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10722 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 10736 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10723 if (presence != null) 10737 if (presence != null)
10724 { 10738 {
10725 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10739 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
10726 return pos; 10740 return pos;
10727 } 10741 }
10728 return new LSL_Vector(); 10742
10743 return Vector3.Zero;
10729 } 10744 }
10730 10745
10731 public LSL_Rotation llGetCameraRot() 10746 public LSL_Rotation llGetCameraRot()
@@ -10733,22 +10748,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10733 m_host.AddScriptLPS(1); 10748 m_host.AddScriptLPS(1);
10734 10749
10735 if (m_item.PermsGranter == UUID.Zero) 10750 if (m_item.PermsGranter == UUID.Zero)
10736 return new LSL_Rotation(); 10751 return Quaternion.Identity;
10737 10752
10738 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10753 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10739 { 10754 {
10740 ShoutError("No permissions to track the camera"); 10755 ShoutError("No permissions to track the camera");
10741 return new LSL_Rotation(); 10756 return Quaternion.Identity;
10742 } 10757 }
10743 10758
10744// ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10759// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10745 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 10760 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10746 if (presence != null) 10761 if (presence != null)
10747 { 10762 {
10748 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10763 return new LSL_Rotation(presence.CameraRotation);
10749 } 10764 }
10750 10765
10751 return new LSL_Rotation(); 10766 return Quaternion.Identity;
10752 } 10767 }
10753 10768
10754 /// <summary> 10769 /// <summary>
@@ -10829,7 +10844,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10829 { 10844 {
10830 m_host.AddScriptLPS(1); 10845 m_host.AddScriptLPS(1);
10831 UUID key; 10846 UUID key;
10832 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10847 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10833 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10848 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10834 { 10849 {
10835 int expires = 0; 10850 int expires = 0;
@@ -10870,7 +10885,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10870 { 10885 {
10871 m_host.AddScriptLPS(1); 10886 m_host.AddScriptLPS(1);
10872 UUID key; 10887 UUID key;
10873 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10888 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10874 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 10889 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed))
10875 { 10890 {
10876 if (UUID.TryParse(avatar, out key)) 10891 if (UUID.TryParse(avatar, out key))
@@ -10897,7 +10912,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10897 { 10912 {
10898 m_host.AddScriptLPS(1); 10913 m_host.AddScriptLPS(1);
10899 UUID key; 10914 UUID key;
10900 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10915 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10901 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10916 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10902 { 10917 {
10903 if (UUID.TryParse(avatar, out key)) 10918 if (UUID.TryParse(avatar, out key))
@@ -11129,9 +11144,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11129 IHttpRequestModule httpScriptMod = 11144 IHttpRequestModule httpScriptMod =
11130 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); 11145 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
11131 List<string> param = new List<string>(); 11146 List<string> param = new List<string>();
11132 foreach (object o in parameters.Data) 11147 bool ok;
11148 Int32 flag;
11149
11150 for (int i = 0; i < parameters.Data.Length; i += 2)
11133 { 11151 {
11134 param.Add(o.ToString()); 11152 ok = Int32.TryParse(parameters.Data[i].ToString(), out flag);
11153 if (!ok || flag < 0 ||
11154 flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE)
11155 {
11156 throw new ScriptException("Parameter " + i.ToString() + " is an invalid flag");
11157 }
11158
11159 param.Add(parameters.Data[i].ToString()); //Add parameter flag
11160
11161 if (flag != (int)HttpRequestConstants.HTTP_CUSTOM_HEADER)
11162 {
11163 param.Add(parameters.Data[i+1].ToString()); //Add parameter value
11164 }
11165 else
11166 {
11167 //Parameters are in pairs and custom header takes
11168 //arguments in pairs so adjust for header marker.
11169 ++i;
11170
11171 //Maximum of 8 headers are allowed based on the
11172 //Second Life documentation for llHTTPRequest.
11173 for (int count = 1; count <= 8; ++count)
11174 {
11175 //Enough parameters remaining for (another) header?
11176 if (parameters.Data.Length - i < 2)
11177 {
11178 //There must be at least one name/value pair for custom header
11179 if (count == 1)
11180 throw new ScriptException("Missing name/value for custom header at parameter " + i.ToString());
11181 break;
11182 }
11183
11184 if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase))
11185 throw new ScriptException("Name is invalid as a custom header at parameter " + i.ToString());
11186
11187 param.Add(parameters.Data[i].ToString());
11188 param.Add(parameters.Data[i+1].ToString());
11189
11190 //Have we reached the end of the list of headers?
11191 //End is marked by a string with a single digit.
11192 if (i+2 >= parameters.Data.Length ||
11193 Char.IsDigit(parameters.Data[i].ToString()[0]))
11194 {
11195 break;
11196 }
11197
11198 i += 2;
11199 }
11200 }
11135 } 11201 }
11136 11202
11137 Vector3 position = m_host.AbsolutePosition; 11203 Vector3 position = m_host.AbsolutePosition;
@@ -11263,7 +11329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11263 public void llResetLandBanList() 11329 public void llResetLandBanList()
11264 { 11330 {
11265 m_host.AddScriptLPS(1); 11331 m_host.AddScriptLPS(1);
11266 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 11332 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
11267 if (land.OwnerID == m_host.OwnerID) 11333 if (land.OwnerID == m_host.OwnerID)
11268 { 11334 {
11269 foreach (LandAccessEntry entry in land.ParcelAccessList) 11335 foreach (LandAccessEntry entry in land.ParcelAccessList)
@@ -11280,7 +11346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11280 public void llResetLandPassList() 11346 public void llResetLandPassList()
11281 { 11347 {
11282 m_host.AddScriptLPS(1); 11348 m_host.AddScriptLPS(1);
11283 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 11349 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
11284 if (land.OwnerID == m_host.OwnerID) 11350 if (land.OwnerID == m_host.OwnerID)
11285 { 11351 {
11286 foreach (LandAccessEntry entry in land.ParcelAccessList) 11352 foreach (LandAccessEntry entry in land.ParcelAccessList)
@@ -11297,12 +11363,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11297 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) 11363 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide)
11298 { 11364 {
11299 m_host.AddScriptLPS(1); 11365 m_host.AddScriptLPS(1);
11300 11366
11301 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 11367 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
11302 11368
11303 if (lo == null) 11369 if (lo == null)
11304 return 0; 11370 return 0;
11305 11371
11306 IPrimCounts pc = lo.PrimCounts; 11372 IPrimCounts pc = lo.PrimCounts;
11307 11373
11308 if (sim_wide != ScriptBaseClass.FALSE) 11374 if (sim_wide != ScriptBaseClass.FALSE)
@@ -11332,7 +11398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11332 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP) 11398 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP)
11333 return 0; // counts not implemented yet 11399 return 0; // counts not implemented yet
11334 } 11400 }
11335 11401
11336 return 0; 11402 return 0;
11337 } 11403 }
11338 11404
@@ -11517,6 +11583,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11517 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11583 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11518 ret.Add(new LSL_Float(0)); 11584 ret.Add(new LSL_Float(0));
11519 break; 11585 break;
11586 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11587 ret.Add(new LSL_Float(0));
11588 break;
11589 case ScriptBaseClass.OBJECT_ROOT:
11590 SceneObjectPart p = av.ParentPart;
11591 if (p != null)
11592 {
11593 ret.Add(new LSL_String(p.ParentGroup.RootPart.UUID.ToString()));
11594 }
11595 else
11596 {
11597 ret.Add(new LSL_String(id));
11598 }
11599 break;
11600 case ScriptBaseClass.OBJECT_ATTACHED_POINT:
11601 ret.Add(new LSL_Integer(0));
11602 break;
11603 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: // Pathfinding
11604 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_AVATAR));
11605 break;
11606 case ScriptBaseClass.OBJECT_PHYSICS:
11607 ret.Add(new LSL_Integer(0));
11608 break;
11609 case ScriptBaseClass.OBJECT_PHANTOM:
11610 ret.Add(new LSL_Integer(0));
11611 break;
11612 case ScriptBaseClass.OBJECT_TEMP_ON_REZ:
11613 ret.Add(new LSL_Integer(0));
11614 break;
11520 default: 11615 default:
11521 // Invalid or unhandled constant. 11616 // Invalid or unhandled constant.
11522 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 11617 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
@@ -11608,6 +11703,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11608 // The value returned in SL for normal prims is prim count 11703 // The value returned in SL for normal prims is prim count
11609 ret.Add(new LSL_Float(obj.PhysicsCost)); 11704 ret.Add(new LSL_Float(obj.PhysicsCost));
11610 break; 11705 break;
11706 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11707 ret.Add(new LSL_Float(0));
11708 break;
11709 case ScriptBaseClass.OBJECT_ROOT:
11710 ret.Add(new LSL_String(obj.ParentGroup.RootPart.UUID.ToString()));
11711 break;
11712 case ScriptBaseClass.OBJECT_ATTACHED_POINT:
11713 ret.Add(new LSL_Integer(obj.ParentGroup.AttachmentPoint));
11714 break;
11715 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE:
11716 byte pcode = obj.Shape.PCode;
11717 if (obj.ParentGroup.AttachmentPoint != 0
11718 || pcode == (byte)PCode.Grass
11719 || pcode == (byte)PCode.Tree
11720 || pcode == (byte)PCode.NewTree)
11721 {
11722 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_OTHER));
11723 }
11724 else
11725 {
11726 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_LEGACY_LINKSET));
11727 }
11728 break;
11729 case ScriptBaseClass.OBJECT_PHYSICS:
11730 if (obj.ParentGroup.AttachmentPoint != 0)
11731 {
11732 ret.Add(new LSL_Integer(0)); // Always false if attached
11733 }
11734 else
11735 {
11736 ret.Add(new LSL_Integer(obj.ParentGroup.UsesPhysics ? 1 : 0));
11737 }
11738 break;
11739 case ScriptBaseClass.OBJECT_PHANTOM:
11740 if (obj.ParentGroup.AttachmentPoint != 0)
11741 {
11742 ret.Add(new LSL_Integer(0)); // Always false if attached
11743 }
11744 else
11745 {
11746 ret.Add(new LSL_Integer(obj.ParentGroup.IsPhantom ? 1 : 0));
11747 }
11748 break;
11749 case ScriptBaseClass.OBJECT_TEMP_ON_REZ:
11750 ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0));
11751 break;
11611 default: 11752 default:
11612 // Invalid or unhandled constant. 11753 // Invalid or unhandled constant.
11613 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 11754 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
@@ -11618,7 +11759,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11618 return ret; 11759 return ret;
11619 } 11760 }
11620 } 11761 }
11621 11762
11622 return new LSL_List(); 11763 return new LSL_List();
11623 } 11764 }
11624 11765
@@ -11687,14 +11828,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11687 return UUID.Zero.ToString(); 11828 return UUID.Zero.ToString();
11688 } 11829 }
11689 11830
11831 string reqIdentifier = UUID.Random().ToString();
11832
11690 // was: UUID tid = tid = AsyncCommands. 11833 // was: UUID tid = tid = AsyncCommands.
11691 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, assetID.ToString()); 11834 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier);
11692 11835
11693 if (NotecardCache.IsCached(assetID)) 11836 if (NotecardCache.IsCached(assetID))
11694 { 11837 {
11695 AsyncCommands. 11838 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(assetID).ToString());
11696 DataserverPlugin.DataserverReply(assetID.ToString(), 11839
11697 NotecardCache.GetLines(assetID).ToString());
11698 ScriptSleep(100); 11840 ScriptSleep(100);
11699 return tid.ToString(); 11841 return tid.ToString();
11700 } 11842 }
@@ -11710,9 +11852,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11710 string data = Encoding.UTF8.GetString(a.Data); 11852 string data = Encoding.UTF8.GetString(a.Data);
11711 //m_log.Debug(data); 11853 //m_log.Debug(data);
11712 NotecardCache.Cache(id, data); 11854 NotecardCache.Cache(id, data);
11713 AsyncCommands. 11855 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString());
11714 DataserverPlugin.DataserverReply(id.ToString(),
11715 NotecardCache.GetLines(id).ToString());
11716 }); 11856 });
11717 11857
11718 ScriptSleep(100); 11858 ScriptSleep(100);
@@ -11741,13 +11881,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11741 return UUID.Zero.ToString(); 11881 return UUID.Zero.ToString();
11742 } 11882 }
11743 11883
11884 string reqIdentifier = UUID.Random().ToString();
11885
11744 // was: UUID tid = tid = AsyncCommands. 11886 // was: UUID tid = tid = AsyncCommands.
11745 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, assetID.ToString()); 11887 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier);
11746 11888
11747 if (NotecardCache.IsCached(assetID)) 11889 if (NotecardCache.IsCached(assetID))
11748 { 11890 {
11749 AsyncCommands.DataserverPlugin.DataserverReply(assetID.ToString(), 11891 AsyncCommands.DataserverPlugin.DataserverReply(
11750 NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); 11892 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11893
11751 ScriptSleep(100); 11894 ScriptSleep(100);
11752 return tid.ToString(); 11895 return tid.ToString();
11753 } 11896 }
@@ -11763,8 +11906,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11763 string data = Encoding.UTF8.GetString(a.Data); 11906 string data = Encoding.UTF8.GetString(a.Data);
11764 //m_log.Debug(data); 11907 //m_log.Debug(data);
11765 NotecardCache.Cache(id, data); 11908 NotecardCache.Cache(id, data);
11766 AsyncCommands.DataserverPlugin.DataserverReply(id.ToString(), 11909 AsyncCommands.DataserverPlugin.DataserverReply(
11767 NotecardCache.GetLine(id, line, m_notecardLineReadCharsMax)); 11910 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11768 }); 11911 });
11769 11912
11770 ScriptSleep(100); 11913 ScriptSleep(100);
@@ -11799,7 +11942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11799 11942
11800 LSL_List result = new LSL_List(); 11943 LSL_List result = new LSL_List();
11801 11944
11802 if (obj != null && obj.OwnerID != m_host.OwnerID) 11945 if (obj != null && obj.OwnerID == m_host.OwnerID)
11803 { 11946 {
11804 LSL_List remaining = GetPrimParams(obj, rules, ref result); 11947 LSL_List remaining = GetPrimParams(obj, rules, ref result);
11805 11948
@@ -11903,7 +12046,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11903 World.ForEachScenePresence(delegate(ScenePresence sp) 12046 World.ForEachScenePresence(delegate(ScenePresence sp)
11904 { 12047 {
11905 Vector3 ac = sp.AbsolutePosition - rayStart; 12048 Vector3 ac = sp.AbsolutePosition - rayStart;
11906 Vector3 bc = sp.AbsolutePosition - rayEnd; 12049// Vector3 bc = sp.AbsolutePosition - rayEnd;
11907 12050
11908 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 12051 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11909 12052
@@ -11991,9 +12134,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11991 radius = Math.Abs(maxY); 12134 radius = Math.Abs(maxY);
11992 if (Math.Abs(maxZ) > radius) 12135 if (Math.Abs(maxZ) > radius)
11993 radius = Math.Abs(maxZ); 12136 radius = Math.Abs(maxZ);
11994 12137 radius = radius*1.413f;
11995 Vector3 ac = group.AbsolutePosition - rayStart; 12138 Vector3 ac = group.AbsolutePosition - rayStart;
11996 Vector3 bc = group.AbsolutePosition - rayEnd; 12139// Vector3 bc = group.AbsolutePosition - rayEnd;
11997 12140
11998 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 12141 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11999 12142
@@ -12006,11 +12149,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12006 if (d2 > 0) 12149 if (d2 > 0)
12007 return; 12150 return;
12008 12151
12152 ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
12009 EntityIntersection intersection = group.TestIntersection(ray, true, false); 12153 EntityIntersection intersection = group.TestIntersection(ray, true, false);
12010 // Miss. 12154 // Miss.
12011 if (!intersection.HitTF) 12155 if (!intersection.HitTF)
12012 return; 12156 return;
12013 12157
12158 Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ);
12159 Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ);
12160 //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);
12161 if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X &&
12162 intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y &&
12163 intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z))
12164 return;
12165
12014 ContactResult result = new ContactResult (); 12166 ContactResult result = new ContactResult ();
12015 result.ConsumerID = group.LocalId; 12167 result.ConsumerID = group.LocalId;
12016// result.Depth = intersection.distance; 12168// result.Depth = intersection.distance;
@@ -12226,7 +12378,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12226 if (checkNonPhysical) 12378 if (checkNonPhysical)
12227 rayfilter |= RayFilterFlags.nonphysical; 12379 rayfilter |= RayFilterFlags.nonphysical;
12228 if (detectPhantom) 12380 if (detectPhantom)
12229 rayfilter |= RayFilterFlags.LSLPhanton; 12381 rayfilter |= RayFilterFlags.LSLPhantom;
12230 12382
12231 Vector3 direction = dir * ( 1/dist); 12383 Vector3 direction = dir * ( 1/dist);
12232 12384
@@ -12284,8 +12436,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12284 if (checkPhysical || checkNonPhysical || detectPhantom) 12436 if (checkPhysical || checkNonPhysical || detectPhantom)
12285 { 12437 {
12286 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12438 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12287 foreach (ContactResult r in objectHits) 12439 for (int iter = 0; iter < objectHits.Length; iter++)
12288 results.Add(r); 12440 {
12441 // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler.
12442 objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart);
12443 results.Add(objectHits[iter]);
12444 }
12289 } 12445 }
12290 } 12446 }
12291 12447
@@ -12346,7 +12502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12346 else 12502 else
12347 { 12503 {
12348 ScenePresence sp = World.GetScenePresence(result.ConsumerID); 12504 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
12349 /// It it a boy? a girl? 12505 /// It it a boy? a girl?
12350 if (sp != null) 12506 if (sp != null)
12351 itemID = sp.UUID; 12507 itemID = sp.UUID;
12352 } 12508 }
@@ -12358,7 +12514,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12358 list.Add(new LSL_Integer(linkNum)); 12514 list.Add(new LSL_Integer(linkNum));
12359 12515
12360 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 12516 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
12361 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z)); 12517 list.Add(new LSL_Vector(result.Normal));
12362 12518
12363 values++; 12519 values++;
12364 if (values >= count) 12520 if (values >= count)
@@ -13233,7 +13389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13233 13389
13234 public static void Cache(UUID assetID, string text) 13390 public static void Cache(UUID assetID, string text)
13235 { 13391 {
13236 CacheCheck(); 13392 CheckCache();
13237 13393
13238 lock (m_Notecards) 13394 lock (m_Notecards)
13239 { 13395 {
@@ -13271,7 +13427,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13271 /// Get a notecard line. 13427 /// Get a notecard line.
13272 /// </summary> 13428 /// </summary>
13273 /// <param name="assetID"></param> 13429 /// <param name="assetID"></param>
13274 /// <param name="line">Lines start at index 0</param> 13430 /// <param name="lineNumber">Lines start at index 0</param>
13275 /// <returns></returns> 13431 /// <returns></returns>
13276 public static string GetLine(UUID assetID, int lineNumber) 13432 public static string GetLine(UUID assetID, int lineNumber)
13277 { 13433 {
@@ -13300,9 +13456,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13300 /// Get a notecard line. 13456 /// Get a notecard line.
13301 /// </summary> 13457 /// </summary>
13302 /// <param name="assetID"></param> 13458 /// <param name="assetID"></param>
13303 /// <param name="line">Lines start at index 0</param> 13459 /// <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> 13460 /// <param name="maxLength">
13305 /// <returns></returns> 13461 /// Maximum length of the returned line.
13462 /// </param>
13463 /// <returns>
13464 /// If the line length is longer than <paramref name="maxLength"/>,
13465 /// the return string will be truncated.
13466 /// </returns>
13306 public static string GetLine(UUID assetID, int lineNumber, int maxLength) 13467 public static string GetLine(UUID assetID, int lineNumber, int maxLength)
13307 { 13468 {
13308 string line = GetLine(assetID, lineNumber); 13469 string line = GetLine(assetID, lineNumber);
@@ -13313,13 +13474,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13313 return line; 13474 return line;
13314 } 13475 }
13315 13476
13316 public static void CacheCheck() 13477 public static void CheckCache()
13317 { 13478 {
13318 foreach (UUID key in new List<UUID>(m_Notecards.Keys)) 13479 lock (m_Notecards)
13319 { 13480 {
13320 Notecard nc = m_Notecards[key]; 13481 foreach (UUID key in new List<UUID>(m_Notecards.Keys))
13321 if (nc.lastRef.AddSeconds(30) < DateTime.Now) 13482 {
13322 m_Notecards.Remove(key); 13483 Notecard nc = m_Notecards[key];
13484 if (nc.lastRef.AddSeconds(30) < DateTime.Now)
13485 m_Notecards.Remove(key);
13486 }
13323 } 13487 }
13324 } 13488 }
13325 } 13489 }
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;
30using System.Collections; 30using System.Collections;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
33using System.Threading;
33using OpenMetaverse; 34using OpenMetaverse;
34using Nini.Config; 35using Nini.Config;
35using OpenSim; 36using 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..bd776b6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -30,6 +30,8 @@ using System.Reflection;
30using System.Collections; 30using System.Collections;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
33using System.Threading;
34using log4net;
33using OpenMetaverse; 35using OpenMetaverse;
34using Nini.Config; 36using Nini.Config;
35using OpenSim; 37using OpenSim;
@@ -55,15 +57,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
55 [Serializable] 57 [Serializable]
56 public class MOD_Api : MarshalByRefObject, IMOD_Api, IScriptApi 58 public class MOD_Api : MarshalByRefObject, IMOD_Api, IScriptApi
57 { 59 {
60// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
61
58 internal IScriptEngine m_ScriptEngine; 62 internal IScriptEngine m_ScriptEngine;
59 internal SceneObjectPart m_host; 63 internal SceneObjectPart m_host;
60 internal TaskInventoryItem m_item; 64 internal TaskInventoryItem m_item;
61 internal bool m_MODFunctionsEnabled = false; 65 internal bool m_MODFunctionsEnabled = false;
62 internal IScriptModuleComms m_comms = null; 66 internal IScriptModuleComms m_comms = null;
63 67
64 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 68 public void Initialize(
69 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
65 { 70 {
66 m_ScriptEngine = ScriptEngine; 71 m_ScriptEngine = scriptEngine;
67 m_host = host; 72 m_host = host;
68 m_item = item; 73 m_item = item;
69 74
@@ -107,8 +112,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
107 if (message.Length > 1023) 112 if (message.Length > 1023)
108 message = message.Substring(0, 1023); 113 message = message.Substring(0, 1023);
109 114
110 World.SimChat(Utils.StringToBytes(message), 115 World.SimChat(
111 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); 116 Utils.StringToBytes(message),
117 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL,
118 m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false);
112 119
113 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 120 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
114 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); 121 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
@@ -122,8 +129,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
122 /// <returns>string result of the invocation</returns> 129 /// <returns>string result of the invocation</returns>
123 public void modInvokeN(string fname, params object[] parms) 130 public void modInvokeN(string fname, params object[] parms)
124 { 131 {
132// m_log.DebugFormat(
133// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
134// fname,
135// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
137
125 Type returntype = m_comms.LookupReturnType(fname); 138 Type returntype = m_comms.LookupReturnType(fname);
126 if (returntype != typeof(string)) 139 if (returntype != typeof(void))
127 MODError(String.Format("return type mismatch for {0}",fname)); 140 MODError(String.Format("return type mismatch for {0}",fname));
128 141
129 modInvoke(fname,parms); 142 modInvoke(fname,parms);
@@ -131,6 +144,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
131 144
132 public LSL_String modInvokeS(string fname, params object[] parms) 145 public LSL_String modInvokeS(string fname, params object[] parms)
133 { 146 {
147// m_log.DebugFormat(
148// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
149// fname,
150// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
151// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
152
134 Type returntype = m_comms.LookupReturnType(fname); 153 Type returntype = m_comms.LookupReturnType(fname);
135 if (returntype != typeof(string)) 154 if (returntype != typeof(string))
136 MODError(String.Format("return type mismatch for {0}",fname)); 155 MODError(String.Format("return type mismatch for {0}",fname));
@@ -141,6 +160,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
141 160
142 public LSL_Integer modInvokeI(string fname, params object[] parms) 161 public LSL_Integer modInvokeI(string fname, params object[] parms)
143 { 162 {
163// m_log.DebugFormat(
164// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
165// fname,
166// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
167// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
168
144 Type returntype = m_comms.LookupReturnType(fname); 169 Type returntype = m_comms.LookupReturnType(fname);
145 if (returntype != typeof(int)) 170 if (returntype != typeof(int))
146 MODError(String.Format("return type mismatch for {0}",fname)); 171 MODError(String.Format("return type mismatch for {0}",fname));
@@ -151,6 +176,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
151 176
152 public LSL_Float modInvokeF(string fname, params object[] parms) 177 public LSL_Float modInvokeF(string fname, params object[] parms)
153 { 178 {
179// m_log.DebugFormat(
180// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
181// fname,
182// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
183// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
184
154 Type returntype = m_comms.LookupReturnType(fname); 185 Type returntype = m_comms.LookupReturnType(fname);
155 if (returntype != typeof(float)) 186 if (returntype != typeof(float))
156 MODError(String.Format("return type mismatch for {0}",fname)); 187 MODError(String.Format("return type mismatch for {0}",fname));
@@ -161,6 +192,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 192
162 public LSL_Key modInvokeK(string fname, params object[] parms) 193 public LSL_Key modInvokeK(string fname, params object[] parms)
163 { 194 {
195// m_log.DebugFormat(
196// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
197// fname,
198// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
199// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
200
164 Type returntype = m_comms.LookupReturnType(fname); 201 Type returntype = m_comms.LookupReturnType(fname);
165 if (returntype != typeof(UUID)) 202 if (returntype != typeof(UUID))
166 MODError(String.Format("return type mismatch for {0}",fname)); 203 MODError(String.Format("return type mismatch for {0}",fname));
@@ -171,6 +208,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 208
172 public LSL_Vector modInvokeV(string fname, params object[] parms) 209 public LSL_Vector modInvokeV(string fname, params object[] parms)
173 { 210 {
211// m_log.DebugFormat(
212// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
213// fname,
214// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
215// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
216
174 Type returntype = m_comms.LookupReturnType(fname); 217 Type returntype = m_comms.LookupReturnType(fname);
175 if (returntype != typeof(OpenMetaverse.Vector3)) 218 if (returntype != typeof(OpenMetaverse.Vector3))
176 MODError(String.Format("return type mismatch for {0}",fname)); 219 MODError(String.Format("return type mismatch for {0}",fname));
@@ -181,6 +224,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
181 224
182 public LSL_Rotation modInvokeR(string fname, params object[] parms) 225 public LSL_Rotation modInvokeR(string fname, params object[] parms)
183 { 226 {
227// m_log.DebugFormat(
228// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
229// fname,
230// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
231// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
232
184 Type returntype = m_comms.LookupReturnType(fname); 233 Type returntype = m_comms.LookupReturnType(fname);
185 if (returntype != typeof(OpenMetaverse.Quaternion)) 234 if (returntype != typeof(OpenMetaverse.Quaternion))
186 MODError(String.Format("return type mismatch for {0}",fname)); 235 MODError(String.Format("return type mismatch for {0}",fname));
@@ -191,6 +240,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
191 240
192 public LSL_List modInvokeL(string fname, params object[] parms) 241 public LSL_List modInvokeL(string fname, params object[] parms)
193 { 242 {
243// m_log.DebugFormat(
244// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
245// fname,
246// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
247// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
248
194 Type returntype = m_comms.LookupReturnType(fname); 249 Type returntype = m_comms.LookupReturnType(fname);
195 if (returntype != typeof(object[])) 250 if (returntype != typeof(object[]))
196 MODError(String.Format("return type mismatch for {0}",fname)); 251 MODError(String.Format("return type mismatch for {0}",fname));
@@ -211,6 +266,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
211 { 266 {
212 llist[i] = new LSL_Float((float)result[i]); 267 llist[i] = new LSL_Float((float)result[i]);
213 } 268 }
269 else if (result[i] is double)
270 {
271 llist[i] = new LSL_Float((double)result[i]);
272 }
214 else if (result[i] is UUID) 273 else if (result[i] is UUID)
215 { 274 {
216 llist[i] = new LSL_Key(result[i].ToString()); 275 llist[i] = new LSL_Key(result[i].ToString());
@@ -248,6 +307,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
248 return ""; 307 return "";
249 } 308 }
250 309
310// m_log.DebugFormat(
311// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
312// fname,
313// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
314// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
315
251 Type[] signature = m_comms.LookupTypeSignature(fname); 316 Type[] signature = m_comms.LookupTypeSignature(fname);
252 if (signature.Length != parms.Length) 317 if (signature.Length != parms.Length)
253 MODError(String.Format("wrong number of parameters to function {0}",fname)); 318 MODError(String.Format("wrong number of parameters to function {0}",fname));
@@ -264,6 +329,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
264 if (result != null) 329 if (result != null)
265 return result; 330 return result;
266 331
332 Type returntype = m_comms.LookupReturnType(fname);
333 if (returntype == typeof(void))
334 return null;
335
267 MODError(String.Format("Invocation of {0} failed; null return value",fname)); 336 MODError(String.Format("Invocation of {0} failed; null return value",fname));
268 } 337 }
269 catch (Exception e) 338 catch (Exception e)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 7c2f8ed..f4e4f44 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -62,6 +62,7 @@ using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
62using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; 62using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
63using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 63using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
64using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 64using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
65using PermissionMask = OpenSim.Framework.PermissionMask;
65 66
66namespace OpenSim.Region.ScriptEngine.Shared.Api 67namespace OpenSim.Region.ScriptEngine.Shared.Api
67{ 68{
@@ -143,9 +144,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
143 144
144 protected IUrlModule m_UrlModule = null; 145 protected IUrlModule m_UrlModule = null;
145 146
146 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 147 public void Initialize(
148 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
147 { 149 {
148 m_ScriptEngine = ScriptEngine; 150 m_ScriptEngine = scriptEngine;
149 m_host = host; 151 m_host = host;
150 m_item = item; 152 m_item = item;
151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); 153 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
@@ -254,11 +256,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
254 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); 256 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
255 } 257 }
256 258
259 // Returns of the function is allowed. Throws a script exception if not allowed.
257 public void CheckThreatLevel(ThreatLevel level, string function) 260 public void CheckThreatLevel(ThreatLevel level, string function)
258 { 261 {
259 if (!m_OSFunctionsEnabled) 262 if (!m_OSFunctionsEnabled)
260 OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws 263 OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws
261 264
265 string reasonWhyNot = CheckThreatLevelTest(level, function);
266 if (!String.IsNullOrEmpty(reasonWhyNot))
267 {
268 OSSLError(reasonWhyNot);
269 }
270 }
271
272 // Check to see if function is allowed. Returns an empty string if function permitted
273 // or a string explaining why this function can't be used.
274 private string CheckThreatLevelTest(ThreatLevel level, string function)
275 {
262 if (!m_FunctionPerms.ContainsKey(function)) 276 if (!m_FunctionPerms.ContainsKey(function))
263 { 277 {
264 FunctionPerms perms = new FunctionPerms(); 278 FunctionPerms perms = new FunctionPerms();
@@ -338,10 +352,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
338 { 352 {
339 // Allow / disallow by threat level 353 // Allow / disallow by threat level
340 if (level > m_MaxThreatLevel) 354 if (level > m_MaxThreatLevel)
341 OSSLError( 355 return
342 String.Format( 356 String.Format(
343 "{0} permission denied. Allowed threat level is {1} but function threat level is {2}.", 357 "{0} permission denied. Allowed threat level is {1} but function threat level is {2}.",
344 function, m_MaxThreatLevel, level)); 358 function, m_MaxThreatLevel, level);
345 } 359 }
346 else 360 else
347 { 361 {
@@ -351,7 +365,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
351 if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID)) 365 if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID))
352 { 366 {
353 // prim owner is in the list of allowed owners 367 // prim owner is in the list of allowed owners
354 return; 368 return String.Empty;
355 } 369 }
356 370
357 UUID ownerID = m_item.OwnerID; 371 UUID ownerID = m_item.OwnerID;
@@ -359,22 +373,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
359 //OSSL only may be used if object is in the same group as the parcel 373 //OSSL only may be used if object is in the same group as the parcel
360 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER")) 374 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER"))
361 { 375 {
362 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 376 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
363 377
364 if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero) 378 if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero)
365 { 379 {
366 return; 380 return String.Empty;
367 } 381 }
368 } 382 }
369 383
370 //Only Parcelowners may use the function 384 //Only Parcelowners may use the function
371 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_OWNER")) 385 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_OWNER"))
372 { 386 {
373 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 387 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
374 388
375 if (land.LandData.OwnerID == ownerID) 389 if (land.LandData.OwnerID == ownerID)
376 { 390 {
377 return; 391 return String.Empty;
378 } 392 }
379 } 393 }
380 394
@@ -384,7 +398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 //Only Estate Managers may use the function 398 //Only Estate Managers may use the function
385 if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID) 399 if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID)
386 { 400 {
387 return; 401 return String.Empty;
388 } 402 }
389 } 403 }
390 404
@@ -393,25 +407,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
393 { 407 {
394 if (World.RegionInfo.EstateSettings.EstateOwner == ownerID) 408 if (World.RegionInfo.EstateSettings.EstateOwner == ownerID)
395 { 409 {
396 return; 410 return String.Empty;
397 } 411 }
398 } 412 }
399 413
400 if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID)) 414 if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID))
401 OSSLError( 415 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.", 416 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)); 417 function));
404 418
405 if (m_item.CreatorID != ownerID) 419 if (m_item.CreatorID != ownerID)
406 { 420 {
407 if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0) 421 if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0)
408 OSSLError( 422 return String.Format("{0} permission denied. Script permissions error.", function);
409 String.Format("{0} permission denied. Script permissions error.",
410 function));
411 423
412 } 424 }
413 } 425 }
414 } 426 }
427 return String.Empty;
415 } 428 }
416 429
417 internal void OSSLDeprecated(string function, string replacement) 430 internal void OSSLDeprecated(string function, string replacement)
@@ -983,7 +996,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
983 if (animID == UUID.Zero) 996 if (animID == UUID.Zero)
984 target.Animator.RemoveAnimation(animation); 997 target.Animator.RemoveAnimation(animation);
985 else 998 else
986 target.Animator.RemoveAnimation(animID); 999 target.Animator.RemoveAnimation(animID, true);
987 } 1000 }
988 } 1001 }
989 } 1002 }
@@ -1214,12 +1227,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1214 sunHour += 24.0; 1227 sunHour += 24.0;
1215 1228
1216 World.RegionInfo.RegionSettings.UseEstateSun = useEstateSun; 1229 World.RegionInfo.RegionSettings.UseEstateSun = useEstateSun;
1217 World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30 1230 World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30
1218 World.RegionInfo.RegionSettings.FixedSun = sunFixed; 1231 World.RegionInfo.RegionSettings.FixedSun = sunFixed;
1219 World.RegionInfo.RegionSettings.Save(); 1232 World.RegionInfo.RegionSettings.Save();
1220 1233
1221 World.EventManager.TriggerEstateToolsSunUpdate( 1234 World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle);
1222 World.RegionInfo.RegionHandle, sunFixed, useEstateSun, (float)sunHour);
1223 } 1235 }
1224 1236
1225 /// <summary> 1237 /// <summary>
@@ -1244,8 +1256,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1244 World.RegionInfo.EstateSettings.FixedSun = sunFixed; 1256 World.RegionInfo.EstateSettings.FixedSun = sunFixed;
1245 World.RegionInfo.EstateSettings.Save(); 1257 World.RegionInfo.EstateSettings.Save();
1246 1258
1247 World.EventManager.TriggerEstateToolsSunUpdate( 1259 World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle);
1248 World.RegionInfo.RegionHandle, sunFixed, World.RegionInfo.RegionSettings.UseEstateSun, (float)sunHour);
1249 } 1260 }
1250 1261
1251 /// <summary> 1262 /// <summary>
@@ -1501,8 +1512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1501 1512
1502 m_host.AddScriptLPS(1); 1513 m_host.AddScriptLPS(1);
1503 1514
1504 ILandObject land 1515 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
1505 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1506 1516
1507 if (land.LandData.OwnerID != m_host.OwnerID) 1517 if (land.LandData.OwnerID != m_host.OwnerID)
1508 return; 1518 return;
@@ -1518,8 +1528,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1518 1528
1519 m_host.AddScriptLPS(1); 1529 m_host.AddScriptLPS(1);
1520 1530
1521 ILandObject land 1531 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
1522 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1523 1532
1524 if (land.LandData.OwnerID != m_host.OwnerID) 1533 if (land.LandData.OwnerID != m_host.OwnerID)
1525 { 1534 {
@@ -1569,6 +1578,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1569 } 1578 }
1570 } 1579 }
1571 1580
1581 public string osGetPhysicsEngineType()
1582 {
1583 // High because it can be used to target attacks to known weaknesses
1584 // This would allow a new class of griefer scripts that don't even
1585 // require their user to know what they are doing (see script
1586 // kiddie)
1587 // Because it would be nice if scripts didn't blow up if the information
1588 // about the physics engine, this function returns an empty string if
1589 // the user does not have permission to see it. This as opposed to
1590 // throwing an exception.
1591 m_host.AddScriptLPS(1);
1592 string ret = String.Empty;
1593 if (String.IsNullOrEmpty(CheckThreatLevelTest(ThreatLevel.High, "osGetPhysicsEngineType")))
1594 {
1595 if (m_ScriptEngine.World.PhysicsScene != null)
1596 {
1597 ret = m_ScriptEngine.World.PhysicsScene.EngineType;
1598 // An old physics engine might have an uninitialized engine type
1599 if (ret == null)
1600 ret = "unknown";
1601 }
1602 }
1603
1604 return ret;
1605 }
1606
1572 public string osGetSimulatorVersion() 1607 public string osGetSimulatorVersion()
1573 { 1608 {
1574 // High because it can be used to target attacks to known weaknesses 1609 // High because it can be used to target attacks to known weaknesses
@@ -1619,7 +1654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1619 } 1654 }
1620 } 1655 }
1621 1656
1622 public Object osParseJSONNew(string JSON) 1657 private Object osParseJSONNew(string JSON)
1623 { 1658 {
1624 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); 1659 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1625 1660
@@ -1762,8 +1797,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1762 taskItem.InvType = (int)InventoryType.Notecard; 1797 taskItem.InvType = (int)InventoryType.Notecard;
1763 taskItem.OwnerID = m_host.OwnerID; 1798 taskItem.OwnerID = m_host.OwnerID;
1764 taskItem.CreatorID = m_host.OwnerID; 1799 taskItem.CreatorID = m_host.OwnerID;
1765 taskItem.BasePermissions = (uint)PermissionMask.All; 1800 taskItem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1766 taskItem.CurrentPermissions = (uint)PermissionMask.All; 1801 taskItem.CurrentPermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1767 taskItem.EveryonePermissions = 0; 1802 taskItem.EveryonePermissions = 0;
1768 taskItem.NextPermissions = (uint)PermissionMask.All; 1803 taskItem.NextPermissions = (uint)PermissionMask.All;
1769 taskItem.GroupID = m_host.GroupID; 1804 taskItem.GroupID = m_host.GroupID;
@@ -2136,9 +2171,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2136 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridHomeURI"); 2171 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridHomeURI");
2137 m_host.AddScriptLPS(1); 2172 m_host.AddScriptLPS(1);
2138 2173
2139 string HomeURI = String.Empty;
2140 IConfigSource config = m_ScriptEngine.ConfigSource; 2174 IConfigSource config = m_ScriptEngine.ConfigSource;
2175 string HomeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI",
2176 new string[] { "Startup", "Hypergrid" }, String.Empty);
2177
2178 if (!string.IsNullOrEmpty(HomeURI))
2179 return HomeURI;
2141 2180
2181 // Legacy. Remove soon!
2142 if (config.Configs["LoginService"] != null) 2182 if (config.Configs["LoginService"] != null)
2143 HomeURI = config.Configs["LoginService"].GetString("SRV_HomeURI", HomeURI); 2183 HomeURI = config.Configs["LoginService"].GetString("SRV_HomeURI", HomeURI);
2144 2184
@@ -2153,9 +2193,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2153 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridGatekeeperURI"); 2193 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridGatekeeperURI");
2154 m_host.AddScriptLPS(1); 2194 m_host.AddScriptLPS(1);
2155 2195
2156 string gatekeeperURI = String.Empty;
2157 IConfigSource config = m_ScriptEngine.ConfigSource; 2196 IConfigSource config = m_ScriptEngine.ConfigSource;
2197 string gatekeeperURI = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
2198 new string[] { "Startup", "Hypergrid" }, String.Empty);
2199
2200 if (!string.IsNullOrEmpty(gatekeeperURI))
2201 return gatekeeperURI;
2158 2202
2203 // Legacy. Remove soon!
2159 if (config.Configs["GridService"] != null) 2204 if (config.Configs["GridService"] != null)
2160 gatekeeperURI = config.Configs["GridService"].GetString("Gatekeeper", gatekeeperURI); 2205 gatekeeperURI = config.Configs["GridService"].GetString("Gatekeeper", gatekeeperURI);
2161 2206
@@ -2532,13 +2577,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2532 ScenePresence sp = World.GetScenePresence(npcId); 2577 ScenePresence sp = World.GetScenePresence(npcId);
2533 2578
2534 if (sp != null) 2579 if (sp != null)
2535 { 2580 return new LSL_Vector(sp.AbsolutePosition);
2536 Vector3 pos = sp.AbsolutePosition;
2537 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2538 }
2539 } 2581 }
2540 2582
2541 return new LSL_Vector(0, 0, 0); 2583 return Vector3.Zero;
2542 } 2584 }
2543 2585
2544 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos) 2586 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
@@ -2595,21 +2637,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2595 { 2637 {
2596 UUID npcId; 2638 UUID npcId;
2597 if (!UUID.TryParse(npc.m_string, out npcId)) 2639 if (!UUID.TryParse(npc.m_string, out npcId))
2598 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2640 return new LSL_Rotation(Quaternion.Identity);
2599 2641
2600 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID)) 2642 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2601 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2643 return new LSL_Rotation(Quaternion.Identity);
2602 2644
2603 ScenePresence sp = World.GetScenePresence(npcId); 2645 ScenePresence sp = World.GetScenePresence(npcId);
2604 2646
2605 if (sp != null) 2647 if (sp != null)
2606 { 2648 return new LSL_Rotation(sp.GetWorldRotation());
2607 Quaternion rot = sp.Rotation;
2608 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2609 }
2610 } 2649 }
2611 2650
2612 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2651 return Quaternion.Identity;
2613 } 2652 }
2614 2653
2615 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation) 2654 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
@@ -3055,20 +3094,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3055 3094
3056 UUID avatarId = new UUID(avatar); 3095 UUID avatarId = new UUID(avatar);
3057 ScenePresence presence = World.GetScenePresence(avatarId); 3096 ScenePresence presence = World.GetScenePresence(avatarId);
3058 Vector3 pos = m_host.GetWorldPosition(); 3097
3059 bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.X, (float)pos.Y, (float)pos.Z)); 3098 if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition()))
3060 if (result)
3061 { 3099 {
3062 if (presence != null) 3100 float health = presence.Health;
3063 { 3101 health += (float)healing;
3064 float health = presence.Health; 3102
3065 health += (float)healing; 3103 if (health >= 100)
3066 if (health >= 100) 3104 health = 100;
3067 { 3105
3068 health = 100; 3106 presence.setHealthWithUpdate(health);
3069 }
3070 presence.setHealthWithUpdate(health);
3071 }
3072 } 3107 }
3073 } 3108 }
3074 3109
@@ -3145,8 +3180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3145 if (avatar != null && avatar.UUID != m_host.OwnerID) 3180 if (avatar != null && avatar.UUID != m_host.OwnerID)
3146 { 3181 {
3147 result.Add(new LSL_String(avatar.UUID.ToString())); 3182 result.Add(new LSL_String(avatar.UUID.ToString()));
3148 OpenMetaverse.Vector3 ap = avatar.AbsolutePosition; 3183 result.Add(new LSL_Vector(avatar.AbsolutePosition));
3149 result.Add(new LSL_Vector(ap.X, ap.Y, ap.Z));
3150 result.Add(new LSL_String(avatar.Name)); 3184 result.Add(new LSL_String(avatar.Name));
3151 } 3185 }
3152 }); 3186 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 4dd795d..884f07c 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}
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/Implementation/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs
index d173db0..6d218a6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.7.6.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index c447d1f..a652cb8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -259,7 +259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
259 259
260 string osGetScriptEngineName(); 260 string osGetScriptEngineName();
261 string osGetSimulatorVersion(); 261 string osGetSimulatorVersion();
262 Object osParseJSONNew(string JSON); 262 string osGetPhysicsEngineType();
263 Hashtable osParseJSON(string JSON); 263 Hashtable osParseJSON(string JSON);
264 264
265 void osMessageObject(key objectUUID,string message); 265 void osMessageObject(key objectUUID,string message);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 0dd5a57..2f8154d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -356,6 +356,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
356 public const int HTTP_MIMETYPE = 1; 356 public const int HTTP_MIMETYPE = 1;
357 public const int HTTP_BODY_MAXLENGTH = 2; 357 public const int HTTP_BODY_MAXLENGTH = 2;
358 public const int HTTP_VERIFY_CERT = 3; 358 public const int HTTP_VERIFY_CERT = 3;
359 public const int HTTP_VERBOSE_THROTTLE = 4;
360 public const int HTTP_CUSTOM_HEADER = 5;
361 public const int HTTP_PRAGMA_NO_CACHE = 6;
359 362
360 public const int PRIM_MATERIAL = 2; 363 public const int PRIM_MATERIAL = 2;
361 public const int PRIM_PHYSICS = 3; 364 public const int PRIM_PHYSICS = 3;
@@ -557,6 +560,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
557 public const int OBJECT_SERVER_COST = 14; 560 public const int OBJECT_SERVER_COST = 14;
558 public const int OBJECT_STREAMING_COST = 15; 561 public const int OBJECT_STREAMING_COST = 15;
559 public const int OBJECT_PHYSICS_COST = 16; 562 public const int OBJECT_PHYSICS_COST = 16;
563 public const int OBJECT_CHARACTER_TIME = 17;
564 public const int OBJECT_ROOT = 18;
565 public const int OBJECT_ATTACHED_POINT = 19;
566 public const int OBJECT_PATHFINDING_TYPE = 20;
567 public const int OBJECT_PHYSICS = 21;
568 public const int OBJECT_PHANTOM = 22;
569 public const int OBJECT_TEMP_ON_REZ = 23;
570
571 // Pathfinding types
572 public const int OPT_OTHER = -1;
573 public const int OPT_LEGACY_LINKSET = 0;
574 public const int OPT_AVATAR = 1;
575 public const int OPT_CHARACTER = 2;
576 public const int OPT_WALKABLE = 3;
577 public const int OPT_STATIC_OBSTACLE = 4;
578 public const int OPT_MATERIAL_VOLUME = 5;
579 public const int OPT_EXCLUSION_VOLUME = 6;
560 580
561 // for llGetAgentList 581 // for llGetAgentList
562 public const int AGENT_LIST_PARCEL = 1; 582 public const int AGENT_LIST_PARCEL = 1;
@@ -619,7 +639,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
619 public const int TOUCH_INVALID_FACE = -1; 639 public const int TOUCH_INVALID_FACE = -1;
620 public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0); 640 public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0);
621 public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR; 641 public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
622 642
623 // constants for llGetPrimMediaParams/llSetPrimMediaParams 643 // constants for llGetPrimMediaParams/llSetPrimMediaParams
624 public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0; 644 public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0;
625 public const int PRIM_MEDIA_CONTROLS = 1; 645 public const int PRIM_MEDIA_CONTROLS = 1;
@@ -636,10 +656,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
636 public const int PRIM_MEDIA_WHITELIST = 12; 656 public const int PRIM_MEDIA_WHITELIST = 12;
637 public const int PRIM_MEDIA_PERMS_INTERACT = 13; 657 public const int PRIM_MEDIA_PERMS_INTERACT = 13;
638 public const int PRIM_MEDIA_PERMS_CONTROL = 14; 658 public const int PRIM_MEDIA_PERMS_CONTROL = 14;
639 659
640 public const int PRIM_MEDIA_CONTROLS_STANDARD = 0; 660 public const int PRIM_MEDIA_CONTROLS_STANDARD = 0;
641 public const int PRIM_MEDIA_CONTROLS_MINI = 1; 661 public const int PRIM_MEDIA_CONTROLS_MINI = 1;
642 662
643 public const int PRIM_MEDIA_PERM_NONE = 0; 663 public const int PRIM_MEDIA_PERM_NONE = 0;
644 public const int PRIM_MEDIA_PERM_OWNER = 1; 664 public const int PRIM_MEDIA_PERM_OWNER = 1;
645 public const int PRIM_MEDIA_PERM_GROUP = 2; 665 public const int PRIM_MEDIA_PERM_GROUP = 2;
@@ -672,7 +692,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
672 public const string TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; 692 public const string TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f";
673 public const string TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; 693 public const string TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903";
674 public const string TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; 694 public const string TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361";
675 695
676 // Constants for osGetRegionStats 696 // Constants for osGetRegionStats
677 public const int STATS_TIME_DILATION = 0; 697 public const int STATS_TIME_DILATION = 0;
678 public const int STATS_SIM_FPS = 1; 698 public const int STATS_SIM_FPS = 1;
@@ -725,7 +745,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
725 public static readonly LSLInteger RC_GET_ROOT_KEY = 2; 745 public static readonly LSLInteger RC_GET_ROOT_KEY = 2;
726 public static readonly LSLInteger RC_GET_LINK_NUM = 4; 746 public static readonly LSLInteger RC_GET_LINK_NUM = 4;
727 747
728 public static readonly LSLInteger RCERR_UNKNOWN = -1; 748 public static readonly LSLInteger RCERR_UNKNOWN = -1;
729 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 749 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
730 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3; 750 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
731 751
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index afa9ae0..b63773b 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();
@@ -430,11 +435,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
430 return m_OSSL_Functions.osParseJSON(JSON); 435 return m_OSSL_Functions.osParseJSON(JSON);
431 } 436 }
432 437
433 public Object osParseJSONNew(string JSON)
434 {
435 return m_OSSL_Functions.osParseJSONNew(JSON);
436 }
437
438 public void osMessageObject(key objectUUID,string message) 438 public void osMessageObject(key objectUUID,string message)
439 { 439 {
440 m_OSSL_Functions.osMessageObject(objectUUID,message); 440 m_OSSL_Functions.osMessageObject(objectUUID,message);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs
index 573a803..b1825ac 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.7.6.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs
index f6d5d41..342dbff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.7.6.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33[assembly: AssemblyFileVersion("1.0.0.0")]
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;
31using System.Reflection; 31using System.Reflection;
32using log4net; 32using log4net;
33using Tools; 33using Tools;
34
35using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
36 35
37namespace OpenSim.Region.ScriptEngine.Shared.CodeTools 36namespace 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..b71afe3 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 { " + 468using System.Collections.Generic;
459 String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + 469
460 @"public Script() { } " + 470namespace 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,
@@ -631,13 +662,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
631 { 662 {
632 string severity = CompErr.IsWarning ? "Warning" : "Error"; 663 string severity = CompErr.IsWarning ? "Warning" : "Error";
633 664
634 KeyValuePair<int, int> lslPos; 665 KeyValuePair<int, int> errorPos;
635 666
636 // Show 5 errors max, but check entire list for errors 667 // Show 5 errors max, but check entire list for errors
637 668
638 if (severity == "Error") 669 if (severity == "Error")
639 { 670 {
640 lslPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]); 671 // C# scripts will not have a linemap since theres no line translation involved.
672 if (!m_lineMaps.ContainsKey(assembly))
673 errorPos = new KeyValuePair<int, int>(CompErr.Line, CompErr.Column);
674 else
675 errorPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]);
676
641 string text = CompErr.ErrorText; 677 string text = CompErr.ErrorText;
642 678
643 // Use LSL type names 679 // Use LSL type names
@@ -647,7 +683,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
647 // The Second Life viewer's script editor begins 683 // The Second Life viewer's script editor begins
648 // countingn lines and columns at 0, so we subtract 1. 684 // countingn lines and columns at 0, so we subtract 1.
649 errtext += String.Format("({0},{1}): {4} {2}: {3}\n", 685 errtext += String.Format("({0},{1}): {4} {2}: {3}\n",
650 lslPos.Key - 1, lslPos.Value - 1, 686 errorPos.Key - 1, errorPos.Value - 1,
651 CompErr.ErrorNumber, text, severity); 687 CompErr.ErrorNumber, text, severity);
652 hadErrors = true; 688 hadErrors = true;
653 } 689 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs
index c65caa8..5b5c4fd 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.7.6.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
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/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs
index 470e1a1..48964b6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.7.6.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 771db0c..26850c4 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(timeout))
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(Timeout.Infinite))
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..ac822c6
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
@@ -0,0 +1,513 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Threading;
31using Nini.Config;
32using NUnit.Framework;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Region.CoreModules.Scripting.WorldComm;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.ScriptEngine.XEngine;
39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41
42namespace 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@"
369integer i = 0;
370
371ufn1()
372{
373 llSay(0, ""Iter ufn1() "" + (string)i++);
374 ufn1();
375}
376
377default
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
447 // Wait for the script to start the event before we try stopping it.
448 m_chatEvent.WaitOne(60000);
449
450 if (m_osChatMessageReceived == null)
451 Assert.Fail("Script did not start");
452 else
453 Assert.That(m_chatMessagesReceived, Is.EqualTo(2));
454
455 bool running;
456 TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
457 Assert.That(
458 SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True);
459 Assert.That(running, Is.True);
460 }
461
462 private void TestStop(string script)
463 {
464 // In these tests we're only interested in the first message to confirm that the script has started.
465 m_chatMessagesThreshold = 1;
466
467 UUID userId = TestHelpers.ParseTail(0x1);
468// UUID objectId = TestHelpers.ParseTail(0x100);
469// UUID itemId = TestHelpers.ParseTail(0x3);
470 string itemName = "TestStop";
471
472 SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId);
473 TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
474
475 // Wait for the script to start the event before we try stopping it.
476 m_chatEvent.WaitOne(60000);
477
478 if (m_osChatMessageReceived != null)
479 Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message);
480 else
481 Assert.Fail("Script did not start");
482
483 // FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script
484 // executes llSay() but has not started the next statement before we try to stop it.
485 Thread.Sleep(1000);
486
487 // We need a way of carrying on if StopScript() fail, since it won't return if the script isn't actually
488 // stopped. This kind of multi-threading is far from ideal in a regression test.
489 new Thread(() => { m_xEngine.StopScript(rezzedItem.ItemID); m_stoppedEvent.Set(); }).Start();
490
491 if (!m_stoppedEvent.WaitOne(30000))
492 Assert.Fail("Script did not co-operatively stop.");
493
494 bool running;
495 TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
496 Assert.That(
497 SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True);
498 Assert.That(running, Is.False);
499 }
500
501 private void OnChatFromWorld(object sender, OSChatMessage oscm)
502 {
503 Console.WriteLine("Got chat [{0}]", oscm.Message);
504 m_osChatMessageReceived = oscm;
505
506 if (++m_chatMessagesReceived >= m_chatMessagesThreshold)
507 {
508 m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
509 m_chatEvent.Set();
510 }
511 }
512 }
513} \ 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..b524a18 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -512,7 +512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
512 else if (o is LSL_Types.LSLFloat) 512 else if (o is LSL_Types.LSLFloat)
513 size += 8; 513 size += 8;
514 else if (o is LSL_Types.LSLString) 514 else if (o is LSL_Types.LSLString)
515 size += ((LSL_Types.LSLString)o).m_string.Length; 515 size += ((LSL_Types.LSLString)o).m_string == null ? 0 : ((LSL_Types.LSLString)o).m_string.Length;
516 else if (o is LSL_Types.key) 516 else if (o is LSL_Types.key)
517 size += ((LSL_Types.key)o).value.Length; 517 size += ((LSL_Types.key)o).value.Length;
518 else if (o is LSL_Types.Vector3) 518 else if (o is LSL_Types.Vector3)
@@ -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/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs
index e6e8777..d08b0a6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.7.6.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs
new file mode 100644
index 0000000..ab44e38
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs
@@ -0,0 +1,249 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Net;
32using System.Reflection;
33using System.Text;
34using log4net;
35using Nini.Config;
36using NUnit.Framework;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Servers;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Region.CoreModules.Scripting.LSLHttp;
42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.ScriptEngine.Shared;
44using OpenSim.Region.ScriptEngine.Shared.Api;
45using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49
50namespace OpenSim.Region.ScriptEngine.Shared.Tests
51{
52 /// <summary>
53 /// Tests for HTTP related functions in LSL
54 /// </summary>
55 [TestFixture]
56 public class LSL_ApiHttpTests : OpenSimTestCase
57 {
58 private Scene m_scene;
59 private MockScriptEngine m_engine;
60 private UrlModule m_urlModule;
61
62 private TaskInventoryItem m_scriptItem;
63 private LSL_Api m_lslApi;
64
65 [TestFixtureSetUp]
66 public void TestFixtureSetUp()
67 {
68 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
69 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
70 }
71
72 [TestFixtureTearDown]
73 public void TestFixureTearDown()
74 {
75 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
76 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
77 // tests really shouldn't).
78 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
79 }
80
81 [SetUp]
82 public override void SetUp()
83 {
84 base.SetUp();
85
86 // This is an unfortunate bit of clean up we have to do because MainServer manages things through static
87 // variables and the VM is not restarted between tests.
88 uint port = 9999;
89 MainServer.RemoveHttpServer(port);
90
91 BaseHttpServer server = new BaseHttpServer(port, false, 0, "");
92 MainServer.AddHttpServer(server);
93 MainServer.Instance = server;
94
95 server.Start();
96
97 m_engine = new MockScriptEngine();
98 m_urlModule = new UrlModule();
99
100 m_scene = new SceneHelpers().SetupScene();
101 SceneHelpers.SetupSceneModules(m_scene, new IniConfigSource(), m_engine, m_urlModule);
102
103 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
104 m_scriptItem = TaskInventoryHelpers.AddScript(m_scene, so.RootPart);
105
106 // This is disconnected from the actual script - the mock engine does not set up any LSL_Api atm.
107 // Possibly this could be done and we could obtain it directly from the MockScriptEngine.
108 m_lslApi = new LSL_Api();
109 m_lslApi.Initialize(m_engine, so.RootPart, m_scriptItem, null);
110 }
111
112 [TearDown]
113 public void TearDown()
114 {
115 MainServer.Instance.Stop();
116 }
117
118 [Test]
119 public void TestLlReleaseUrl()
120 {
121 TestHelpers.InMethod();
122
123 m_lslApi.llRequestURL();
124 string returnedUri = m_engine.PostedEvents[m_scriptItem.ItemID][0].Params[2].ToString();
125
126 {
127 // Check that the initial number of URLs is correct
128 Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
129 }
130
131 {
132 // Check releasing a non-url
133 m_lslApi.llReleaseURL("GARBAGE");
134 Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
135 }
136
137 {
138 // Check releasing a non-existing url
139 m_lslApi.llReleaseURL("http://example.com");
140 Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
141 }
142
143 {
144 // Check URL release
145 m_lslApi.llReleaseURL(returnedUri);
146 Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls));
147
148 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri);
149
150 bool gotExpectedException = false;
151
152 try
153 {
154 using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
155 {}
156 }
157 catch (WebException e)
158 {
159 using (HttpWebResponse response = (HttpWebResponse)e.Response)
160 gotExpectedException = response.StatusCode == HttpStatusCode.NotFound;
161 }
162
163 Assert.That(gotExpectedException, Is.True);
164 }
165
166 {
167 // Check releasing the same URL again
168 m_lslApi.llReleaseURL(returnedUri);
169 Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls));
170 }
171 }
172
173 [Test]
174 public void TestLlRequestUrl()
175 {
176 TestHelpers.InMethod();
177
178 string requestId = m_lslApi.llRequestURL();
179 Assert.That(requestId, Is.Not.EqualTo(UUID.Zero.ToString()));
180 string returnedUri;
181
182 {
183 // Check that URL is correctly set up
184 Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
185
186 Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID));
187
188 List<EventParams> events = m_engine.PostedEvents[m_scriptItem.ItemID];
189 Assert.That(events.Count, Is.EqualTo(1));
190 EventParams eventParams = events[0];
191 Assert.That(eventParams.EventName, Is.EqualTo("http_request"));
192
193 UUID returnKey;
194 string rawReturnKey = eventParams.Params[0].ToString();
195 string method = eventParams.Params[1].ToString();
196 returnedUri = eventParams.Params[2].ToString();
197
198 Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True);
199 Assert.That(method, Is.EqualTo(ScriptBaseClass.URL_REQUEST_GRANTED));
200 Assert.That(Uri.IsWellFormedUriString(returnedUri, UriKind.Absolute), Is.True);
201 }
202
203 {
204 // Check that request to URL works.
205 string testResponse = "Hello World";
206
207 m_engine.ClearPostedEvents();
208 m_engine.PostEventHook
209 += (itemId, evp) => m_lslApi.llHTTPResponse(evp.Params[0].ToString(), 200, testResponse);
210
211// Console.WriteLine("Trying {0}", returnedUri);
212
213 AssertHttpResponse(returnedUri, testResponse);
214
215 Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID));
216
217 List<EventParams> events = m_engine.PostedEvents[m_scriptItem.ItemID];
218 Assert.That(events.Count, Is.EqualTo(1));
219 EventParams eventParams = events[0];
220 Assert.That(eventParams.EventName, Is.EqualTo("http_request"));
221
222 UUID returnKey;
223 string rawReturnKey = eventParams.Params[0].ToString();
224 string method = eventParams.Params[1].ToString();
225 string body = eventParams.Params[2].ToString();
226
227 Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True);
228 Assert.That(method, Is.EqualTo("GET"));
229 Assert.That(body, Is.EqualTo(""));
230 }
231 }
232
233 private void AssertHttpResponse(string uri, string expectedResponse)
234 {
235 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
236
237 using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
238 {
239 using (Stream stream = webResponse.GetResponseStream())
240 {
241 using (StreamReader reader = new StreamReader(stream))
242 {
243 Assert.That(reader.ReadToEnd(), Is.EqualTo(expectedResponse));
244 }
245 }
246 }
247 }
248 }
249} \ No newline at end of file
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;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.ScriptEngine.Shared; 42using OpenSim.Region.ScriptEngine.Shared;
43using OpenSim.Region.ScriptEngine.Shared.Api; 43using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.Instance;
44using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 46using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock; 47using 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..ac9f93b 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;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.ScriptEngine.Shared; 42using OpenSim.Region.ScriptEngine.Shared;
43using OpenSim.Region.ScriptEngine.Shared.Api; 43using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.Instance;
44using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 45using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
45using OpenSim.Services.Interfaces; 46using OpenSim.Services.Interfaces;
46using OpenSim.Tests.Common; 47using 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");
@@ -90,7 +93,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
90 // FIXME: This should really be a script item (with accompanying script) 93 // FIXME: This should really be a script item (with accompanying script)
91 TaskInventoryItem grp1Item 94 TaskInventoryItem grp1Item
92 = TaskInventoryHelpers.AddNotecard( 95 = TaskInventoryHelpers.AddNotecard(
93 m_scene, grp1.RootPart, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); 96 m_scene, grp1.RootPart, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900), "Hello World!");
94 grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 97 grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
95 98
96 SceneObjectGroup grp2 = SceneHelpers.CreateSceneObject(2, ownerId, "grp2-", 0x20); 99 SceneObjectGroup grp2 = SceneHelpers.CreateSceneObject(2, ownerId, "grp2-", 0x20);
@@ -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
@@ -124,12 +127,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
124 // FIXME: This should really be a script item (with accompanying script) 127 // FIXME: This should really be a script item (with accompanying script)
125 TaskInventoryItem grp1Item 128 TaskInventoryItem grp1Item
126 = TaskInventoryHelpers.AddNotecard( 129 = TaskInventoryHelpers.AddNotecard(
127 m_scene, grp1.RootPart, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900)); 130 m_scene, grp1.RootPart, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900), "Hello World!");
128 131
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;
34using OpenSim.Region.Framework.Scenes; 34using OpenSim.Region.Framework.Scenes;
35using Nini.Config; 35using Nini.Config;
36using OpenSim.Region.ScriptEngine.Shared.Api; 36using OpenSim.Region.ScriptEngine.Shared.Api;
37using OpenSim.Region.ScriptEngine.Shared.Instance;
37using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 38using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
38using OpenMetaverse; 39using OpenMetaverse;
39using OpenSim.Tests.Common.Mock; 40using OpenSim.Tests.Common.Mock;
@@ -46,13 +47,15 @@ using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
46namespace OpenSim.Region.ScriptEngine.Shared.Tests 47namespace 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_ApiNotecardTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs
new file mode 100644
index 0000000..c92bcdb
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs
@@ -0,0 +1,270 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Net;
5using System.Reflection;
6using System.Text;
7using log4net;
8using Nini.Config;
9using NUnit.Framework;
10using OpenMetaverse;
11using OpenSim.Framework;
12using OpenSim.Framework.Servers;
13using OpenSim.Framework.Servers.HttpServer;
14using OpenSim.Region.CoreModules.Scripting.LSLHttp;
15using OpenSim.Region.Framework.Scenes;
16using OpenSim.Region.ScriptEngine.Shared;
17using OpenSim.Region.ScriptEngine.Shared.Api;
18using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
19using OpenSim.Services.Interfaces;
20using OpenSim.Tests.Common;
21using OpenSim.Tests.Common.Mock;
22
23namespace OpenSim.Region.ScriptEngine.Shared.Tests
24{
25 /// <summary>
26 /// Tests for notecard related functions in LSL
27 /// </summary>
28 [TestFixture]
29 public class LSL_ApiNotecardTests : OpenSimTestCase
30 {
31 private Scene m_scene;
32 private MockScriptEngine m_engine;
33
34 private SceneObjectGroup m_so;
35 private TaskInventoryItem m_scriptItem;
36 private LSL_Api m_lslApi;
37
38 [TestFixtureSetUp]
39 public void TestFixtureSetUp()
40 {
41 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
42 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
43 }
44
45 [TestFixtureTearDown]
46 public void TestFixureTearDown()
47 {
48 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
49 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
50 // tests really shouldn't).
51 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
52 }
53
54 [SetUp]
55 public override void SetUp()
56 {
57 base.SetUp();
58
59 m_engine = new MockScriptEngine();
60
61 m_scene = new SceneHelpers().SetupScene();
62 SceneHelpers.SetupSceneModules(m_scene, new IniConfigSource(), m_engine);
63
64 m_so = SceneHelpers.AddSceneObject(m_scene);
65 m_scriptItem = TaskInventoryHelpers.AddScript(m_scene, m_so.RootPart);
66
67 // This is disconnected from the actual script - the mock engine does not set up any LSL_Api atm.
68 // Possibly this could be done and we could obtain it directly from the MockScriptEngine.
69 m_lslApi = new LSL_Api();
70 m_lslApi.Initialize(m_engine, m_so.RootPart, m_scriptItem, null);
71 }
72
73 [Test]
74 public void TestLlGetNotecardLine()
75 {
76 TestHelpers.InMethod();
77
78 string[] ncLines = { "One", "Two", "Three" };
79
80 TaskInventoryItem ncItem
81 = TaskInventoryHelpers.AddNotecard(m_scene, m_so.RootPart, "nc", "1", "10", string.Join("\n", ncLines));
82
83 AssertValidNotecardLine(ncItem.Name, 0, ncLines[0]);
84 AssertValidNotecardLine(ncItem.Name, 2, ncLines[2]);
85 AssertValidNotecardLine(ncItem.Name, 3, ScriptBaseClass.EOF);
86 AssertValidNotecardLine(ncItem.Name, 4, ScriptBaseClass.EOF);
87
88 // XXX: Is this correct or do we really expect no dataserver event to fire at all?
89 AssertValidNotecardLine(ncItem.Name, -1, "");
90 AssertValidNotecardLine(ncItem.Name, -2, "");
91 }
92
93 [Test]
94 public void TestLlGetNotecardLine_NoNotecard()
95 {
96 TestHelpers.InMethod();
97
98 AssertInValidNotecardLine("nc", 0);
99 }
100
101 [Test]
102 public void TestLlGetNotecardLine_NotANotecard()
103 {
104 TestHelpers.InMethod();
105
106 TaskInventoryItem ncItem = TaskInventoryHelpers.AddScript(m_scene, m_so.RootPart, "nc1", "Not important");
107
108 AssertInValidNotecardLine(ncItem.Name, 0);
109 }
110
111 private void AssertValidNotecardLine(string ncName, int lineNumber, string assertLine)
112 {
113 string key = m_lslApi.llGetNotecardLine(ncName, lineNumber);
114 Assert.That(key, Is.Not.EqualTo(UUID.Zero.ToString()));
115
116 Assert.That(m_engine.PostedEvents.Count, Is.EqualTo(1));
117 Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID));
118
119 List<EventParams> events = m_engine.PostedEvents[m_scriptItem.ItemID];
120 Assert.That(events.Count, Is.EqualTo(1));
121 EventParams eventParams = events[0];
122
123 Assert.That(eventParams.EventName, Is.EqualTo("dataserver"));
124 Assert.That(eventParams.Params[0].ToString(), Is.EqualTo(key));
125 Assert.That(eventParams.Params[1].ToString(), Is.EqualTo(assertLine));
126
127 m_engine.ClearPostedEvents();
128 }
129
130 private void AssertInValidNotecardLine(string ncName, int lineNumber)
131 {
132 string key = m_lslApi.llGetNotecardLine(ncName, lineNumber);
133 Assert.That(key, Is.EqualTo(UUID.Zero.ToString()));
134
135 Assert.That(m_engine.PostedEvents.Count, Is.EqualTo(0));
136 }
137
138// [Test]
139// public void TestLlReleaseUrl()
140// {
141// TestHelpers.InMethod();
142//
143// m_lslApi.llRequestURL();
144// string returnedUri = m_engine.PostedEvents[m_scriptItem.ItemID][0].Params[2].ToString();
145//
146// {
147// // Check that the initial number of URLs is correct
148// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
149// }
150//
151// {
152// // Check releasing a non-url
153// m_lslApi.llReleaseURL("GARBAGE");
154// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
155// }
156//
157// {
158// // Check releasing a non-existing url
159// m_lslApi.llReleaseURL("http://example.com");
160// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
161// }
162//
163// {
164// // Check URL release
165// m_lslApi.llReleaseURL(returnedUri);
166// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls));
167//
168// HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri);
169//
170// bool gotExpectedException = false;
171//
172// try
173// {
174// using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
175// {}
176// }
177// catch (WebException e)
178// {
179// using (HttpWebResponse response = (HttpWebResponse)e.Response)
180// gotExpectedException = response.StatusCode == HttpStatusCode.NotFound;
181// }
182//
183// Assert.That(gotExpectedException, Is.True);
184// }
185//
186// {
187// // Check releasing the same URL again
188// m_lslApi.llReleaseURL(returnedUri);
189// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls));
190// }
191// }
192//
193// [Test]
194// public void TestLlRequestUrl()
195// {
196// TestHelpers.InMethod();
197//
198// string requestId = m_lslApi.llRequestURL();
199// Assert.That(requestId, Is.Not.EqualTo(UUID.Zero.ToString()));
200// string returnedUri;
201//
202// {
203// // Check that URL is correctly set up
204// Assert.That(m_lslApi.llGetFreeURLs().value, Is.EqualTo(m_urlModule.TotalUrls - 1));
205//
206// Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID));
207//
208// List<EventParams> events = m_engine.PostedEvents[m_scriptItem.ItemID];
209// Assert.That(events.Count, Is.EqualTo(1));
210// EventParams eventParams = events[0];
211// Assert.That(eventParams.EventName, Is.EqualTo("http_request"));
212//
213// UUID returnKey;
214// string rawReturnKey = eventParams.Params[0].ToString();
215// string method = eventParams.Params[1].ToString();
216// returnedUri = eventParams.Params[2].ToString();
217//
218// Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True);
219// Assert.That(method, Is.EqualTo(ScriptBaseClass.URL_REQUEST_GRANTED));
220// Assert.That(Uri.IsWellFormedUriString(returnedUri, UriKind.Absolute), Is.True);
221// }
222//
223// {
224// // Check that request to URL works.
225// string testResponse = "Hello World";
226//
227// m_engine.ClearPostedEvents();
228// m_engine.PostEventHook
229// += (itemId, evp) => m_lslApi.llHTTPResponse(evp.Params[0].ToString(), 200, testResponse);
230//
231//// Console.WriteLine("Trying {0}", returnedUri);
232// HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri);
233//
234// AssertHttpResponse(returnedUri, testResponse);
235//
236// Assert.That(m_engine.PostedEvents.ContainsKey(m_scriptItem.ItemID));
237//
238// List<EventParams> events = m_engine.PostedEvents[m_scriptItem.ItemID];
239// Assert.That(events.Count, Is.EqualTo(1));
240// EventParams eventParams = events[0];
241// Assert.That(eventParams.EventName, Is.EqualTo("http_request"));
242//
243// UUID returnKey;
244// string rawReturnKey = eventParams.Params[0].ToString();
245// string method = eventParams.Params[1].ToString();
246// string body = eventParams.Params[2].ToString();
247//
248// Assert.That(UUID.TryParse(rawReturnKey, out returnKey), Is.True);
249// Assert.That(method, Is.EqualTo("GET"));
250// Assert.That(body, Is.EqualTo(""));
251// }
252// }
253//
254// private void AssertHttpResponse(string uri, string expectedResponse)
255// {
256// HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
257//
258// using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
259// {
260// using (Stream stream = webResponse.GetResponseStream())
261// {
262// using (StreamReader reader = new StreamReader(stream))
263// {
264// Assert.That(reader.ReadToEnd(), Is.EqualTo(expectedResponse));
265// }
266// }
267// }
268// }
269 }
270} \ No newline at end of file
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;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34using Nini.Config; 34using Nini.Config;
35using OpenSim.Region.ScriptEngine.Shared.Api; 35using OpenSim.Region.ScriptEngine.Shared.Api;
36using OpenSim.Region.ScriptEngine.Shared.Instance;
36using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 37using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
37using OpenMetaverse; 38using OpenMetaverse;
38using System; 39using 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;
33namespace OpenSim.Region.ScriptEngine.Shared.Tests 33namespace 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;
33namespace OpenSim.Region.ScriptEngine.Shared.Tests 33namespace 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;
33namespace OpenSim.Region.ScriptEngine.Shared.Tests 33namespace 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;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.ScriptEngine.Shared; 42using OpenSim.Region.ScriptEngine.Shared;
43using OpenSim.Region.ScriptEngine.Shared.Api; 43using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.Instance;
44using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 46using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock; 47using 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..e422f5b 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;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.ScriptEngine.Shared; 42using OpenSim.Region.ScriptEngine.Shared;
43using OpenSim.Region.ScriptEngine.Shared.Api; 43using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.Instance;
44using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 46using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock; 47using 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,13 +145,13 @@ 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(
153 m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, TestHelpers.ParseTail(0x900)); 154 m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, TestHelpers.ParseTail(0x900), "Hello World!");
154 155
155 bool exceptionCaught = false; 156 bool exceptionCaught = false;
156 157
@@ -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..74f010e 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;
42using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.ScriptEngine.Shared; 43using OpenSim.Region.ScriptEngine.Shared;
44using OpenSim.Region.ScriptEngine.Shared.Api; 44using OpenSim.Region.ScriptEngine.Shared.Api;
45using OpenSim.Region.ScriptEngine.Shared.Instance;
45using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 46using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
46using OpenSim.Services.Interfaces; 47using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common; 48using 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
@@ -223,7 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
223 // Store an avatar with a different height from default in a notecard. 222 // Store an avatar with a different height from default in a notecard.
224 UUID userId = TestHelpers.ParseTail(0x1); 223 UUID userId = TestHelpers.ParseTail(0x1);
225 float firstHeight = 1.9f; 224 float firstHeight = 1.9f;
226 float secondHeight = 2.1f; 225// float secondHeight = 2.1f;
227 string firstAppearanceNcName = "appearanceNc1"; 226 string firstAppearanceNcName = "appearanceNc1";
228 string secondAppearanceNcName = "appearanceNc2"; 227 string secondAppearanceNcName = "appearanceNc2";
229 228
@@ -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
28using System;
29using System.Runtime.Remoting;
30using System.Runtime.Remoting.Lifetime;
31using System.Security.Permissions;
32using System.Threading;
33using System.Reflection;
34using System.Collections;
35using System.Collections.Generic;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
39
40namespace 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/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs
index bd26a8b..f0640da 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.7.6.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
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
28using System;
29using System.Collections.Generic;
30using OpenSim.Framework;
31using OpenSim.Framework.Console;
32using OpenSim.Region.ScriptEngine.Interfaces;
33using OpenSim.Region.ScriptEngine.Shared.Api;
34using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
35
36namespace 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;
31using System.Diagnostics; //for [DebuggerNonUserCode] 31using System.Diagnostics; //for [DebuggerNonUserCode]
32using System.Globalization; 32using System.Globalization;
33using System.IO; 33using System.IO;
34using System.Linq;
34using System.Reflection; 35using System.Reflection;
35using System.Security; 36using System.Security;
36using System.Security.Policy; 37using System.Security.Policy;
@@ -46,13 +47,14 @@ using OpenSim.Framework;
46using OpenSim.Framework.Console; 47using OpenSim.Framework.Console;
47using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Framework.Interfaces; 49using OpenSim.Region.Framework.Interfaces;
50using OpenSim.Region.ScriptEngine.Interfaces;
49using OpenSim.Region.ScriptEngine.Shared; 51using OpenSim.Region.ScriptEngine.Shared;
50using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
51using OpenSim.Region.ScriptEngine.Shared.CodeTools; 52using OpenSim.Region.ScriptEngine.Shared.CodeTools;
52using OpenSim.Region.ScriptEngine.Shared.Instance; 53using OpenSim.Region.ScriptEngine.Shared.Instance;
53using OpenSim.Region.ScriptEngine.Shared.Api; 54using OpenSim.Region.ScriptEngine.Shared.Api;
54using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 55using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
55using OpenSim.Region.ScriptEngine.Interfaces; 56using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
57using OpenSim.Region.ScriptEngine.XEngine.ScriptBase;
56using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; 58using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer;
57 59
58using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; 60using 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 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs b/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs
index 2ac5c31..8dd7677 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs
@@ -57,8 +57,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
57 wr.Abort(); 57 wr.Abort();
58 } 58 }
59 59
60 public bool Wait(TimeSpan t) 60 public bool Wait(int t)
61 { 61 {
62 // We use the integer version of WaitAll because the current version of SmartThreadPool has a bug with the
63 // TimeSpan version. The number of milliseconds in TimeSpan is an int64 so when STP casts it down to an
64 // int (32-bit) we can end up with bad values. This occurs on Windows though curious not on Mono 2.10.8
65 // (or very likely other versions of Mono at least up until 3.0.3).
62 return SmartThreadPool.WaitAll(new IWorkItemResult[] {wr}, t, false); 66 return SmartThreadPool.WaitAll(new IWorkItemResult[] {wr}, t, false);
63 } 67 }
64 } 68 }