diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Threading; | ||
29 | using OpenMetaverse; | 30 | using OpenMetaverse; |
30 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
31 | using OpenSim.Region.Framework.Scenes; | 32 | using OpenSim.Region.Framework.Scenes; |
33 | using OpenSim.Region.ScriptEngine.Shared; | ||
32 | 34 | ||
33 | namespace OpenSim.Region.ScriptEngine.Interfaces | 35 | namespace OpenSim.Region.ScriptEngine.Interfaces |
34 | { | 36 | { |
@@ -38,11 +40,12 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
38 | /// Initialize the API | 40 | /// Initialize the API |
39 | /// </summary> | 41 | /// </summary> |
40 | /// <remarks> | 42 | /// <remarks> |
41 | /// Each API has an identifier, which is used to load the | 43 | /// Each API has an identifier, which is used to load the proper runtime assembly at load time. |
42 | /// proper runtime assembly at load time. | 44 | /// <param name='scriptEngine'>/param> |
43 | /// <param name='engine'>/param> | 45 | /// <param name='host'>/param> |
44 | /// <param name='part'></param> | 46 | /// <param name='item'>/param> |
45 | /// <param name='item'></param> | 47 | /// <param name='coopSleepHandle'>/param> |
46 | void Initialize(IScriptEngine engine, SceneObjectPart part, TaskInventoryItem item); | 48 | void Initialize( |
49 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle); | ||
47 | } | 50 | } |
48 | } \ No newline at end of file | 51 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs index 17c2708..b8fdd01 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs | |||
@@ -25,16 +25,17 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using log4net; | ||
29 | using System; | 28 | using System; |
30 | using OpenSim.Region.ScriptEngine.Shared; | 29 | using System.Reflection; |
30 | using OpenSim.Framework; | ||
31 | using OpenSim.Region.Framework.Scenes; | 31 | using OpenSim.Region.Framework.Scenes; |
32 | using OpenSim.Region.Framework.Interfaces; | 32 | using OpenSim.Region.Framework.Interfaces; |
33 | using OpenMetaverse; | ||
34 | using Nini.Config; | ||
35 | using OpenSim.Region.ScriptEngine.Interfaces; | 33 | using OpenSim.Region.ScriptEngine.Interfaces; |
34 | using OpenSim.Region.ScriptEngine.Shared; | ||
36 | using Amib.Threading; | 35 | using Amib.Threading; |
37 | using OpenSim.Framework; | 36 | using log4net; |
37 | using Nini.Config; | ||
38 | using OpenMetaverse; | ||
38 | 39 | ||
39 | namespace OpenSim.Region.ScriptEngine.Interfaces | 40 | namespace OpenSim.Region.ScriptEngine.Interfaces |
40 | { | 41 | { |
@@ -76,6 +77,38 @@ namespace OpenSim.Region.ScriptEngine.Interfaces | |||
76 | IConfigSource ConfigSource { get; } | 77 | IConfigSource ConfigSource { get; } |
77 | string ScriptEngineName { get; } | 78 | string ScriptEngineName { get; } |
78 | string ScriptEnginePath { get; } | 79 | string ScriptEnginePath { get; } |
80 | |||
81 | /// <summary> | ||
82 | /// Return the name of the class that will be used for all running scripts. | ||
83 | /// </summary> | ||
84 | /// <remarks> | ||
85 | /// Each class goes in its own assembly so we don't need to otherwise distinguish the class name. | ||
86 | /// </remarks> | ||
87 | string ScriptClassName { get; } | ||
88 | |||
89 | /// <summary> | ||
90 | /// Return the name of the base class that will be used for all running scripts. | ||
91 | /// </summary> | ||
92 | string ScriptBaseClassName { get; } | ||
93 | |||
94 | /// <summary> | ||
95 | /// Assemblies that need to be referenced when compiling scripts. | ||
96 | /// </summary> | ||
97 | /// <remarks> | ||
98 | /// These are currently additional to those always referenced by the compiler, BUT THIS MAY CHANGE IN THE | ||
99 | /// FUTURE. | ||
100 | /// This can be null if there are no additional assemblies. | ||
101 | /// </remarks> | ||
102 | string[] ScriptReferencedAssemblies { get; } | ||
103 | |||
104 | /// <summary> | ||
105 | /// Parameters for the generated script's constructor. | ||
106 | /// </summary> | ||
107 | /// <remarks> | ||
108 | /// Can be null if there are no parameters | ||
109 | /// </remarks> | ||
110 | ParameterInfo[] ScriptBaseClassParameters { get; } | ||
111 | |||
79 | IScriptApi GetApi(UUID itemID, string name); | 112 | IScriptApi GetApi(UUID itemID, string name); |
80 | } | 113 | } |
81 | } | 114 | } |
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index b04f6b6..35ae44c 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | |||
@@ -28,9 +28,11 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Threading; | ||
31 | using OpenMetaverse; | 32 | using OpenMetaverse; |
32 | using log4net; | 33 | using log4net; |
33 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.Framework.Scenes; | ||
34 | using OpenSim.Region.ScriptEngine.Shared; | 36 | using OpenSim.Region.ScriptEngine.Shared; |
35 | using OpenSim.Region.ScriptEngine.Interfaces; | 37 | using OpenSim.Region.ScriptEngine.Interfaces; |
36 | 38 | ||
@@ -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 | ||
28 | using System; | 28 | using System; |
29 | using System.Threading; | ||
29 | using System.Reflection; | 30 | using System.Reflection; |
30 | using System.Collections; | 31 | using System.Collections; |
31 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
@@ -62,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
62 | internal TaskInventoryItem m_item; | 63 | internal TaskInventoryItem m_item; |
63 | internal bool m_CMFunctionsEnabled = false; | 64 | internal bool m_CMFunctionsEnabled = false; |
64 | 65 | ||
65 | public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) | 66 | public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) |
66 | { | 67 | { |
67 | m_ScriptEngine = ScriptEngine; | 68 | m_ScriptEngine = ScriptEngine; |
68 | m_host = host; | 69 | m_host = host; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 53c6e5c..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; | |||
48 | using OpenSim.Region.Framework.Scenes; | 48 | using OpenSim.Region.Framework.Scenes; |
49 | using OpenSim.Region.Framework.Scenes.Serialization; | 49 | using OpenSim.Region.Framework.Scenes.Serialization; |
50 | using OpenSim.Region.Framework.Scenes.Animation; | 50 | using OpenSim.Region.Framework.Scenes.Animation; |
51 | using OpenSim.Region.Framework.Scenes.Scripting; | ||
51 | using OpenSim.Region.Physics.Manager; | 52 | using OpenSim.Region.Physics.Manager; |
52 | using OpenSim.Region.ScriptEngine.Shared; | 53 | using OpenSim.Region.ScriptEngine.Shared; |
53 | using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; | 54 | using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; |
@@ -70,6 +71,8 @@ using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | |||
70 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | 71 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; |
71 | using System.Reflection; | 72 | using System.Reflection; |
72 | using Timer = System.Timers.Timer; | 73 | using Timer = System.Timers.Timer; |
74 | using System.Linq; | ||
75 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
73 | 76 | ||
74 | namespace OpenSim.Region.ScriptEngine.Shared.Api | 77 | namespace 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; | |||
30 | using System.Collections; | 30 | using System.Collections; |
31 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
32 | using System.Runtime.Remoting.Lifetime; | 32 | using System.Runtime.Remoting.Lifetime; |
33 | using System.Threading; | ||
33 | using OpenMetaverse; | 34 | using OpenMetaverse; |
34 | using Nini.Config; | 35 | using Nini.Config; |
35 | using OpenSim; | 36 | using OpenSim; |
@@ -61,9 +62,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
61 | internal bool m_LSFunctionsEnabled = false; | 62 | internal bool m_LSFunctionsEnabled = false; |
62 | internal IScriptModuleComms m_comms = null; | 63 | internal IScriptModuleComms m_comms = null; |
63 | 64 | ||
64 | public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) | 65 | public void Initialize( |
66 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) | ||
65 | { | 67 | { |
66 | m_ScriptEngine = ScriptEngine; | 68 | m_ScriptEngine = scriptEngine; |
67 | m_host = host; | 69 | m_host = host; |
68 | 70 | ||
69 | if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) | 71 | if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) |
@@ -92,10 +94,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
92 | get { return m_ScriptEngine.World; } | 94 | get { return m_ScriptEngine.World; } |
93 | } | 95 | } |
94 | 96 | ||
95 | // | 97 | /// <summary> |
96 | //Dumps an error message on the debug console. | 98 | /// Dumps an error message on the debug console. |
97 | // | 99 | /// </summary> |
98 | |||
99 | internal void LSShoutError(string message) | 100 | internal void LSShoutError(string message) |
100 | { | 101 | { |
101 | if (message.Length > 1023) | 102 | if (message.Length > 1023) |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 8f34833..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; | |||
30 | using System.Collections; | 30 | using System.Collections; |
31 | using System.Collections.Generic; | 31 | using System.Collections.Generic; |
32 | using System.Runtime.Remoting.Lifetime; | 32 | using System.Runtime.Remoting.Lifetime; |
33 | using System.Threading; | ||
34 | using log4net; | ||
33 | using OpenMetaverse; | 35 | using OpenMetaverse; |
34 | using Nini.Config; | 36 | using Nini.Config; |
35 | using OpenSim; | 37 | using 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; | |||
62 | using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; | 62 | using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; |
63 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | 63 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; |
64 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | 64 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; |
65 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
65 | 66 | ||
66 | namespace OpenSim.Region.ScriptEngine.Shared.Api | 67 | namespace 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; | |||
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using log4net; | 32 | using log4net; |
33 | using Tools; | 33 | using Tools; |
34 | |||
35 | using OpenSim.Region.Framework.Interfaces; | 34 | using OpenSim.Region.Framework.Interfaces; |
36 | 35 | ||
37 | namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | 36 | namespace OpenSim.Region.ScriptEngine.Shared.CodeTools |
@@ -49,6 +48,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
49 | private List<string> m_warnings = new List<string>(); | 48 | private List<string> m_warnings = new List<string>(); |
50 | private IScriptModuleComms m_comms = null; | 49 | private IScriptModuleComms m_comms = null; |
51 | 50 | ||
51 | private bool m_insertCoopTerminationChecks; | ||
52 | private static string m_coopTerminationCheck = "opensim_reserved_CheckForCoopTermination();"; | ||
53 | |||
54 | /// <summary> | ||
55 | /// Keep a record of the previous node when we do the parsing. | ||
56 | /// </summary> | ||
57 | /// <remarks> | ||
58 | /// We do this here because the parser generated by CSTools does not retain a reference to its parent node. | ||
59 | /// The previous node is required so we can correctly insert co-op termination checks when required. | ||
60 | /// </remarks> | ||
61 | // private SYMBOL m_previousNode; | ||
62 | |||
52 | /// <summary> | 63 | /// <summary> |
53 | /// Creates an 'empty' CSCodeGenerator instance. | 64 | /// Creates an 'empty' CSCodeGenerator instance. |
54 | /// </summary> | 65 | /// </summary> |
@@ -58,9 +69,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
58 | ResetCounters(); | 69 | ResetCounters(); |
59 | } | 70 | } |
60 | 71 | ||
61 | public CSCodeGenerator(IScriptModuleComms comms) | 72 | public CSCodeGenerator(IScriptModuleComms comms, bool insertCoopTerminationChecks) |
62 | { | 73 | { |
63 | m_comms = comms; | 74 | m_comms = comms; |
75 | m_insertCoopTerminationChecks = insertCoopTerminationChecks; | ||
64 | ResetCounters(); | 76 | ResetCounters(); |
65 | } | 77 | } |
66 | 78 | ||
@@ -155,7 +167,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
155 | // here's the payload | 167 | // here's the payload |
156 | retstr += GenerateLine(); | 168 | retstr += GenerateLine(); |
157 | foreach (SYMBOL s in m_astRoot.kids) | 169 | foreach (SYMBOL s in m_astRoot.kids) |
158 | retstr += GenerateNode(s); | 170 | retstr += GenerateNode(m_astRoot, s); |
159 | 171 | ||
160 | // close braces! | 172 | // close braces! |
161 | m_braceCount--; | 173 | m_braceCount--; |
@@ -165,7 +177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
165 | 177 | ||
166 | // Removes all carriage return characters which may be generated in Windows platform. Is there | 178 | // Removes all carriage return characters which may be generated in Windows platform. Is there |
167 | // cleaner way of doing this? | 179 | // cleaner way of doing this? |
168 | retstr=retstr.Replace("\r", ""); | 180 | retstr = retstr.Replace("\r", ""); |
169 | 181 | ||
170 | return retstr; | 182 | return retstr; |
171 | } | 183 | } |
@@ -191,9 +203,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
191 | /// Recursively called to generate each type of node. Will generate this | 203 | /// Recursively called to generate each type of node. Will generate this |
192 | /// node, then all it's children. | 204 | /// node, then all it's children. |
193 | /// </summary> | 205 | /// </summary> |
206 | /// <param name="previousSymbol">The parent node.</param> | ||
194 | /// <param name="s">The current node to generate code for.</param> | 207 | /// <param name="s">The current node to generate code for.</param> |
195 | /// <returns>String containing C# code for SYMBOL s.</returns> | 208 | /// <returns>String containing C# code for SYMBOL s.</returns> |
196 | private string GenerateNode(SYMBOL s) | 209 | private string GenerateNode(SYMBOL previousSymbol, SYMBOL s) |
197 | { | 210 | { |
198 | string retstr = String.Empty; | 211 | string retstr = String.Empty; |
199 | 212 | ||
@@ -207,11 +220,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
207 | else if (s is State) | 220 | else if (s is State) |
208 | retstr += GenerateState((State) s); | 221 | retstr += GenerateState((State) s); |
209 | else if (s is CompoundStatement) | 222 | else if (s is CompoundStatement) |
210 | retstr += GenerateCompoundStatement((CompoundStatement) s); | 223 | retstr += GenerateCompoundStatement(previousSymbol, (CompoundStatement) s); |
211 | else if (s is Declaration) | 224 | else if (s is Declaration) |
212 | retstr += GenerateDeclaration((Declaration) s); | 225 | retstr += GenerateDeclaration((Declaration) s); |
213 | else if (s is Statement) | 226 | else if (s is Statement) |
214 | retstr += GenerateStatement((Statement) s); | 227 | retstr += GenerateStatement(previousSymbol, (Statement) s); |
215 | else if (s is ReturnStatement) | 228 | else if (s is ReturnStatement) |
216 | retstr += GenerateReturnStatement((ReturnStatement) s); | 229 | retstr += GenerateReturnStatement((ReturnStatement) s); |
217 | else if (s is JumpLabel) | 230 | else if (s is JumpLabel) |
@@ -261,7 +274,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
261 | else | 274 | else |
262 | { | 275 | { |
263 | foreach (SYMBOL kid in s.kids) | 276 | foreach (SYMBOL kid in s.kids) |
264 | retstr += GenerateNode(kid); | 277 | retstr += GenerateNode(s, kid); |
265 | } | 278 | } |
266 | 279 | ||
267 | return retstr; | 280 | return retstr; |
@@ -295,7 +308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
295 | retstr += GenerateLine(")"); | 308 | retstr += GenerateLine(")"); |
296 | 309 | ||
297 | foreach (SYMBOL kid in remainingKids) | 310 | foreach (SYMBOL kid in remainingKids) |
298 | retstr += GenerateNode(kid); | 311 | retstr += GenerateNode(gf, kid); |
299 | 312 | ||
300 | return retstr; | 313 | return retstr; |
301 | } | 314 | } |
@@ -312,7 +325,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
312 | foreach (SYMBOL s in gv.kids) | 325 | foreach (SYMBOL s in gv.kids) |
313 | { | 326 | { |
314 | retstr += Indent(); | 327 | retstr += Indent(); |
315 | retstr += GenerateNode(s); | 328 | retstr += GenerateNode(gv, s); |
316 | retstr += GenerateLine(";"); | 329 | retstr += GenerateLine(";"); |
317 | } | 330 | } |
318 | 331 | ||
@@ -365,7 +378,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
365 | retstr += GenerateLine(")"); | 378 | retstr += GenerateLine(")"); |
366 | 379 | ||
367 | foreach (SYMBOL kid in remainingKids) | 380 | foreach (SYMBOL kid in remainingKids) |
368 | retstr += GenerateNode(kid); | 381 | retstr += GenerateNode(se, kid); |
369 | 382 | ||
370 | return retstr; | 383 | return retstr; |
371 | } | 384 | } |
@@ -404,7 +417,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
404 | 417 | ||
405 | foreach (SYMBOL s in al.kids) | 418 | foreach (SYMBOL s in al.kids) |
406 | { | 419 | { |
407 | retstr += GenerateNode(s); | 420 | retstr += GenerateNode(al, s); |
408 | if (0 < comma--) | 421 | if (0 < comma--) |
409 | retstr += Generate(", "); | 422 | retstr += Generate(", "); |
410 | } | 423 | } |
@@ -417,7 +430,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
417 | /// </summary> | 430 | /// </summary> |
418 | /// <param name="cs">The CompoundStatement node.</param> | 431 | /// <param name="cs">The CompoundStatement node.</param> |
419 | /// <returns>String containing C# code for CompoundStatement cs.</returns> | 432 | /// <returns>String containing C# code for CompoundStatement cs.</returns> |
420 | private string GenerateCompoundStatement(CompoundStatement cs) | 433 | private string GenerateCompoundStatement(SYMBOL previousSymbol, CompoundStatement cs) |
421 | { | 434 | { |
422 | string retstr = String.Empty; | 435 | string retstr = String.Empty; |
423 | 436 | ||
@@ -425,8 +438,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
425 | retstr += GenerateIndentedLine("{"); | 438 | retstr += GenerateIndentedLine("{"); |
426 | m_braceCount++; | 439 | m_braceCount++; |
427 | 440 | ||
441 | if (m_insertCoopTerminationChecks) | ||
442 | { | ||
443 | // We have to check in event functions as well because the user can manually call these. | ||
444 | if (previousSymbol is GlobalFunctionDefinition | ||
445 | || previousSymbol is WhileStatement | ||
446 | || previousSymbol is DoWhileStatement | ||
447 | || previousSymbol is ForLoop | ||
448 | || previousSymbol is StateEvent) | ||
449 | retstr += GenerateIndentedLine(m_coopTerminationCheck); | ||
450 | } | ||
451 | |||
428 | foreach (SYMBOL kid in cs.kids) | 452 | foreach (SYMBOL kid in cs.kids) |
429 | retstr += GenerateNode(kid); | 453 | retstr += GenerateNode(cs, kid); |
430 | 454 | ||
431 | // closing brace | 455 | // closing brace |
432 | m_braceCount--; | 456 | m_braceCount--; |
@@ -450,10 +474,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
450 | /// </summary> | 474 | /// </summary> |
451 | /// <param name="s">The Statement node.</param> | 475 | /// <param name="s">The Statement node.</param> |
452 | /// <returns>String containing C# code for Statement s.</returns> | 476 | /// <returns>String containing C# code for Statement s.</returns> |
453 | private string GenerateStatement(Statement s) | 477 | private string GenerateStatement(SYMBOL previousSymbol, Statement s) |
454 | { | 478 | { |
455 | string retstr = String.Empty; | 479 | string retstr = String.Empty; |
456 | bool printSemicolon = true; | 480 | bool printSemicolon = true; |
481 | bool transformToBlock = false; | ||
482 | |||
483 | if (m_insertCoopTerminationChecks) | ||
484 | { | ||
485 | // A non-braced single line do while structure cannot contain multiple statements. | ||
486 | // So to insert the termination check we change this to a braced control structure instead. | ||
487 | if (previousSymbol is WhileStatement | ||
488 | || previousSymbol is DoWhileStatement | ||
489 | || previousSymbol is ForLoop) | ||
490 | { | ||
491 | transformToBlock = true; | ||
492 | |||
493 | // FIXME: This will be wrongly indented because the previous for/while/dowhile will have already indented. | ||
494 | retstr += GenerateIndentedLine("{"); | ||
495 | |||
496 | retstr += GenerateIndentedLine(m_coopTerminationCheck); | ||
497 | } | ||
498 | } | ||
457 | 499 | ||
458 | retstr += Indent(); | 500 | retstr += Indent(); |
459 | 501 | ||
@@ -466,12 +508,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
466 | // (MONO) error. | 508 | // (MONO) error. |
467 | if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count)) | 509 | if (!(s.kids.Top is IdentExpression && 1 == s.kids.Count)) |
468 | foreach (SYMBOL kid in s.kids) | 510 | foreach (SYMBOL kid in s.kids) |
469 | retstr += GenerateNode(kid); | 511 | retstr += GenerateNode(s, kid); |
470 | } | 512 | } |
471 | 513 | ||
472 | if (printSemicolon) | 514 | if (printSemicolon) |
473 | retstr += GenerateLine(";"); | 515 | retstr += GenerateLine(";"); |
474 | 516 | ||
517 | if (transformToBlock) | ||
518 | { | ||
519 | // FIXME: This will be wrongly indented because the for/while/dowhile is currently handling the unindent | ||
520 | retstr += GenerateIndentedLine("}"); | ||
521 | } | ||
522 | |||
475 | return retstr; | 523 | return retstr; |
476 | } | 524 | } |
477 | 525 | ||
@@ -487,10 +535,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
487 | List<string> identifiers = new List<string>(); | 535 | List<string> identifiers = new List<string>(); |
488 | checkForMultipleAssignments(identifiers, a); | 536 | checkForMultipleAssignments(identifiers, a); |
489 | 537 | ||
490 | retstr += GenerateNode((SYMBOL) a.kids.Pop()); | 538 | retstr += GenerateNode(a, (SYMBOL) a.kids.Pop()); |
491 | retstr += Generate(String.Format(" {0} ", a.AssignmentType), a); | 539 | retstr += Generate(String.Format(" {0} ", a.AssignmentType), a); |
492 | foreach (SYMBOL kid in a.kids) | 540 | foreach (SYMBOL kid in a.kids) |
493 | retstr += GenerateNode(kid); | 541 | retstr += GenerateNode(a, kid); |
494 | 542 | ||
495 | return retstr; | 543 | return retstr; |
496 | } | 544 | } |
@@ -563,7 +611,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
563 | retstr += Generate("return ", rs); | 611 | retstr += Generate("return ", rs); |
564 | 612 | ||
565 | foreach (SYMBOL kid in rs.kids) | 613 | foreach (SYMBOL kid in rs.kids) |
566 | retstr += GenerateNode(kid); | 614 | retstr += GenerateNode(rs, kid); |
567 | 615 | ||
568 | return retstr; | 616 | return retstr; |
569 | } | 617 | } |
@@ -575,7 +623,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
575 | /// <returns>String containing C# code for JumpLabel jl.</returns> | 623 | /// <returns>String containing C# code for JumpLabel jl.</returns> |
576 | private string GenerateJumpLabel(JumpLabel jl) | 624 | private string GenerateJumpLabel(JumpLabel jl) |
577 | { | 625 | { |
578 | return Generate(String.Format("{0}:", CheckName(jl.LabelName)), jl) + " NoOp();\n"; | 626 | string labelStatement; |
627 | |||
628 | if (m_insertCoopTerminationChecks) | ||
629 | labelStatement = m_coopTerminationCheck + "\n"; | ||
630 | else | ||
631 | labelStatement = "NoOp();\n"; | ||
632 | |||
633 | return Generate(String.Format("{0}: ", CheckName(jl.LabelName)), jl) + labelStatement; | ||
579 | } | 634 | } |
580 | 635 | ||
581 | /// <summary> | 636 | /// <summary> |
@@ -598,14 +653,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
598 | string retstr = String.Empty; | 653 | string retstr = String.Empty; |
599 | 654 | ||
600 | retstr += GenerateIndented("if (", ifs); | 655 | retstr += GenerateIndented("if (", ifs); |
601 | retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); | 656 | retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); |
602 | retstr += GenerateLine(")"); | 657 | retstr += GenerateLine(")"); |
603 | 658 | ||
604 | // CompoundStatement handles indentation itself but we need to do it | 659 | // CompoundStatement handles indentation itself but we need to do it |
605 | // otherwise. | 660 | // otherwise. |
606 | bool indentHere = ifs.kids.Top is Statement; | 661 | bool indentHere = ifs.kids.Top is Statement; |
607 | if (indentHere) m_braceCount++; | 662 | if (indentHere) m_braceCount++; |
608 | retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); | 663 | retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); |
609 | if (indentHere) m_braceCount--; | 664 | if (indentHere) m_braceCount--; |
610 | 665 | ||
611 | if (0 < ifs.kids.Count) // do it again for an else | 666 | if (0 < ifs.kids.Count) // do it again for an else |
@@ -614,7 +669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
614 | 669 | ||
615 | indentHere = ifs.kids.Top is Statement; | 670 | indentHere = ifs.kids.Top is Statement; |
616 | if (indentHere) m_braceCount++; | 671 | if (indentHere) m_braceCount++; |
617 | retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); | 672 | retstr += GenerateNode(ifs, (SYMBOL) ifs.kids.Pop()); |
618 | if (indentHere) m_braceCount--; | 673 | if (indentHere) m_braceCount--; |
619 | } | 674 | } |
620 | 675 | ||
@@ -641,14 +696,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
641 | string retstr = String.Empty; | 696 | string retstr = String.Empty; |
642 | 697 | ||
643 | retstr += GenerateIndented("while (", ws); | 698 | retstr += GenerateIndented("while (", ws); |
644 | retstr += GenerateNode((SYMBOL) ws.kids.Pop()); | 699 | retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop()); |
645 | retstr += GenerateLine(")"); | 700 | retstr += GenerateLine(")"); |
646 | 701 | ||
647 | // CompoundStatement handles indentation itself but we need to do it | 702 | // CompoundStatement handles indentation itself but we need to do it |
648 | // otherwise. | 703 | // otherwise. |
649 | bool indentHere = ws.kids.Top is Statement; | 704 | bool indentHere = ws.kids.Top is Statement; |
650 | if (indentHere) m_braceCount++; | 705 | if (indentHere) m_braceCount++; |
651 | retstr += GenerateNode((SYMBOL) ws.kids.Pop()); | 706 | retstr += GenerateNode(ws, (SYMBOL) ws.kids.Pop()); |
652 | if (indentHere) m_braceCount--; | 707 | if (indentHere) m_braceCount--; |
653 | 708 | ||
654 | return retstr; | 709 | return retstr; |
@@ -669,11 +724,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
669 | // otherwise. | 724 | // otherwise. |
670 | bool indentHere = dws.kids.Top is Statement; | 725 | bool indentHere = dws.kids.Top is Statement; |
671 | if (indentHere) m_braceCount++; | 726 | if (indentHere) m_braceCount++; |
672 | retstr += GenerateNode((SYMBOL) dws.kids.Pop()); | 727 | retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop()); |
673 | if (indentHere) m_braceCount--; | 728 | if (indentHere) m_braceCount--; |
674 | 729 | ||
675 | retstr += GenerateIndented("while (", dws); | 730 | retstr += GenerateIndented("while (", dws); |
676 | retstr += GenerateNode((SYMBOL) dws.kids.Pop()); | 731 | retstr += GenerateNode(dws, (SYMBOL) dws.kids.Pop()); |
677 | retstr += GenerateLine(");"); | 732 | retstr += GenerateLine(");"); |
678 | 733 | ||
679 | return retstr; | 734 | return retstr; |
@@ -702,7 +757,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
702 | retstr += Generate("; "); | 757 | retstr += Generate("; "); |
703 | // for (x = 0; x < 10; x++) | 758 | // for (x = 0; x < 10; x++) |
704 | // ^^^^^^ | 759 | // ^^^^^^ |
705 | retstr += GenerateNode((SYMBOL) fl.kids.Pop()); | 760 | retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop()); |
706 | retstr += Generate("; "); | 761 | retstr += Generate("; "); |
707 | // for (x = 0; x < 10; x++) | 762 | // for (x = 0; x < 10; x++) |
708 | // ^^^ | 763 | // ^^^ |
@@ -713,7 +768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
713 | // otherwise. | 768 | // otherwise. |
714 | bool indentHere = fl.kids.Top is Statement; | 769 | bool indentHere = fl.kids.Top is Statement; |
715 | if (indentHere) m_braceCount++; | 770 | if (indentHere) m_braceCount++; |
716 | retstr += GenerateNode((SYMBOL) fl.kids.Pop()); | 771 | retstr += GenerateNode(fl, (SYMBOL) fl.kids.Pop()); |
717 | if (indentHere) m_braceCount--; | 772 | if (indentHere) m_braceCount--; |
718 | 773 | ||
719 | return retstr; | 774 | return retstr; |
@@ -758,7 +813,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
758 | while (s is ParenthesisExpression) | 813 | while (s is ParenthesisExpression) |
759 | s = (SYMBOL)s.kids.Pop(); | 814 | s = (SYMBOL)s.kids.Pop(); |
760 | 815 | ||
761 | retstr += GenerateNode(s); | 816 | retstr += GenerateNode(fls, s); |
762 | if (0 < comma--) | 817 | if (0 < comma--) |
763 | retstr += Generate(", "); | 818 | retstr += Generate(", "); |
764 | } | 819 | } |
@@ -779,20 +834,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
779 | { | 834 | { |
780 | // special case handling for logical and/or, see Mantis 3174 | 835 | // special case handling for logical and/or, see Mantis 3174 |
781 | retstr += "((bool)("; | 836 | retstr += "((bool)("; |
782 | retstr += GenerateNode((SYMBOL)be.kids.Pop()); | 837 | retstr += GenerateNode(be, (SYMBOL)be.kids.Pop()); |
783 | retstr += "))"; | 838 | retstr += "))"; |
784 | retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0,1)), be); | 839 | retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol.Substring(0,1)), be); |
785 | retstr += "((bool)("; | 840 | retstr += "((bool)("; |
786 | foreach (SYMBOL kid in be.kids) | 841 | foreach (SYMBOL kid in be.kids) |
787 | retstr += GenerateNode(kid); | 842 | retstr += GenerateNode(be, kid); |
788 | retstr += "))"; | 843 | retstr += "))"; |
789 | } | 844 | } |
790 | else | 845 | else |
791 | { | 846 | { |
792 | retstr += GenerateNode((SYMBOL)be.kids.Pop()); | 847 | retstr += GenerateNode(be, (SYMBOL)be.kids.Pop()); |
793 | retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); | 848 | retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be); |
794 | foreach (SYMBOL kid in be.kids) | 849 | foreach (SYMBOL kid in be.kids) |
795 | retstr += GenerateNode(kid); | 850 | retstr += GenerateNode(be, kid); |
796 | } | 851 | } |
797 | 852 | ||
798 | return retstr; | 853 | return retstr; |
@@ -808,7 +863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
808 | string retstr = String.Empty; | 863 | string retstr = String.Empty; |
809 | 864 | ||
810 | retstr += Generate(ue.UnarySymbol, ue); | 865 | retstr += Generate(ue.UnarySymbol, ue); |
811 | retstr += GenerateNode((SYMBOL) ue.kids.Pop()); | 866 | retstr += GenerateNode(ue, (SYMBOL) ue.kids.Pop()); |
812 | 867 | ||
813 | return retstr; | 868 | return retstr; |
814 | } | 869 | } |
@@ -824,7 +879,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
824 | 879 | ||
825 | retstr += Generate("("); | 880 | retstr += Generate("("); |
826 | foreach (SYMBOL kid in pe.kids) | 881 | foreach (SYMBOL kid in pe.kids) |
827 | retstr += GenerateNode(kid); | 882 | retstr += GenerateNode(pe, kid); |
828 | retstr += Generate(")"); | 883 | retstr += Generate(")"); |
829 | 884 | ||
830 | return retstr; | 885 | return retstr; |
@@ -861,7 +916,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
861 | 916 | ||
862 | // we wrap all typecasted statements in parentheses | 917 | // we wrap all typecasted statements in parentheses |
863 | retstr += Generate(String.Format("({0}) (", te.TypecastType), te); | 918 | retstr += Generate(String.Format("({0}) (", te.TypecastType), te); |
864 | retstr += GenerateNode((SYMBOL) te.kids.Pop()); | 919 | retstr += GenerateNode(te, (SYMBOL) te.kids.Pop()); |
865 | retstr += Generate(")"); | 920 | retstr += Generate(")"); |
866 | 921 | ||
867 | return retstr; | 922 | return retstr; |
@@ -931,7 +986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
931 | } | 986 | } |
932 | 987 | ||
933 | foreach (SYMBOL kid in fc.kids) | 988 | foreach (SYMBOL kid in fc.kids) |
934 | retstr += GenerateNode(kid); | 989 | retstr += GenerateNode(fc, kid); |
935 | 990 | ||
936 | retstr += Generate(")"); | 991 | retstr += Generate(")"); |
937 | 992 | ||
@@ -980,11 +1035,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
980 | string retstr = String.Empty; | 1035 | string retstr = String.Empty; |
981 | 1036 | ||
982 | retstr += Generate(String.Format("new {0}(", vc.Type), vc); | 1037 | retstr += Generate(String.Format("new {0}(", vc.Type), vc); |
983 | retstr += GenerateNode((SYMBOL) vc.kids.Pop()); | 1038 | retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); |
984 | retstr += Generate(", "); | 1039 | retstr += Generate(", "); |
985 | retstr += GenerateNode((SYMBOL) vc.kids.Pop()); | 1040 | retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); |
986 | retstr += Generate(", "); | 1041 | retstr += Generate(", "); |
987 | retstr += GenerateNode((SYMBOL) vc.kids.Pop()); | 1042 | retstr += GenerateNode(vc, (SYMBOL) vc.kids.Pop()); |
988 | retstr += Generate(")"); | 1043 | retstr += Generate(")"); |
989 | 1044 | ||
990 | return retstr; | 1045 | return retstr; |
@@ -1000,13 +1055,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
1000 | string retstr = String.Empty; | 1055 | string retstr = String.Empty; |
1001 | 1056 | ||
1002 | retstr += Generate(String.Format("new {0}(", rc.Type), rc); | 1057 | retstr += Generate(String.Format("new {0}(", rc.Type), rc); |
1003 | retstr += GenerateNode((SYMBOL) rc.kids.Pop()); | 1058 | retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); |
1004 | retstr += Generate(", "); | 1059 | retstr += Generate(", "); |
1005 | retstr += GenerateNode((SYMBOL) rc.kids.Pop()); | 1060 | retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); |
1006 | retstr += Generate(", "); | 1061 | retstr += Generate(", "); |
1007 | retstr += GenerateNode((SYMBOL) rc.kids.Pop()); | 1062 | retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); |
1008 | retstr += Generate(", "); | 1063 | retstr += Generate(", "); |
1009 | retstr += GenerateNode((SYMBOL) rc.kids.Pop()); | 1064 | retstr += GenerateNode(rc, (SYMBOL) rc.kids.Pop()); |
1010 | retstr += Generate(")"); | 1065 | retstr += Generate(")"); |
1011 | 1066 | ||
1012 | return retstr; | 1067 | return retstr; |
@@ -1024,7 +1079,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
1024 | retstr += Generate(String.Format("new {0}(", lc.Type), lc); | 1079 | retstr += Generate(String.Format("new {0}(", lc.Type), lc); |
1025 | 1080 | ||
1026 | foreach (SYMBOL kid in lc.kids) | 1081 | foreach (SYMBOL kid in lc.kids) |
1027 | retstr += GenerateNode(kid); | 1082 | retstr += GenerateNode(lc, kid); |
1028 | 1083 | ||
1029 | retstr += Generate(")"); | 1084 | retstr += Generate(")"); |
1030 | 1085 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 03be2ab..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 { " + | 468 | using System.Collections.Generic; |
459 | String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + | 469 | |
460 | @"public Script() { } " + | 470 | namespace SecondLife |
461 | compileScript + | 471 | {{ |
462 | "} }\r\n"; | 472 | public class {0} : {1} |
473 | {{ | ||
474 | public {0}({2}) : base({3}) {{}} | ||
475 | {4} | ||
476 | }} | ||
477 | }}", | ||
478 | className, | ||
479 | baseClassName, | ||
480 | constructorParameters != null | ||
481 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.ToString())) | ||
482 | : "", | ||
483 | constructorParameters != null | ||
484 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.Name)) | ||
485 | : "", | ||
486 | compileScript); | ||
487 | |||
463 | return compileScript; | 488 | return compileScript; |
464 | } | 489 | } |
465 | 490 | ||
466 | private static string CreateYPCompilerScript(string compileScript) | 491 | private static string CreateYPCompilerScript(string compileScript, string className, string baseClassName) |
467 | { | 492 | { |
468 | compileScript = String.Empty + | 493 | compileScript = String.Empty + |
469 | "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + | 494 | "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + |
470 | "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + | 495 | "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + |
471 | String.Empty + "namespace SecondLife { " + | 496 | String.Empty + "namespace SecondLife { " + |
472 | String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + | 497 | String.Empty + "public class " + className + " : " + baseClassName + " { \r\n" + |
473 | //@"public Script() { } " + | 498 | //@"public Script() { } " + |
474 | @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + | 499 | @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + |
475 | @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + | 500 | @"public " + className + "() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + |
476 | |||
477 | compileScript + | 501 | compileScript + |
478 | "} }\r\n"; | 502 | "} }\r\n"; |
503 | |||
479 | return compileScript; | 504 | return compileScript; |
480 | } | 505 | } |
481 | 506 | ||
482 | private static string CreateVBCompilerScript(string compileScript) | 507 | private static string CreateVBCompilerScript(string compileScript, string className, string baseClassName) |
483 | { | 508 | { |
484 | compileScript = String.Empty + | 509 | compileScript = String.Empty + |
485 | "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + | 510 | "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + |
486 | String.Empty + "NameSpace SecondLife:" + | 511 | String.Empty + "NameSpace SecondLife:" + |
487 | String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass: " + | 512 | String.Empty + "Public Class " + className + ": Inherits " + baseClassName + |
488 | "\r\nPublic Sub New()\r\nEnd Sub: " + | 513 | "\r\nPublic Sub New()\r\nEnd Sub: " + |
489 | compileScript + | 514 | compileScript + |
490 | ":End Class :End Namespace\r\n"; | 515 | ":End Class :End Namespace\r\n"; |
516 | |||
491 | return compileScript; | 517 | return compileScript; |
492 | } | 518 | } |
493 | 519 | ||
@@ -549,6 +575,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
549 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | 575 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, |
550 | "OpenMetaverseTypes.dll")); | 576 | "OpenMetaverseTypes.dll")); |
551 | 577 | ||
578 | if (m_scriptEngine.ScriptReferencedAssemblies != null) | ||
579 | Array.ForEach<string>( | ||
580 | m_scriptEngine.ScriptReferencedAssemblies, | ||
581 | a => parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, a))); | ||
582 | |||
552 | if (lang == enumCompileType.yp) | 583 | if (lang == enumCompileType.yp) |
553 | { | 584 | { |
554 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | 585 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, |
@@ -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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Threading; | ||
31 | using Nini.Config; | ||
32 | using NUnit.Framework; | ||
33 | using OpenMetaverse; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Region.CoreModules.Scripting.WorldComm; | ||
36 | using OpenSim.Region.Framework.Scenes; | ||
37 | using OpenSim.Region.Framework.Interfaces; | ||
38 | using OpenSim.Region.ScriptEngine.XEngine; | ||
39 | using OpenSim.Tests.Common; | ||
40 | using OpenSim.Tests.Common.Mock; | ||
41 | |||
42 | namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests | ||
43 | { | ||
44 | /// <summary> | ||
45 | /// Test that co-operative script thread termination is working correctly. | ||
46 | /// </summary> | ||
47 | [TestFixture] | ||
48 | public class CoopTerminationTests : OpenSimTestCase | ||
49 | { | ||
50 | private TestScene m_scene; | ||
51 | private OpenSim.Region.ScriptEngine.XEngine.XEngine m_xEngine; | ||
52 | |||
53 | private AutoResetEvent m_chatEvent; | ||
54 | private AutoResetEvent m_stoppedEvent; | ||
55 | |||
56 | private OSChatMessage m_osChatMessageReceived; | ||
57 | |||
58 | /// <summary> | ||
59 | /// Number of chat messages received so far. Reset before each test. | ||
60 | /// </summary> | ||
61 | private int m_chatMessagesReceived; | ||
62 | |||
63 | /// <summary> | ||
64 | /// Number of chat messages expected. m_chatEvent is not fired until this number is reached or exceeded. | ||
65 | /// </summary> | ||
66 | private int m_chatMessagesThreshold; | ||
67 | |||
68 | [SetUp] | ||
69 | public void Init() | ||
70 | { | ||
71 | m_osChatMessageReceived = null; | ||
72 | m_chatMessagesReceived = 0; | ||
73 | m_chatMessagesThreshold = 0; | ||
74 | m_chatEvent = new AutoResetEvent(false); | ||
75 | m_stoppedEvent = new AutoResetEvent(false); | ||
76 | |||
77 | //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); | ||
78 | // Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); | ||
79 | m_xEngine = new OpenSim.Region.ScriptEngine.XEngine.XEngine(); | ||
80 | |||
81 | IniConfigSource configSource = new IniConfigSource(); | ||
82 | |||
83 | IConfig startupConfig = configSource.AddConfig("Startup"); | ||
84 | startupConfig.Set("DefaultScriptEngine", "XEngine"); | ||
85 | |||
86 | IConfig xEngineConfig = configSource.AddConfig("XEngine"); | ||
87 | xEngineConfig.Set("Enabled", "true"); | ||
88 | xEngineConfig.Set("StartDelay", "0"); | ||
89 | |||
90 | // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call | ||
91 | // to AssemblyResolver.OnAssemblyResolve fails. | ||
92 | xEngineConfig.Set("AppDomainLoading", "false"); | ||
93 | |||
94 | xEngineConfig.Set("ScriptStopStrategy", "co-op"); | ||
95 | |||
96 | // Make sure loops aren't actually being terminated by a script delay wait. | ||
97 | xEngineConfig.Set("ScriptDelayFactor", 0); | ||
98 | |||
99 | // This is really just set for debugging the test. | ||
100 | xEngineConfig.Set("WriteScriptSourceToDebugFile", true); | ||
101 | |||
102 | // Set to false if we need to debug test so the old scripts don't get wiped before each separate test | ||
103 | // xEngineConfig.Set("DeleteScriptsOnStartup", false); | ||
104 | |||
105 | // This is not currently used at all for co-op termination. Bumping up to demonstrate that co-op termination | ||
106 | // has an effect - without it tests will fail due to a 120 second wait for the event to finish. | ||
107 | xEngineConfig.Set("WaitForEventCompletionOnScriptStop", 120000); | ||
108 | |||
109 | m_scene = new SceneHelpers().SetupScene("My Test", TestHelpers.ParseTail(0x9999), 1000, 1000, configSource); | ||
110 | SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine); | ||
111 | m_scene.StartScripts(); | ||
112 | } | ||
113 | |||
114 | /// <summary> | ||
115 | /// Test co-operative termination on derez of an object containing a script with a long-running event. | ||
116 | /// </summary> | ||
117 | /// <remarks> | ||
118 | /// TODO: Actually compiling the script is incidental to this test. Really want a way to compile test scripts | ||
119 | /// within the build itself. | ||
120 | /// </remarks> | ||
121 | [Test] | ||
122 | public void TestStopOnLongSleep() | ||
123 | { | ||
124 | TestHelpers.InMethod(); | ||
125 | // TestHelpers.EnableLogging(); | ||
126 | |||
127 | string script = | ||
128 | @"default | ||
129 | { | ||
130 | state_entry() | ||
131 | { | ||
132 | llSay(0, ""Thin Lizzy""); | ||
133 | llSleep(60); | ||
134 | } | ||
135 | }"; | ||
136 | |||
137 | TestStop(script); | ||
138 | } | ||
139 | |||
140 | [Test] | ||
141 | public void TestNoStopOnSingleStatementForLoop() | ||
142 | { | ||
143 | TestHelpers.InMethod(); | ||
144 | // TestHelpers.EnableLogging(); | ||
145 | |||
146 | string script = | ||
147 | @"default | ||
148 | { | ||
149 | state_entry() | ||
150 | { | ||
151 | integer i = 0; | ||
152 | for (i = 0; i <= 1; i++) llSay(0, ""Iter "" + (string)i); | ||
153 | } | ||
154 | }"; | ||
155 | |||
156 | TestSingleStatementNoStop(script); | ||
157 | } | ||
158 | |||
159 | [Test] | ||
160 | public void TestStopOnLongSingleStatementForLoop() | ||
161 | { | ||
162 | TestHelpers.InMethod(); | ||
163 | // TestHelpers.EnableLogging(); | ||
164 | |||
165 | string script = | ||
166 | @"default | ||
167 | { | ||
168 | state_entry() | ||
169 | { | ||
170 | integer i = 0; | ||
171 | llSay(0, ""Thin Lizzy""); | ||
172 | |||
173 | for (i = 0; i < 2147483647; i++) llSay(0, ""Iter "" + (string)i); | ||
174 | } | ||
175 | }"; | ||
176 | |||
177 | TestStop(script); | ||
178 | } | ||
179 | |||
180 | [Test] | ||
181 | public void TestStopOnLongCompoundStatementForLoop() | ||
182 | { | ||
183 | TestHelpers.InMethod(); | ||
184 | // TestHelpers.EnableLogging(); | ||
185 | |||
186 | string script = | ||
187 | @"default | ||
188 | { | ||
189 | state_entry() | ||
190 | { | ||
191 | integer i = 0; | ||
192 | llSay(0, ""Thin Lizzy""); | ||
193 | |||
194 | for (i = 0; i < 2147483647; i++) | ||
195 | { | ||
196 | llSay(0, ""Iter "" + (string)i); | ||
197 | } | ||
198 | } | ||
199 | }"; | ||
200 | |||
201 | TestStop(script); | ||
202 | } | ||
203 | |||
204 | [Test] | ||
205 | public void TestNoStopOnSingleStatementWhileLoop() | ||
206 | { | ||
207 | TestHelpers.InMethod(); | ||
208 | // TestHelpers.EnableLogging(); | ||
209 | |||
210 | string script = | ||
211 | @"default | ||
212 | { | ||
213 | state_entry() | ||
214 | { | ||
215 | integer i = 0; | ||
216 | while (i < 2) llSay(0, ""Iter "" + (string)i++); | ||
217 | } | ||
218 | }"; | ||
219 | |||
220 | TestSingleStatementNoStop(script); | ||
221 | } | ||
222 | |||
223 | [Test] | ||
224 | public void TestStopOnLongSingleStatementWhileLoop() | ||
225 | { | ||
226 | TestHelpers.InMethod(); | ||
227 | // TestHelpers.EnableLogging(); | ||
228 | |||
229 | string script = | ||
230 | @"default | ||
231 | { | ||
232 | state_entry() | ||
233 | { | ||
234 | integer i = 0; | ||
235 | llSay(0, ""Thin Lizzy""); | ||
236 | |||
237 | while (1 == 1) | ||
238 | llSay(0, ""Iter "" + (string)i++); | ||
239 | } | ||
240 | }"; | ||
241 | |||
242 | TestStop(script); | ||
243 | } | ||
244 | |||
245 | [Test] | ||
246 | public void TestStopOnLongCompoundStatementWhileLoop() | ||
247 | { | ||
248 | TestHelpers.InMethod(); | ||
249 | // TestHelpers.EnableLogging(); | ||
250 | |||
251 | string script = | ||
252 | @"default | ||
253 | { | ||
254 | state_entry() | ||
255 | { | ||
256 | integer i = 0; | ||
257 | llSay(0, ""Thin Lizzy""); | ||
258 | |||
259 | while (1 == 1) | ||
260 | { | ||
261 | llSay(0, ""Iter "" + (string)i++); | ||
262 | } | ||
263 | } | ||
264 | }"; | ||
265 | |||
266 | TestStop(script); | ||
267 | } | ||
268 | |||
269 | [Test] | ||
270 | public void TestNoStopOnSingleStatementDoWhileLoop() | ||
271 | { | ||
272 | TestHelpers.InMethod(); | ||
273 | // TestHelpers.EnableLogging(); | ||
274 | |||
275 | string script = | ||
276 | @"default | ||
277 | { | ||
278 | state_entry() | ||
279 | { | ||
280 | integer i = 0; | ||
281 | |||
282 | do llSay(0, ""Iter "" + (string)i++); | ||
283 | while (i < 2); | ||
284 | } | ||
285 | }"; | ||
286 | |||
287 | TestSingleStatementNoStop(script); | ||
288 | } | ||
289 | |||
290 | [Test] | ||
291 | public void TestStopOnLongSingleStatementDoWhileLoop() | ||
292 | { | ||
293 | TestHelpers.InMethod(); | ||
294 | // TestHelpers.EnableLogging(); | ||
295 | |||
296 | string script = | ||
297 | @"default | ||
298 | { | ||
299 | state_entry() | ||
300 | { | ||
301 | integer i = 0; | ||
302 | llSay(0, ""Thin Lizzy""); | ||
303 | |||
304 | do llSay(0, ""Iter "" + (string)i++); | ||
305 | while (1 == 1); | ||
306 | } | ||
307 | }"; | ||
308 | |||
309 | TestStop(script); | ||
310 | } | ||
311 | |||
312 | [Test] | ||
313 | public void TestStopOnLongCompoundStatementDoWhileLoop() | ||
314 | { | ||
315 | TestHelpers.InMethod(); | ||
316 | // TestHelpers.EnableLogging(); | ||
317 | |||
318 | string script = | ||
319 | @"default | ||
320 | { | ||
321 | state_entry() | ||
322 | { | ||
323 | integer i = 0; | ||
324 | llSay(0, ""Thin Lizzy""); | ||
325 | |||
326 | do | ||
327 | { | ||
328 | llSay(0, ""Iter "" + (string)i++); | ||
329 | } while (1 == 1); | ||
330 | } | ||
331 | }"; | ||
332 | |||
333 | TestStop(script); | ||
334 | } | ||
335 | |||
336 | [Test] | ||
337 | public void TestStopOnInfiniteJumpLoop() | ||
338 | { | ||
339 | TestHelpers.InMethod(); | ||
340 | // TestHelpers.EnableLogging(); | ||
341 | |||
342 | string script = | ||
343 | @"default | ||
344 | { | ||
345 | state_entry() | ||
346 | { | ||
347 | integer i = 0; | ||
348 | llSay(0, ""Thin Lizzy""); | ||
349 | |||
350 | @p1; | ||
351 | llSay(0, ""Iter "" + (string)i++); | ||
352 | jump p1; | ||
353 | } | ||
354 | }"; | ||
355 | |||
356 | TestStop(script); | ||
357 | } | ||
358 | |||
359 | // Disabling for now as these are not particularly useful tests (since they fail due to stack overflow before | ||
360 | // termination can even be tried. | ||
361 | // [Test] | ||
362 | public void TestStopOnInfiniteUserFunctionCallLoop() | ||
363 | { | ||
364 | TestHelpers.InMethod(); | ||
365 | // TestHelpers.EnableLogging(); | ||
366 | |||
367 | string script = | ||
368 | @" | ||
369 | integer i = 0; | ||
370 | |||
371 | ufn1() | ||
372 | { | ||
373 | llSay(0, ""Iter ufn1() "" + (string)i++); | ||
374 | ufn1(); | ||
375 | } | ||
376 | |||
377 | default | ||
378 | { | ||
379 | state_entry() | ||
380 | { | ||
381 | integer i = 0; | ||
382 | llSay(0, ""Thin Lizzy""); | ||
383 | |||
384 | ufn1(); | ||
385 | } | ||
386 | }"; | ||
387 | |||
388 | TestStop(script); | ||
389 | } | ||
390 | |||
391 | // Disabling for now as these are not particularly useful tests (since they fail due to stack overflow before | ||
392 | // termination can even be tried. | ||
393 | // [Test] | ||
394 | public void TestStopOnInfiniteManualEventCallLoop() | ||
395 | { | ||
396 | TestHelpers.InMethod(); | ||
397 | // TestHelpers.EnableLogging(); | ||
398 | |||
399 | string script = | ||
400 | @"default | ||
401 | { | ||
402 | state_entry() | ||
403 | { | ||
404 | integer i = 0; | ||
405 | llSay(0, ""Thin Lizzy""); | ||
406 | |||
407 | llSay(0, ""Iter"" + (string)i++); | ||
408 | default_event_state_entry(); | ||
409 | } | ||
410 | }"; | ||
411 | |||
412 | TestStop(script); | ||
413 | } | ||
414 | |||
415 | private SceneObjectPart CreateScript(string script, string itemName, UUID userId) | ||
416 | { | ||
417 | // UUID objectId = TestHelpers.ParseTail(0x100); | ||
418 | // UUID itemId = TestHelpers.ParseTail(0x3); | ||
419 | |||
420 | SceneObjectGroup so | ||
421 | = SceneHelpers.CreateSceneObject(1, userId, string.Format("Object for {0}", itemName), 0x100); | ||
422 | m_scene.AddNewSceneObject(so, true); | ||
423 | |||
424 | InventoryItemBase itemTemplate = new InventoryItemBase(); | ||
425 | // itemTemplate.ID = itemId; | ||
426 | itemTemplate.Name = itemName; | ||
427 | itemTemplate.Folder = so.UUID; | ||
428 | itemTemplate.InvType = (int)InventoryType.LSL; | ||
429 | |||
430 | m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; | ||
431 | |||
432 | return m_scene.RezNewScript(userId, itemTemplate, script); | ||
433 | } | ||
434 | |||
435 | private void TestSingleStatementNoStop(string script) | ||
436 | { | ||
437 | // In these tests we expect to see at least 2 chat messages to confirm that the loop is working properly. | ||
438 | m_chatMessagesThreshold = 2; | ||
439 | |||
440 | UUID userId = TestHelpers.ParseTail(0x1); | ||
441 | // UUID objectId = TestHelpers.ParseTail(0x100); | ||
442 | // UUID itemId = TestHelpers.ParseTail(0x3); | ||
443 | string itemName = "TestNoStop"; | ||
444 | |||
445 | SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId); | ||
446 | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.Net; | ||
32 | using System.Reflection; | ||
33 | using System.Text; | ||
34 | using log4net; | ||
35 | using Nini.Config; | ||
36 | using NUnit.Framework; | ||
37 | using OpenMetaverse; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Framework.Servers; | ||
40 | using OpenSim.Framework.Servers.HttpServer; | ||
41 | using OpenSim.Region.CoreModules.Scripting.LSLHttp; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | using OpenSim.Region.ScriptEngine.Shared; | ||
44 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
46 | using OpenSim.Services.Interfaces; | ||
47 | using OpenSim.Tests.Common; | ||
48 | using OpenSim.Tests.Common.Mock; | ||
49 | |||
50 | namespace 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; | |||
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.ScriptEngine.Shared; | 42 | using OpenSim.Region.ScriptEngine.Shared; |
43 | using OpenSim.Region.ScriptEngine.Shared.Api; | 43 | using OpenSim.Region.ScriptEngine.Shared.Api; |
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
44 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | 47 | using OpenSim.Tests.Common.Mock; |
@@ -51,14 +52,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
51 | /// Tests for inventory functions in LSL | 52 | /// Tests for inventory functions in LSL |
52 | /// </summary> | 53 | /// </summary> |
53 | [TestFixture] | 54 | [TestFixture] |
54 | public class LSL_ApiInventoryTests | 55 | public class LSL_ApiInventoryTests : OpenSimTestCase |
55 | { | 56 | { |
56 | protected Scene m_scene; | 57 | protected Scene m_scene; |
57 | protected XEngine.XEngine m_engine; | 58 | protected XEngine.XEngine m_engine; |
58 | 59 | ||
59 | [SetUp] | 60 | [SetUp] |
60 | public void SetUp() | 61 | public override void SetUp() |
61 | { | 62 | { |
63 | base.SetUp(); | ||
64 | |||
62 | IConfigSource initConfigSource = new IniConfigSource(); | 65 | IConfigSource initConfigSource = new IniConfigSource(); |
63 | IConfig config = initConfigSource.AddConfig("XEngine"); | 66 | IConfig config = initConfigSource.AddConfig("XEngine"); |
64 | config.Set("Enabled", "true"); | 67 | config.Set("Enabled", "true"); |
@@ -91,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
91 | TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); | 94 | TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); |
92 | 95 | ||
93 | LSL_Api api = new LSL_Api(); | 96 | LSL_Api api = new LSL_Api(); |
94 | api.Initialize(m_engine, so1.RootPart, null); | 97 | api.Initialize(m_engine, so1.RootPart, null, null); |
95 | 98 | ||
96 | // Create a second object | 99 | // Create a second object |
97 | SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); | 100 | SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); |
@@ -124,7 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
124 | SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); | 127 | SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); |
125 | m_scene.AddSceneObject(so1); | 128 | m_scene.AddSceneObject(so1); |
126 | LSL_Api api = new LSL_Api(); | 129 | LSL_Api api = new LSL_Api(); |
127 | api.Initialize(m_engine, so1.RootPart, null); | 130 | api.Initialize(m_engine, so1.RootPart, null, null); |
128 | 131 | ||
129 | // Create an object embedded inside the first | 132 | // Create an object embedded inside the first |
130 | UUID itemId = TestHelpers.ParseTail(0x20); | 133 | UUID itemId = TestHelpers.ParseTail(0x20); |
@@ -134,7 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
134 | SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); | 137 | SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); |
135 | m_scene.AddSceneObject(so2); | 138 | m_scene.AddSceneObject(so2); |
136 | LSL_Api api2 = new LSL_Api(); | 139 | LSL_Api api2 = new LSL_Api(); |
137 | api2.Initialize(m_engine, so2.RootPart, null); | 140 | api2.Initialize(m_engine, so2.RootPart, null, null); |
138 | 141 | ||
139 | // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** | 142 | // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** |
140 | api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); | 143 | api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index 2565ae7..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; | |||
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.ScriptEngine.Shared; | 42 | using OpenSim.Region.ScriptEngine.Shared; |
43 | using OpenSim.Region.ScriptEngine.Shared.Api; | 43 | using OpenSim.Region.ScriptEngine.Shared.Api; |
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
44 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
45 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
46 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
@@ -56,14 +57,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
56 | /// OpenSim.Region.Framework.Scenes.Tests.SceneObjectLinkingTests. | 57 | /// OpenSim.Region.Framework.Scenes.Tests.SceneObjectLinkingTests. |
57 | /// </remarks> | 58 | /// </remarks> |
58 | [TestFixture] | 59 | [TestFixture] |
59 | public class LSL_ApiLinkingTests | 60 | public class LSL_ApiLinkingTests : OpenSimTestCase |
60 | { | 61 | { |
61 | protected Scene m_scene; | 62 | protected Scene m_scene; |
62 | protected XEngine.XEngine m_engine; | 63 | protected XEngine.XEngine m_engine; |
63 | 64 | ||
64 | [SetUp] | 65 | [SetUp] |
65 | public void SetUp() | 66 | public override void SetUp() |
66 | { | 67 | { |
68 | base.SetUp(); | ||
69 | |||
67 | IConfigSource initConfigSource = new IniConfigSource(); | 70 | IConfigSource initConfigSource = new IniConfigSource(); |
68 | IConfig config = initConfigSource.AddConfig("XEngine"); | 71 | IConfig config = initConfigSource.AddConfig("XEngine"); |
69 | config.Set("Enabled", "true"); | 72 | config.Set("Enabled", "true"); |
@@ -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; | |||
34 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
35 | using Nini.Config; | 35 | using Nini.Config; |
36 | using OpenSim.Region.ScriptEngine.Shared.Api; | 36 | using OpenSim.Region.ScriptEngine.Shared.Api; |
37 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
37 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 38 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
38 | using OpenMetaverse; | 39 | using OpenMetaverse; |
39 | using OpenSim.Tests.Common.Mock; | 40 | using OpenSim.Tests.Common.Mock; |
@@ -46,13 +47,15 @@ using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | |||
46 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 47 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
47 | { | 48 | { |
48 | [TestFixture] | 49 | [TestFixture] |
49 | public class LSL_ApiListTests | 50 | public class LSL_ApiListTests : OpenSimTestCase |
50 | { | 51 | { |
51 | private LSL_Api m_lslApi; | 52 | private LSL_Api m_lslApi; |
52 | 53 | ||
53 | [SetUp] | 54 | [SetUp] |
54 | public void SetUp() | 55 | public override void SetUp() |
55 | { | 56 | { |
57 | base.SetUp(); | ||
58 | |||
56 | IConfigSource initConfigSource = new IniConfigSource(); | 59 | IConfigSource initConfigSource = new IniConfigSource(); |
57 | IConfig config = initConfigSource.AddConfig("XEngine"); | 60 | IConfig config = initConfigSource.AddConfig("XEngine"); |
58 | config.Set("Enabled", "true"); | 61 | config.Set("Enabled", "true"); |
@@ -65,7 +68,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
65 | engine.AddRegion(scene); | 68 | engine.AddRegion(scene); |
66 | 69 | ||
67 | m_lslApi = new LSL_Api(); | 70 | m_lslApi = new LSL_Api(); |
68 | m_lslApi.Initialize(engine, part, null); | 71 | m_lslApi.Initialize(engine, part, null, null); |
69 | } | 72 | } |
70 | 73 | ||
71 | [Test] | 74 | [Test] |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_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 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.IO; | ||
4 | using System.Net; | ||
5 | using System.Reflection; | ||
6 | using System.Text; | ||
7 | using log4net; | ||
8 | using Nini.Config; | ||
9 | using NUnit.Framework; | ||
10 | using OpenMetaverse; | ||
11 | using OpenSim.Framework; | ||
12 | using OpenSim.Framework.Servers; | ||
13 | using OpenSim.Framework.Servers.HttpServer; | ||
14 | using OpenSim.Region.CoreModules.Scripting.LSLHttp; | ||
15 | using OpenSim.Region.Framework.Scenes; | ||
16 | using OpenSim.Region.ScriptEngine.Shared; | ||
17 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
18 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
19 | using OpenSim.Services.Interfaces; | ||
20 | using OpenSim.Tests.Common; | ||
21 | using OpenSim.Tests.Common.Mock; | ||
22 | |||
23 | namespace 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; | |||
33 | using OpenSim.Region.Framework.Scenes; | 33 | using OpenSim.Region.Framework.Scenes; |
34 | using Nini.Config; | 34 | using Nini.Config; |
35 | using OpenSim.Region.ScriptEngine.Shared.Api; | 35 | using OpenSim.Region.ScriptEngine.Shared.Api; |
36 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
36 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 37 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
37 | using OpenMetaverse; | 38 | using OpenMetaverse; |
38 | using System; | 39 | using System; |
@@ -66,7 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
66 | engine.AddRegion(scene); | 67 | engine.AddRegion(scene); |
67 | 68 | ||
68 | m_lslApi = new LSL_Api(); | 69 | m_lslApi = new LSL_Api(); |
69 | m_lslApi.Initialize(engine, part, null); | 70 | m_lslApi.Initialize(engine, part, null, null); |
70 | } | 71 | } |
71 | 72 | ||
72 | [Test] | 73 | [Test] |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs index 3ed2562..c8c7f82 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs | |||
@@ -33,7 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; | |||
33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
34 | { | 34 | { |
35 | [TestFixture] | 35 | [TestFixture] |
36 | public class LSL_TypesTestLSLFloat | 36 | public class LSL_TypesTestLSLFloat : OpenSimTestCase |
37 | { | 37 | { |
38 | // Used for testing equality of two floats. | 38 | // Used for testing equality of two floats. |
39 | private double _lowPrecisionTolerance = 0.000001; | 39 | private double _lowPrecisionTolerance = 0.000001; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs index 8d1169a..c664108 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs | |||
@@ -33,7 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; | |||
33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
34 | { | 34 | { |
35 | [TestFixture] | 35 | [TestFixture] |
36 | public class LSL_TypesTestLSLInteger | 36 | public class LSL_TypesTestLSLInteger : OpenSimTestCase |
37 | { | 37 | { |
38 | private Dictionary<double, int> m_doubleIntSet; | 38 | private Dictionary<double, int> m_doubleIntSet; |
39 | private Dictionary<string, int> m_stringIntSet; | 39 | private Dictionary<string, int> m_stringIntSet; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs index c4ca1a8..8550f2d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs | |||
@@ -33,7 +33,7 @@ using OpenSim.Region.ScriptEngine.Shared; | |||
33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 33 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
34 | { | 34 | { |
35 | [TestFixture] | 35 | [TestFixture] |
36 | public class LSL_TypesTestLSLString | 36 | public class LSL_TypesTestLSLString : OpenSimTestCase |
37 | { | 37 | { |
38 | private Dictionary<double, string> m_doubleStringSet; | 38 | private Dictionary<double, string> m_doubleStringSet; |
39 | 39 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs index b81225f..71b88bc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs | |||
@@ -36,7 +36,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
36 | /// Tests the LSL_Types.list class. | 36 | /// Tests the LSL_Types.list class. |
37 | /// </summary> | 37 | /// </summary> |
38 | [TestFixture] | 38 | [TestFixture] |
39 | public class LSL_TypesTestList | 39 | public class LSL_TypesTestList : OpenSimTestCase |
40 | { | 40 | { |
41 | /// <summary> | 41 | /// <summary> |
42 | /// Tests concatenating a string to a list. | 42 | /// Tests concatenating a string to a list. |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs index ebf8001..0c838af 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs | |||
@@ -36,7 +36,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
36 | /// Tests for Vector3 | 36 | /// Tests for Vector3 |
37 | /// </summary> | 37 | /// </summary> |
38 | [TestFixture] | 38 | [TestFixture] |
39 | public class LSL_TypesTestVector3 | 39 | public class LSL_TypesTestVector3 : OpenSimTestCase |
40 | { | 40 | { |
41 | [Test] | 41 | [Test] |
42 | public void TestDotProduct() | 42 | public void TestDotProduct() |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index c401794..c88bad5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs | |||
@@ -41,6 +41,7 @@ using OpenSim.Region.OptionalModules.World.NPC; | |||
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.ScriptEngine.Shared; | 42 | using OpenSim.Region.ScriptEngine.Shared; |
43 | using OpenSim.Region.ScriptEngine.Shared.Api; | 43 | using OpenSim.Region.ScriptEngine.Shared.Api; |
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
44 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | 47 | using OpenSim.Tests.Common.Mock; |
@@ -51,14 +52,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
51 | /// Tests for OSSL_Api | 52 | /// Tests for OSSL_Api |
52 | /// </summary> | 53 | /// </summary> |
53 | [TestFixture] | 54 | [TestFixture] |
54 | public class OSSL_ApiAppearanceTest | 55 | public class OSSL_ApiAppearanceTest : OpenSimTestCase |
55 | { | 56 | { |
56 | protected Scene m_scene; | 57 | protected Scene m_scene; |
57 | protected XEngine.XEngine m_engine; | 58 | protected XEngine.XEngine m_engine; |
58 | 59 | ||
59 | [SetUp] | 60 | [SetUp] |
60 | public void SetUp() | 61 | public override void SetUp() |
61 | { | 62 | { |
63 | base.SetUp(); | ||
64 | |||
62 | IConfigSource initConfigSource = new IniConfigSource(); | 65 | IConfigSource initConfigSource = new IniConfigSource(); |
63 | IConfig config = initConfigSource.AddConfig("XEngine"); | 66 | IConfig config = initConfigSource.AddConfig("XEngine"); |
64 | config.Set("Enabled", "true"); | 67 | config.Set("Enabled", "true"); |
@@ -91,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
91 | m_scene.AddSceneObject(so); | 94 | m_scene.AddSceneObject(so); |
92 | 95 | ||
93 | OSSL_Api osslApi = new OSSL_Api(); | 96 | OSSL_Api osslApi = new OSSL_Api(); |
94 | osslApi.Initialize(m_engine, part, null); | 97 | osslApi.Initialize(m_engine, part, null, null); |
95 | 98 | ||
96 | string notecardName = "appearanceNc"; | 99 | string notecardName = "appearanceNc"; |
97 | 100 | ||
@@ -132,7 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
132 | m_scene.AddSceneObject(so); | 135 | m_scene.AddSceneObject(so); |
133 | 136 | ||
134 | OSSL_Api osslApi = new OSSL_Api(); | 137 | OSSL_Api osslApi = new OSSL_Api(); |
135 | osslApi.Initialize(m_engine, part, null); | 138 | osslApi.Initialize(m_engine, part, null, null); |
136 | 139 | ||
137 | string notecardName = "appearanceNc"; | 140 | string notecardName = "appearanceNc"; |
138 | 141 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs index 5ed1f3d..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; | |||
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.ScriptEngine.Shared; | 42 | using OpenSim.Region.ScriptEngine.Shared; |
43 | using OpenSim.Region.ScriptEngine.Shared.Api; | 43 | using OpenSim.Region.ScriptEngine.Shared.Api; |
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
44 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | 47 | using OpenSim.Tests.Common.Mock; |
@@ -98,9 +99,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
98 | SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); | 99 | SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID); |
99 | TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); | 100 | TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart); |
100 | 101 | ||
101 | new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem); | 102 | new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); |
102 | OSSL_Api osslApi = new OSSL_Api(); | 103 | OSSL_Api osslApi = new OSSL_Api(); |
103 | osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem); | 104 | osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem, null); |
104 | 105 | ||
105 | // SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ua1.PrincipalID); | 106 | // SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ua1.PrincipalID); |
106 | 107 | ||
@@ -144,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; | |||
42 | using OpenSim.Region.Framework.Scenes; | 42 | using OpenSim.Region.Framework.Scenes; |
43 | using OpenSim.Region.ScriptEngine.Shared; | 43 | using OpenSim.Region.ScriptEngine.Shared; |
44 | using OpenSim.Region.ScriptEngine.Shared.Api; | 44 | using OpenSim.Region.ScriptEngine.Shared.Api; |
45 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 46 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
46 | using OpenSim.Services.Interfaces; | 47 | using OpenSim.Services.Interfaces; |
47 | using OpenSim.Tests.Common; | 48 | using OpenSim.Tests.Common; |
@@ -99,7 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
99 | m_scene.AddSceneObject(so); | 100 | m_scene.AddSceneObject(so); |
100 | 101 | ||
101 | OSSL_Api osslApi = new OSSL_Api(); | 102 | OSSL_Api osslApi = new OSSL_Api(); |
102 | osslApi.Initialize(m_engine, part, null); | 103 | osslApi.Initialize(m_engine, part, null, null); |
103 | 104 | ||
104 | string notecardName = "appearanceNc"; | 105 | string notecardName = "appearanceNc"; |
105 | osslApi.osOwnerSaveAppearance(notecardName); | 106 | osslApi.osOwnerSaveAppearance(notecardName); |
@@ -125,14 +126,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
125 | m_scene.AddSceneObject(so); | 126 | m_scene.AddSceneObject(so); |
126 | 127 | ||
127 | OSSL_Api osslApi = new OSSL_Api(); | 128 | OSSL_Api osslApi = new OSSL_Api(); |
128 | osslApi.Initialize(m_engine, so.RootPart, null); | 129 | osslApi.Initialize(m_engine, so.RootPart, null, null); |
129 | 130 | ||
130 | string npcRaw; | ||
131 | bool gotExpectedException = false; | 131 | bool gotExpectedException = false; |
132 | try | 132 | try |
133 | { | 133 | { |
134 | npcRaw | 134 | osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), "not existing notecard name"); |
135 | = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), "not existing notecard name"); | ||
136 | } | 135 | } |
137 | catch (ScriptException) | 136 | catch (ScriptException) |
138 | { | 137 | { |
@@ -162,7 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
162 | m_scene.AddSceneObject(so); | 161 | m_scene.AddSceneObject(so); |
163 | 162 | ||
164 | OSSL_Api osslApi = new OSSL_Api(); | 163 | OSSL_Api osslApi = new OSSL_Api(); |
165 | osslApi.Initialize(m_engine, part, null); | 164 | osslApi.Initialize(m_engine, part, null, null); |
166 | 165 | ||
167 | string notecardName = "appearanceNc"; | 166 | string notecardName = "appearanceNc"; |
168 | osslApi.osOwnerSaveAppearance(notecardName); | 167 | osslApi.osOwnerSaveAppearance(notecardName); |
@@ -196,7 +195,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
196 | m_scene.AddSceneObject(so); | 195 | m_scene.AddSceneObject(so); |
197 | 196 | ||
198 | OSSL_Api osslApi = new OSSL_Api(); | 197 | OSSL_Api osslApi = new OSSL_Api(); |
199 | osslApi.Initialize(m_engine, part, null); | 198 | osslApi.Initialize(m_engine, part, null, null); |
200 | 199 | ||
201 | osslApi.osOwnerSaveAppearance(firstAppearanceNcName); | 200 | osslApi.osOwnerSaveAppearance(firstAppearanceNcName); |
202 | 201 | ||
@@ -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 | |||
28 | using System; | ||
29 | using System.Runtime.Remoting; | ||
30 | using System.Runtime.Remoting.Lifetime; | ||
31 | using System.Security.Permissions; | ||
32 | using System.Threading; | ||
33 | using System.Reflection; | ||
34 | using System.Collections; | ||
35 | using System.Collections.Generic; | ||
36 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
37 | using OpenSim.Region.ScriptEngine.Shared; | ||
38 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
39 | |||
40 | namespace OpenSim.Region.ScriptEngine.XEngine.ScriptBase | ||
41 | { | ||
42 | public class XEngineScriptBase : ScriptBaseClass | ||
43 | { | ||
44 | /// <summary> | ||
45 | /// Used for script sleeps when we are using co-operative script termination. | ||
46 | /// </summary> | ||
47 | /// <remarks>null if co-operative script termination is not active</remarks> | ||
48 | WaitHandle m_coopSleepHandle; | ||
49 | |||
50 | public XEngineScriptBase(WaitHandle coopSleepHandle) : base() | ||
51 | { | ||
52 | m_coopSleepHandle = coopSleepHandle; | ||
53 | } | ||
54 | |||
55 | public void opensim_reserved_CheckForCoopTermination() | ||
56 | { | ||
57 | if (m_coopSleepHandle != null && m_coopSleepHandle.WaitOne(0)) | ||
58 | throw new ScriptCoopStopException(); | ||
59 | } | ||
60 | } | ||
61 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index 9405075..0ff2da3 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs | |||
@@ -52,7 +52,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
52 | { | 52 | { |
53 | myScriptEngine = _ScriptEngine; | 53 | myScriptEngine = _ScriptEngine; |
54 | 54 | ||
55 | m_log.Info("[XEngine] Hooking up to server events"); | 55 | // m_log.Info("[XEngine] Hooking up to server events"); |
56 | myScriptEngine.World.EventManager.OnAttach += attach; | 56 | myScriptEngine.World.EventManager.OnAttach += attach; |
57 | myScriptEngine.World.EventManager.OnObjectGrab += touch_start; | 57 | myScriptEngine.World.EventManager.OnObjectGrab += touch_start; |
58 | myScriptEngine.World.EventManager.OnObjectGrabbing += touch; | 58 | myScriptEngine.World.EventManager.OnObjectGrabbing += touch; |
@@ -62,6 +62,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
62 | myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; | 62 | myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; |
63 | myScriptEngine.World.EventManager.OnScriptAtRotTargetEvent += at_rot_target; | 63 | myScriptEngine.World.EventManager.OnScriptAtRotTargetEvent += at_rot_target; |
64 | myScriptEngine.World.EventManager.OnScriptNotAtRotTargetEvent += not_at_rot_target; | 64 | myScriptEngine.World.EventManager.OnScriptNotAtRotTargetEvent += not_at_rot_target; |
65 | myScriptEngine.World.EventManager.OnScriptMovingStartEvent += moving_start; | ||
66 | myScriptEngine.World.EventManager.OnScriptMovingEndEvent += moving_end; | ||
65 | myScriptEngine.World.EventManager.OnScriptControlEvent += control; | 67 | myScriptEngine.World.EventManager.OnScriptControlEvent += control; |
66 | myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start; | 68 | myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start; |
67 | myScriptEngine.World.EventManager.OnScriptColliding += collision; | 69 | myScriptEngine.World.EventManager.OnScriptColliding += collision; |
@@ -69,7 +71,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
69 | myScriptEngine.World.EventManager.OnScriptLandColliderStart += land_collision_start; | 71 | myScriptEngine.World.EventManager.OnScriptLandColliderStart += land_collision_start; |
70 | myScriptEngine.World.EventManager.OnScriptLandColliding += land_collision; | 72 | myScriptEngine.World.EventManager.OnScriptLandColliding += land_collision; |
71 | myScriptEngine.World.EventManager.OnScriptLandColliderEnd += land_collision_end; | 73 | myScriptEngine.World.EventManager.OnScriptLandColliderEnd += land_collision_end; |
72 | IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>(); | 74 | IMoneyModule money = myScriptEngine.World.RequestModuleInterface<IMoneyModule>(); |
73 | if (money != null) | 75 | if (money != null) |
74 | { | 76 | { |
75 | money.OnObjectPaid+=HandleObjectPaid; | 77 | money.OnObjectPaid+=HandleObjectPaid; |
@@ -419,14 +421,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
419 | // dataserver: not handled here | 421 | // dataserver: not handled here |
420 | // link_message: not handled here | 422 | // link_message: not handled here |
421 | 423 | ||
422 | public void moving_start(uint localID, UUID itemID) | 424 | public void moving_start(uint localID) |
423 | { | 425 | { |
424 | myScriptEngine.PostObjectEvent(localID, new EventParams( | 426 | myScriptEngine.PostObjectEvent(localID, new EventParams( |
425 | "moving_start",new object[0], | 427 | "moving_start",new object[0], |
426 | new DetectParams[0])); | 428 | new DetectParams[0])); |
427 | } | 429 | } |
428 | 430 | ||
429 | public void moving_end(uint localID, UUID itemID) | 431 | public void moving_end(uint localID) |
430 | { | 432 | { |
431 | myScriptEngine.PostObjectEvent(localID, new EventParams( | 433 | myScriptEngine.PostObjectEvent(localID, new EventParams( |
432 | "moving_end",new object[0], | 434 | "moving_end",new object[0], |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using OpenSim.Framework; | ||
31 | using OpenSim.Framework.Console; | ||
32 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
33 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
34 | using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; | ||
35 | |||
36 | namespace OpenSim.Region.ScriptEngine.XEngine | ||
37 | { | ||
38 | public class ScriptEngineConsoleCommands | ||
39 | { | ||
40 | IScriptEngine m_engine; | ||
41 | |||
42 | public ScriptEngineConsoleCommands(IScriptEngine engine) | ||
43 | { | ||
44 | m_engine = engine; | ||
45 | } | ||
46 | |||
47 | public void RegisterCommands() | ||
48 | { | ||
49 | MainConsole.Instance.Commands.AddCommand( | ||
50 | "Scripts", false, "show script sensors", "show script sensors", "Show script sensors information", | ||
51 | HandleShowSensors); | ||
52 | |||
53 | MainConsole.Instance.Commands.AddCommand( | ||
54 | "Scripts", false, "show script timers", "show script timers", "Show script sensors information", | ||
55 | HandleShowTimers); | ||
56 | } | ||
57 | |||
58 | private bool IsSceneSelected() | ||
59 | { | ||
60 | return MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_engine.World; | ||
61 | } | ||
62 | |||
63 | private void HandleShowSensors(string module, string[] cmdparams) | ||
64 | { | ||
65 | if (!IsSceneSelected()) | ||
66 | return; | ||
67 | |||
68 | SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(m_engine); | ||
69 | |||
70 | if (sr == null) | ||
71 | { | ||
72 | MainConsole.Instance.Output("Plugin not yet initialized"); | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | List<SensorRepeat.SensorInfo> sensorInfo = sr.GetSensorInfo(); | ||
77 | |||
78 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
79 | cdt.AddColumn("Part name", 40); | ||
80 | cdt.AddColumn("Script item ID", 36); | ||
81 | cdt.AddColumn("Type", 4); | ||
82 | cdt.AddColumn("Interval", 8); | ||
83 | cdt.AddColumn("Range", 8); | ||
84 | cdt.AddColumn("Arc", 8); | ||
85 | |||
86 | foreach (SensorRepeat.SensorInfo s in sensorInfo) | ||
87 | { | ||
88 | cdt.AddRow(s.host.Name, s.itemID, s.type, s.interval, s.range, s.arc); | ||
89 | } | ||
90 | |||
91 | MainConsole.Instance.Output(cdt.ToString()); | ||
92 | MainConsole.Instance.OutputFormat("Total: {0}", sensorInfo.Count); | ||
93 | } | ||
94 | |||
95 | private void HandleShowTimers(string module, string[] cmdparams) | ||
96 | { | ||
97 | if (!IsSceneSelected()) | ||
98 | return; | ||
99 | |||
100 | Timer timerPlugin = AsyncCommandManager.GetTimerPlugin(m_engine); | ||
101 | |||
102 | if (timerPlugin == null) | ||
103 | { | ||
104 | MainConsole.Instance.Output("Plugin not yet initialized"); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | List<Timer.TimerInfo> timersInfo = timerPlugin.GetTimersInfo(); | ||
109 | |||
110 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
111 | cdt.AddColumn("Part local ID", 13); | ||
112 | cdt.AddColumn("Script item ID", 36); | ||
113 | cdt.AddColumn("Interval", 10); | ||
114 | cdt.AddColumn("Next", 8); | ||
115 | |||
116 | foreach (Timer.TimerInfo t in timersInfo) | ||
117 | { | ||
118 | // Convert from 100 ns ticks back to seconds | ||
119 | cdt.AddRow(t.localID, t.itemID, (double)t.interval / 10000000, t.next); | ||
120 | } | ||
121 | |||
122 | MainConsole.Instance.Output(cdt.ToString()); | ||
123 | MainConsole.Instance.OutputFormat("Total: {0}", timersInfo.Count); | ||
124 | } | ||
125 | } | ||
126 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs index f331658..5abfe9a 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs | |||
@@ -44,7 +44,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests | |||
44 | /// XEngine tests. | 44 | /// XEngine tests. |
45 | /// </summary> | 45 | /// </summary> |
46 | [TestFixture] | 46 | [TestFixture] |
47 | public class XEngineTest | 47 | public class XEngineTest : OpenSimTestCase |
48 | { | 48 | { |
49 | private TestScene m_scene; | 49 | private TestScene m_scene; |
50 | private XEngine m_xEngine; | 50 | private XEngine m_xEngine; |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 9f05666..17243ab 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -31,6 +31,7 @@ using System.Collections.Generic; | |||
31 | using System.Diagnostics; //for [DebuggerNonUserCode] | 31 | using System.Diagnostics; //for [DebuggerNonUserCode] |
32 | using System.Globalization; | 32 | using System.Globalization; |
33 | using System.IO; | 33 | using System.IO; |
34 | using System.Linq; | ||
34 | using System.Reflection; | 35 | using System.Reflection; |
35 | using System.Security; | 36 | using System.Security; |
36 | using System.Security.Policy; | 37 | using System.Security.Policy; |
@@ -46,13 +47,14 @@ using OpenSim.Framework; | |||
46 | using OpenSim.Framework.Console; | 47 | using OpenSim.Framework.Console; |
47 | using OpenSim.Region.Framework.Scenes; | 48 | using OpenSim.Region.Framework.Scenes; |
48 | using OpenSim.Region.Framework.Interfaces; | 49 | using OpenSim.Region.Framework.Interfaces; |
50 | using OpenSim.Region.ScriptEngine.Interfaces; | ||
49 | using OpenSim.Region.ScriptEngine.Shared; | 51 | using OpenSim.Region.ScriptEngine.Shared; |
50 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
51 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; | 52 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; |
52 | using OpenSim.Region.ScriptEngine.Shared.Instance; | 53 | using OpenSim.Region.ScriptEngine.Shared.Instance; |
53 | using OpenSim.Region.ScriptEngine.Shared.Api; | 54 | using OpenSim.Region.ScriptEngine.Shared.Api; |
54 | using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; | 55 | using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; |
55 | using OpenSim.Region.ScriptEngine.Interfaces; | 56 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
57 | using OpenSim.Region.ScriptEngine.XEngine.ScriptBase; | ||
56 | using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; | 58 | using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; |
57 | 59 | ||
58 | using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; | 60 | using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; |
@@ -107,6 +109,24 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
107 | private IXmlRpcRouter m_XmlRpcRouter; | 109 | private IXmlRpcRouter m_XmlRpcRouter; |
108 | private int m_EventLimit; | 110 | private int m_EventLimit; |
109 | private bool m_KillTimedOutScripts; | 111 | private bool m_KillTimedOutScripts; |
112 | |||
113 | /// <summary> | ||
114 | /// Number of milliseconds we will wait for a script event to complete on script stop before we forcibly abort | ||
115 | /// its thread. | ||
116 | /// </summary> | ||
117 | /// <remarks> | ||
118 | /// It appears that if a script thread is aborted whilst it is holding ReaderWriterLockSlim (possibly the write | ||
119 | /// lock) then the lock is not properly released. This causes mono 2.6, 2.10 and possibly | ||
120 | /// later to crash, sometimes with symptoms such as a leap to 100% script usage and a vm thead dump showing | ||
121 | /// all threads waiting on release of ReaderWriterLockSlim write thread which none of the threads listed | ||
122 | /// actually hold. | ||
123 | /// | ||
124 | /// Pausing for event completion reduces the risk of this happening. However, it may be that aborting threads | ||
125 | /// is not a mono issue per se but rather a risky activity in itself in an AppDomain that is not immediately | ||
126 | /// shutting down. | ||
127 | /// </remarks> | ||
128 | private int m_WaitForEventCompletionOnScriptStop = 1000; | ||
129 | |||
110 | private string m_ScriptEnginesPath = null; | 130 | private string m_ScriptEnginesPath = null; |
111 | 131 | ||
112 | private ExpiringCache<UUID, bool> m_runFlags = new ExpiringCache<UUID, bool>(); | 132 | private ExpiringCache<UUID, bool> m_runFlags = new ExpiringCache<UUID, bool>(); |
@@ -218,11 +238,21 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
218 | } | 238 | } |
219 | } | 239 | } |
220 | 240 | ||
241 | private ScriptEngineConsoleCommands m_consoleCommands; | ||
242 | |||
221 | public string ScriptEngineName | 243 | public string ScriptEngineName |
222 | { | 244 | { |
223 | get { return "XEngine"; } | 245 | get { return "XEngine"; } |
224 | } | 246 | } |
225 | 247 | ||
248 | public string ScriptClassName { get; private set; } | ||
249 | |||
250 | public string ScriptBaseClassName { get; private set; } | ||
251 | |||
252 | public ParameterInfo[] ScriptBaseClassParameters { get; private set; } | ||
253 | |||
254 | public string[] ScriptReferencedAssemblies { get; private set; } | ||
255 | |||
226 | public Scene World | 256 | public Scene World |
227 | { | 257 | { |
228 | get { return m_Scene; } | 258 | get { return m_Scene; } |
@@ -277,21 +307,35 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
277 | 307 | ||
278 | m_ScriptConfig = configSource.Configs["XEngine"]; | 308 | m_ScriptConfig = configSource.Configs["XEngine"]; |
279 | m_ConfigSource = configSource; | 309 | m_ConfigSource = configSource; |
310 | |||
311 | string rawScriptStopStrategy = m_ScriptConfig.GetString("ScriptStopStrategy", "abort"); | ||
312 | |||
313 | m_log.InfoFormat("[XEngine]: Script stop strategy is {0}", rawScriptStopStrategy); | ||
314 | |||
315 | if (rawScriptStopStrategy == "co-op") | ||
316 | { | ||
317 | ScriptClassName = "XEngineScript"; | ||
318 | ScriptBaseClassName = typeof(XEngineScriptBase).FullName; | ||
319 | ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters(); | ||
320 | ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) }; | ||
321 | } | ||
322 | else | ||
323 | { | ||
324 | ScriptClassName = "Script"; | ||
325 | ScriptBaseClassName = typeof(ScriptBaseClass).FullName; | ||
326 | } | ||
327 | |||
328 | // Console.WriteLine("ASSEMBLY NAME: {0}", ScriptReferencedAssemblies[0]); | ||
280 | } | 329 | } |
281 | 330 | ||
282 | public void AddRegion(Scene scene) | 331 | public void AddRegion(Scene scene) |
283 | { | 332 | { |
284 | if (m_ScriptConfig == null) | 333 | if (m_ScriptConfig == null) |
285 | return; | 334 | return; |
335 | |||
286 | m_ScriptFailCount = 0; | 336 | m_ScriptFailCount = 0; |
287 | m_ScriptErrorMessage = String.Empty; | 337 | m_ScriptErrorMessage = String.Empty; |
288 | 338 | ||
289 | if (m_ScriptConfig == null) | ||
290 | { | ||
291 | // m_log.ErrorFormat("[XEngine] No script configuration found. Scripts disabled"); | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | m_Enabled = m_ScriptConfig.GetBoolean("Enabled", true); | 339 | m_Enabled = m_ScriptConfig.GetBoolean("Enabled", true); |
296 | 340 | ||
297 | if (!m_Enabled) | 341 | if (!m_Enabled) |
@@ -316,6 +360,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
316 | m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); | 360 | m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); |
317 | m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); | 361 | m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); |
318 | m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; | 362 | m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; |
363 | m_WaitForEventCompletionOnScriptStop | ||
364 | = m_ScriptConfig.GetInt("WaitForEventCompletionOnScriptStop", m_WaitForEventCompletionOnScriptStop); | ||
365 | |||
319 | m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); | 366 | m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); |
320 | 367 | ||
321 | m_Prio = ThreadPriority.BelowNormal; | 368 | m_Prio = ThreadPriority.BelowNormal; |
@@ -364,48 +411,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
364 | OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved; | 411 | OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved; |
365 | } | 412 | } |
366 | 413 | ||
414 | m_consoleCommands = new ScriptEngineConsoleCommands(this); | ||
415 | m_consoleCommands.RegisterCommands(); | ||
416 | |||
367 | MainConsole.Instance.Commands.AddCommand( | 417 | MainConsole.Instance.Commands.AddCommand( |
368 | "Scripts", false, "xengine status", "xengine status", "Show status information", | 418 | "Scripts", false, "xengine status", "xengine status", "Show status information", |
369 | "Show status information on the script engine.", | 419 | "Show status information on the script engine.", |
370 | HandleShowStatus); | 420 | HandleShowStatus); |
371 | 421 | ||
372 | MainConsole.Instance.Commands.AddCommand( | 422 | MainConsole.Instance.Commands.AddCommand( |
373 | "Scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information", | 423 | "Scripts", false, "scripts show", "scripts show [<script-item-uuid>+]", "Show script information", |
374 | "Show information on all scripts known to the script engine." | 424 | "Show information on all scripts known to the script engine.\n" |
375 | + "If a <script-item-uuid> is given then only information on that script will be shown.", | 425 | + "If one or more <script-item-uuid>s are given then only information on that script will be shown.", |
376 | HandleShowScripts); | 426 | HandleShowScripts); |
377 | 427 | ||
378 | MainConsole.Instance.Commands.AddCommand( | 428 | MainConsole.Instance.Commands.AddCommand( |
379 | "Scripts", false, "show scripts", "show scripts [<script-item-uuid>]", "Show script information", | 429 | "Scripts", false, "show scripts", "show scripts [<script-item-uuid>+]", "Show script information", |
380 | "Synonym for scripts show command", HandleShowScripts); | 430 | "Synonym for scripts show command", HandleShowScripts); |
381 | 431 | ||
382 | MainConsole.Instance.Commands.AddCommand( | 432 | MainConsole.Instance.Commands.AddCommand( |
383 | "Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts", | 433 | "Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>+]", "Suspends all running scripts", |
384 | "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" | 434 | "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" |
385 | + " script that is currently processing an event.\n" | 435 | + " script that is currently processing an event.\n" |
386 | + "Suspended scripts will continue to accumulate events but won't process them.\n" | 436 | + "Suspended scripts will continue to accumulate events but won't process them.\n" |
387 | + "If a <script-item-uuid> is given then only that script will be suspended. Otherwise, all suitable scripts are suspended.", | 437 | + "If one or more <script-item-uuid>s are given then only that script will be suspended. Otherwise, all suitable scripts are suspended.", |
388 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); | 438 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); |
389 | 439 | ||
390 | MainConsole.Instance.Commands.AddCommand( | 440 | MainConsole.Instance.Commands.AddCommand( |
391 | "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts", | 441 | "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>+]", "Resumes all suspended scripts", |
392 | "Resumes all currently suspended scripts.\n" | 442 | "Resumes all currently suspended scripts.\n" |
393 | + "Resumed scripts will process all events accumulated whilst suspended." | 443 | + "Resumed scripts will process all events accumulated whilst suspended.\n" |
394 | + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", | 444 | + "If one or more <script-item-uuid>s are given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", |
395 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); | 445 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); |
396 | 446 | ||
397 | MainConsole.Instance.Commands.AddCommand( | 447 | MainConsole.Instance.Commands.AddCommand( |
398 | "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts", | 448 | "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>+]", "Stops all running scripts", |
399 | "Stops all running scripts." | 449 | "Stops all running scripts.\n" |
400 | + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", | 450 | + "If one or more <script-item-uuid>s are given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", |
401 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); | 451 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); |
402 | 452 | ||
403 | MainConsole.Instance.Commands.AddCommand( | 453 | MainConsole.Instance.Commands.AddCommand( |
404 | "Scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts", | 454 | "Scripts", false, "scripts start", "scripts start [<script-item-uuid>+]", "Starts all stopped scripts", |
405 | "Starts all stopped scripts." | 455 | "Starts all stopped scripts.\n" |
406 | + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.", | 456 | + "If one or more <script-item-uuid>s are given then only that script will be started. Otherwise, all suitable scripts are started.", |
407 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); | 457 | (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); |
408 | 458 | ||
459 | MainConsole.Instance.Commands.AddCommand( | ||
460 | "Scripts", false, "debug scripts log", "debug scripts log <item-id> <log-level>", "Extra debug logging for a script", | ||
461 | "Activates or deactivates extra debug logging for the given script.\n" | ||
462 | + "Level == 0, deactivate extra debug logging.\n" | ||
463 | + "Level >= 1, log state changes.\n" | ||
464 | + "Level >= 2, log event invocations.\n", | ||
465 | HandleDebugScriptLogCommand); | ||
466 | |||
409 | // MainConsole.Instance.Commands.AddCommand( | 467 | // MainConsole.Instance.Commands.AddCommand( |
410 | // "Debug", false, "debug xengine", "debug xengine [<level>]", | 468 | // "Debug", false, "debug xengine", "debug xengine [<level>]", |
411 | // "Turn on detailed xengine debugging.", | 469 | // "Turn on detailed xengine debugging.", |
@@ -414,6 +472,41 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
414 | // HandleDebugLevelCommand); | 472 | // HandleDebugLevelCommand); |
415 | } | 473 | } |
416 | 474 | ||
475 | private void HandleDebugScriptLogCommand(string module, string[] args) | ||
476 | { | ||
477 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) | ||
478 | return; | ||
479 | |||
480 | if (args.Length != 5) | ||
481 | { | ||
482 | MainConsole.Instance.Output("Usage: debug script log <item-id> <log-level>"); | ||
483 | return; | ||
484 | } | ||
485 | |||
486 | UUID itemId; | ||
487 | |||
488 | if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, args[3], out itemId)) | ||
489 | return; | ||
490 | |||
491 | int newLevel; | ||
492 | |||
493 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out newLevel)) | ||
494 | return; | ||
495 | |||
496 | IScriptInstance si; | ||
497 | |||
498 | lock (m_Scripts) | ||
499 | { | ||
500 | // XXX: We can't give the user feedback on a bad item id because this may apply to a different script | ||
501 | // engine | ||
502 | if (!m_Scripts.TryGetValue(itemId, out si)) | ||
503 | return; | ||
504 | } | ||
505 | |||
506 | si.DebugLevel = newLevel; | ||
507 | MainConsole.Instance.OutputFormat("Set debug level of {0} {1} to {2}", si.ScriptName, si.ItemID, newLevel); | ||
508 | } | ||
509 | |||
417 | /// <summary> | 510 | /// <summary> |
418 | /// Change debug level | 511 | /// Change debug level |
419 | /// </summary> | 512 | /// </summary> |
@@ -445,9 +538,21 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
445 | /// </summary> | 538 | /// </summary> |
446 | /// <param name="cmdparams"></param> | 539 | /// <param name="cmdparams"></param> |
447 | /// <param name="instance"></param> | 540 | /// <param name="instance"></param> |
448 | /// <returns>true if we're okay to proceed, false if not.</returns> | 541 | /// <param name="comparer">Basis on which to sort output. Can be null if no sort needs to take place</param> |
449 | private void HandleScriptsAction(string[] cmdparams, Action<IScriptInstance> action) | 542 | private void HandleScriptsAction(string[] cmdparams, Action<IScriptInstance> action) |
450 | { | 543 | { |
544 | HandleScriptsAction<object>(cmdparams, action, null); | ||
545 | } | ||
546 | |||
547 | /// <summary> | ||
548 | /// Parse the raw item id into a script instance from the command params if it's present. | ||
549 | /// </summary> | ||
550 | /// <param name="cmdparams"></param> | ||
551 | /// <param name="instance"></param> | ||
552 | /// <param name="keySelector">Basis on which to sort output. Can be null if no sort needs to take place</param> | ||
553 | private void HandleScriptsAction<TKey>( | ||
554 | string[] cmdparams, Action<IScriptInstance> action, Func<IScriptInstance, TKey> keySelector) | ||
555 | { | ||
451 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) | 556 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) |
452 | return; | 557 | return; |
453 | 558 | ||
@@ -458,35 +563,42 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
458 | 563 | ||
459 | if (cmdparams.Length == 2) | 564 | if (cmdparams.Length == 2) |
460 | { | 565 | { |
461 | foreach (IScriptInstance instance in m_Scripts.Values) | 566 | IEnumerable<IScriptInstance> scripts = m_Scripts.Values; |
567 | |||
568 | if (keySelector != null) | ||
569 | scripts = scripts.OrderBy<IScriptInstance, TKey>(keySelector); | ||
570 | |||
571 | foreach (IScriptInstance instance in scripts) | ||
462 | action(instance); | 572 | action(instance); |
463 | 573 | ||
464 | return; | 574 | return; |
465 | } | 575 | } |
466 | 576 | ||
467 | rawItemId = cmdparams[2]; | 577 | for (int i = 2; i < cmdparams.Length; i++) |
468 | |||
469 | if (!UUID.TryParse(rawItemId, out itemId)) | ||
470 | { | ||
471 | MainConsole.Instance.OutputFormat("Error - {0} is not a valid UUID", rawItemId); | ||
472 | return; | ||
473 | } | ||
474 | |||
475 | if (itemId != UUID.Zero) | ||
476 | { | 578 | { |
477 | IScriptInstance instance = GetInstance(itemId); | 579 | rawItemId = cmdparams[i]; |
478 | if (instance == null) | 580 | |
581 | if (!UUID.TryParse(rawItemId, out itemId)) | ||
479 | { | 582 | { |
480 | // Commented out for now since this will cause false reports on simulators with more than | 583 | MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId); |
481 | // one scene where the current command line set region is 'root' (which causes commands to | 584 | continue; |
482 | // go to both regions... (sigh) | ||
483 | // MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId); | ||
484 | return; | ||
485 | } | 585 | } |
486 | else | 586 | |
587 | if (itemId != UUID.Zero) | ||
487 | { | 588 | { |
488 | action(instance); | 589 | IScriptInstance instance = GetInstance(itemId); |
489 | return; | 590 | if (instance == null) |
591 | { | ||
592 | // Commented out for now since this will cause false reports on simulators with more than | ||
593 | // one scene where the current command line set region is 'root' (which causes commands to | ||
594 | // go to both regions... (sigh) | ||
595 | // MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId); | ||
596 | continue; | ||
597 | } | ||
598 | else | ||
599 | { | ||
600 | action(instance); | ||
601 | } | ||
490 | } | 602 | } |
491 | } | 603 | } |
492 | } | 604 | } |
@@ -505,9 +617,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
505 | StringBuilder sb = new StringBuilder(); | 617 | StringBuilder sb = new StringBuilder(); |
506 | sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName); | 618 | sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName); |
507 | 619 | ||
620 | long scriptsLoaded, eventsQueued = 0, eventsProcessed = 0; | ||
621 | |||
508 | lock (m_Scripts) | 622 | lock (m_Scripts) |
509 | sb.AppendFormat("Scripts loaded : {0}\n", m_Scripts.Count); | 623 | { |
624 | scriptsLoaded = m_Scripts.Count; | ||
510 | 625 | ||
626 | foreach (IScriptInstance si in m_Scripts.Values) | ||
627 | { | ||
628 | eventsQueued += si.EventsQueued; | ||
629 | eventsProcessed += si.EventsProcessed; | ||
630 | } | ||
631 | } | ||
632 | |||
633 | sb.AppendFormat("Scripts loaded : {0}\n", scriptsLoaded); | ||
511 | sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); | 634 | sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); |
512 | sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); | 635 | sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); |
513 | sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads); | 636 | sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads); |
@@ -516,6 +639,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
516 | sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads); | 639 | sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads); |
517 | sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks); | 640 | sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks); |
518 | // sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); | 641 | // sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); |
642 | sb.AppendFormat("Events queued : {0}\n", eventsQueued); | ||
643 | sb.AppendFormat("Events processed : {0}\n", eventsProcessed); | ||
519 | 644 | ||
520 | SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this); | 645 | SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this); |
521 | sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0); | 646 | sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0); |
@@ -546,7 +671,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
546 | } | 671 | } |
547 | } | 672 | } |
548 | 673 | ||
549 | HandleScriptsAction(cmdparams, HandleShowScript); | 674 | HandleScriptsAction<long>(cmdparams, HandleShowScript, si => si.EventsProcessed); |
550 | } | 675 | } |
551 | 676 | ||
552 | private void HandleShowScript(IScriptInstance instance) | 677 | private void HandleShowScript(IScriptInstance instance) |
@@ -572,15 +697,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
572 | } | 697 | } |
573 | 698 | ||
574 | StringBuilder sb = new StringBuilder(); | 699 | StringBuilder sb = new StringBuilder(); |
575 | Queue eq = instance.EventQueue; | ||
576 | 700 | ||
577 | sb.AppendFormat("Script name : {0}\n", instance.ScriptName); | 701 | sb.AppendFormat("Script name : {0}\n", instance.ScriptName); |
578 | sb.AppendFormat("Status : {0}\n", status); | 702 | sb.AppendFormat("Status : {0}\n", status); |
579 | 703 | sb.AppendFormat("Queued events : {0}\n", instance.EventsQueued); | |
580 | lock (eq) | 704 | sb.AppendFormat("Processed events : {0}\n", instance.EventsProcessed); |
581 | sb.AppendFormat("Queued events : {0}\n", eq.Count); | ||
582 | |||
583 | sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); | 705 | sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); |
706 | sb.AppendFormat("Asset UUID : {0}\n", instance.AssetID); | ||
584 | sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); | 707 | sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); |
585 | sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID); | 708 | sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID); |
586 | sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition); | 709 | sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition); |
@@ -1079,7 +1202,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1079 | } | 1202 | } |
1080 | 1203 | ||
1081 | m_log.DebugFormat( | 1204 | m_log.DebugFormat( |
1082 | "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", | 1205 | "[XEngine]: Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", |
1083 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, | 1206 | part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, |
1084 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); | 1207 | part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); |
1085 | 1208 | ||
@@ -1089,8 +1212,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1089 | 1212 | ||
1090 | string assembly = ""; | 1213 | string assembly = ""; |
1091 | 1214 | ||
1092 | CultureInfo USCulture = new CultureInfo("en-US"); | 1215 | Culture.SetCurrentCulture(); |
1093 | Thread.CurrentThread.CurrentCulture = USCulture; | ||
1094 | 1216 | ||
1095 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap; | 1217 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap; |
1096 | 1218 | ||
@@ -1101,6 +1223,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1101 | lock (m_AddingAssemblies) | 1223 | lock (m_AddingAssemblies) |
1102 | { | 1224 | { |
1103 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap); | 1225 | m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap); |
1226 | |||
1104 | if (!m_AddingAssemblies.ContainsKey(assembly)) { | 1227 | if (!m_AddingAssemblies.ContainsKey(assembly)) { |
1105 | m_AddingAssemblies[assembly] = 1; | 1228 | m_AddingAssemblies[assembly] = 1; |
1106 | } else { | 1229 | } else { |
@@ -1150,7 +1273,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1150 | } | 1273 | } |
1151 | catch (Exception e) | 1274 | catch (Exception e) |
1152 | { | 1275 | { |
1153 | // m_log.ErrorFormat("[XEngine]: Exception when rezzing script {0}{1}", e.Message, e.StackTrace); | 1276 | // m_log.ErrorFormat( |
1277 | // "[XEngine]: Exception when rezzing script with item ID {0}, {1}{2}", | ||
1278 | // itemID, e.Message, e.StackTrace); | ||
1154 | 1279 | ||
1155 | // try | 1280 | // try |
1156 | // { | 1281 | // { |
@@ -1229,13 +1354,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1229 | sandbox = AppDomain.CurrentDomain; | 1354 | sandbox = AppDomain.CurrentDomain; |
1230 | } | 1355 | } |
1231 | 1356 | ||
1232 | //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); | 1357 | if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) |
1233 | //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); | 1358 | return false; |
1234 | //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); | ||
1235 | //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); | ||
1236 | //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); | ||
1237 | //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; | ||
1238 | //sandbox.SetAppDomainPolicy(sandboxPolicy); | ||
1239 | 1359 | ||
1240 | m_AppDomains[appDomain] = sandbox; | 1360 | m_AppDomains[appDomain] = sandbox; |
1241 | 1361 | ||
@@ -1256,12 +1376,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1256 | m_DomainScripts[appDomain].Add(itemID); | 1376 | m_DomainScripts[appDomain].Add(itemID); |
1257 | 1377 | ||
1258 | instance = new ScriptInstance(this, part, | 1378 | instance = new ScriptInstance(this, part, |
1259 | itemID, assetID, assembly, | 1379 | item, |
1260 | m_AppDomains[appDomain], | 1380 | startParam, postOnRez, |
1261 | part.ParentGroup.RootPart.Name, | 1381 | m_MaxScriptQueue); |
1262 | item.Name, startParam, postOnRez, | ||
1263 | stateSource, m_MaxScriptQueue); | ||
1264 | 1382 | ||
1383 | instance.Load(m_AppDomains[appDomain], assembly, stateSource); | ||
1265 | // m_log.DebugFormat( | 1384 | // m_log.DebugFormat( |
1266 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", | 1385 | // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", |
1267 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, | 1386 | // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, |
@@ -1347,9 +1466,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1347 | lockScriptsForWrite(false); | 1466 | lockScriptsForWrite(false); |
1348 | instance.ClearQueue(); | 1467 | instance.ClearQueue(); |
1349 | 1468 | ||
1350 | // Give the script some time to finish processing its last event. Simply aborting the script thread can | 1469 | instance.Stop(m_WaitForEventCompletionOnScriptStop); |
1351 | // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort. | ||
1352 | instance.Stop(1000); | ||
1353 | 1470 | ||
1354 | // bool objectRemoved = false; | 1471 | // bool objectRemoved = false; |
1355 | 1472 | ||
@@ -1477,7 +1594,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1477 | m_MaxScriptQueue = maxScriptQueue; | 1594 | m_MaxScriptQueue = maxScriptQueue; |
1478 | 1595 | ||
1479 | STPStartInfo startInfo = new STPStartInfo(); | 1596 | STPStartInfo startInfo = new STPStartInfo(); |
1480 | startInfo.IdleTimeout = idleTimeout*1000; // convert to seconds as stated in .ini | 1597 | startInfo.ThreadPoolName = "XEngine"; |
1598 | startInfo.IdleTimeout = idleTimeout * 1000; // convert to seconds as stated in .ini | ||
1481 | startInfo.MaxWorkerThreads = maxThreads; | 1599 | startInfo.MaxWorkerThreads = maxThreads; |
1482 | startInfo.MinWorkerThreads = minThreads; | 1600 | startInfo.MinWorkerThreads = minThreads; |
1483 | startInfo.ThreadPriority = threadPriority;; | 1601 | startInfo.ThreadPriority = threadPriority;; |
@@ -1504,8 +1622,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1504 | /// <returns></returns> | 1622 | /// <returns></returns> |
1505 | private object ProcessEventHandler(object parms) | 1623 | private object ProcessEventHandler(object parms) |
1506 | { | 1624 | { |
1507 | CultureInfo USCulture = new CultureInfo("en-US"); | 1625 | Culture.SetCurrentCulture(); |
1508 | Thread.CurrentThread.CurrentCulture = USCulture; | ||
1509 | 1626 | ||
1510 | IScriptInstance instance = (ScriptInstance) parms; | 1627 | IScriptInstance instance = (ScriptInstance) parms; |
1511 | 1628 | ||
@@ -1693,7 +1810,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1693 | { | 1810 | { |
1694 | IScriptInstance instance = GetInstance(itemID); | 1811 | IScriptInstance instance = GetInstance(itemID); |
1695 | if (instance != null) | 1812 | if (instance != null) |
1696 | instance.ResetScript(); | 1813 | instance.ResetScript(m_WaitForEventCompletionOnScriptStop); |
1697 | } | 1814 | } |
1698 | 1815 | ||
1699 | public void StartScript(UUID itemID) | 1816 | public void StartScript(UUID itemID) |
@@ -1708,14 +1825,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1708 | public void StopScript(UUID itemID) | 1825 | public void StopScript(UUID itemID) |
1709 | { | 1826 | { |
1710 | IScriptInstance instance = GetInstance(itemID); | 1827 | IScriptInstance instance = GetInstance(itemID); |
1828 | |||
1711 | if (instance != null) | 1829 | if (instance != null) |
1712 | { | 1830 | { |
1713 | // Give the script some time to finish processing its last event. Simply aborting the script thread can | 1831 | instance.Stop(m_WaitForEventCompletionOnScriptStop); |
1714 | // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort. | ||
1715 | instance.Stop(1000); | ||
1716 | } | 1832 | } |
1717 | else | 1833 | else |
1718 | { | 1834 | { |
1835 | // m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name); | ||
1719 | m_runFlags.AddOrUpdate(itemID, false, 240); | 1836 | m_runFlags.AddOrUpdate(itemID, false, 240); |
1720 | } | 1837 | } |
1721 | } | 1838 | } |
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 | } |