diff options
author | UbitUmarov | 2015-09-01 11:43:07 +0100 |
---|---|---|
committer | UbitUmarov | 2015-09-01 11:43:07 +0100 |
commit | fb78b182520fc9bb0f971afd0322029c70278ea6 (patch) | |
tree | b4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Region/OptionalModules/Scripting | |
parent | lixo (diff) | |
parent | Mantis #7713: fixed bug introduced by 1st MOSES patch. (diff) | |
download | opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.zip opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2 opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz |
Merge remote-tracking branch 'os/master'
Diffstat (limited to 'OpenSim/Region/OptionalModules/Scripting')
54 files changed, 9087 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs new file mode 100755 index 0000000..ff4afbf --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs | |||
@@ -0,0 +1,623 @@ | |||
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 copyrightD | ||
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 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using System.Linq; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Threading; | ||
33 | |||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Region.CoreModules; | ||
36 | using OpenSim.Region.Framework; | ||
37 | using OpenSim.Region.Framework.Interfaces; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | using OpenSim.Region.Physics.Manager; | ||
40 | |||
41 | using Mono.Addins; | ||
42 | using Nini.Config; | ||
43 | using log4net; | ||
44 | using OpenMetaverse; | ||
45 | |||
46 | namespace OpenSim.Region.OptionalModules.Scripting | ||
47 | { | ||
48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] | ||
49 | public class ExtendedPhysics : INonSharedRegionModule | ||
50 | { | ||
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
52 | private static string LogHeader = "[EXTENDED PHYSICS]"; | ||
53 | |||
54 | // ============================================================= | ||
55 | // Since BulletSim is a plugin, this these values aren't defined easily in one place. | ||
56 | // This table must correspond to an identical table in BSScene. | ||
57 | |||
58 | // Per scene functions. See BSScene. | ||
59 | |||
60 | // Per avatar functions. See BSCharacter. | ||
61 | |||
62 | // Per prim functions. See BSPrim. | ||
63 | public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType"; | ||
64 | public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType"; | ||
65 | public const string PhysFunctChangeLinkFixed = "BulletSim.ChangeLinkFixed"; | ||
66 | public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType"; | ||
67 | public const string PhysFunctGetLinkType = "BulletSim.GetLinkType"; | ||
68 | public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams"; | ||
69 | public const string PhysFunctAxisLockLimits = "BulletSim.AxisLockLimits"; | ||
70 | |||
71 | // ============================================================= | ||
72 | |||
73 | private IConfig Configuration { get; set; } | ||
74 | private bool Enabled { get; set; } | ||
75 | private Scene BaseScene { get; set; } | ||
76 | private IScriptModuleComms Comms { get; set; } | ||
77 | |||
78 | #region INonSharedRegionModule | ||
79 | |||
80 | public string Name { get { return this.GetType().Name; } } | ||
81 | |||
82 | public void Initialise(IConfigSource config) | ||
83 | { | ||
84 | BaseScene = null; | ||
85 | Enabled = false; | ||
86 | Configuration = null; | ||
87 | Comms = null; | ||
88 | |||
89 | try | ||
90 | { | ||
91 | if ((Configuration = config.Configs["ExtendedPhysics"]) != null) | ||
92 | { | ||
93 | Enabled = Configuration.GetBoolean("Enabled", Enabled); | ||
94 | } | ||
95 | } | ||
96 | catch (Exception e) | ||
97 | { | ||
98 | m_log.ErrorFormat("{0} Initialization error: {0}", LogHeader, e); | ||
99 | } | ||
100 | |||
101 | m_log.InfoFormat("{0} module {1} enabled", LogHeader, (Enabled ? "is" : "is not")); | ||
102 | } | ||
103 | |||
104 | public void Close() | ||
105 | { | ||
106 | if (BaseScene != null) | ||
107 | { | ||
108 | BaseScene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene; | ||
109 | BaseScene.EventManager.OnSceneObjectPartUpdated -= EventManager_OnSceneObjectPartUpdated; | ||
110 | BaseScene = null; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | public void AddRegion(Scene scene) | ||
115 | { | ||
116 | } | ||
117 | |||
118 | public void RemoveRegion(Scene scene) | ||
119 | { | ||
120 | if (BaseScene != null && BaseScene == scene) | ||
121 | { | ||
122 | Close(); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | public void RegionLoaded(Scene scene) | ||
127 | { | ||
128 | if (!Enabled) return; | ||
129 | |||
130 | BaseScene = scene; | ||
131 | |||
132 | Comms = BaseScene.RequestModuleInterface<IScriptModuleComms>(); | ||
133 | if (Comms == null) | ||
134 | { | ||
135 | m_log.WarnFormat("{0} ScriptModuleComms interface not defined", LogHeader); | ||
136 | Enabled = false; | ||
137 | |||
138 | return; | ||
139 | } | ||
140 | |||
141 | // Register as LSL functions all the [ScriptInvocation] marked methods. | ||
142 | Comms.RegisterScriptInvocations(this); | ||
143 | Comms.RegisterConstants(this); | ||
144 | |||
145 | // When an object is modified, we might need to update its extended physics parameters | ||
146 | BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; | ||
147 | BaseScene.EventManager.OnSceneObjectPartUpdated += EventManager_OnSceneObjectPartUpdated; | ||
148 | |||
149 | } | ||
150 | |||
151 | public Type ReplaceableInterface { get { return null; } } | ||
152 | |||
153 | #endregion // INonSharedRegionModule | ||
154 | |||
155 | private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj) | ||
156 | { | ||
157 | } | ||
158 | |||
159 | // Event generated when some property of a prim changes. | ||
160 | private void EventManager_OnSceneObjectPartUpdated(SceneObjectPart sop, bool isFullUpdate) | ||
161 | { | ||
162 | } | ||
163 | |||
164 | [ScriptConstant] | ||
165 | public const int PHYS_CENTER_OF_MASS = 1 << 0; | ||
166 | |||
167 | [ScriptInvocation] | ||
168 | public string physGetEngineType(UUID hostID, UUID scriptID) | ||
169 | { | ||
170 | string ret = string.Empty; | ||
171 | |||
172 | if (BaseScene.PhysicsScene != null) | ||
173 | { | ||
174 | ret = BaseScene.PhysicsScene.EngineType; | ||
175 | } | ||
176 | |||
177 | return ret; | ||
178 | } | ||
179 | |||
180 | // Code for specifying params. | ||
181 | // The choice if 14700 is arbitrary and only serves to catch parameter code misuse. | ||
182 | [ScriptConstant] | ||
183 | public const int PHYS_AXIS_LOCK_LINEAR = 14700; | ||
184 | [ScriptConstant] | ||
185 | public const int PHYS_AXIS_LOCK_LINEAR_X = 14701; | ||
186 | [ScriptConstant] | ||
187 | public const int PHYS_AXIS_LIMIT_LINEAR_X = 14702; | ||
188 | [ScriptConstant] | ||
189 | public const int PHYS_AXIS_LOCK_LINEAR_Y = 14703; | ||
190 | [ScriptConstant] | ||
191 | public const int PHYS_AXIS_LIMIT_LINEAR_Y = 14704; | ||
192 | [ScriptConstant] | ||
193 | public const int PHYS_AXIS_LOCK_LINEAR_Z = 14705; | ||
194 | [ScriptConstant] | ||
195 | public const int PHYS_AXIS_LIMIT_LINEAR_Z = 14706; | ||
196 | [ScriptConstant] | ||
197 | public const int PHYS_AXIS_LOCK_ANGULAR = 14707; | ||
198 | [ScriptConstant] | ||
199 | public const int PHYS_AXIS_LOCK_ANGULAR_X = 14708; | ||
200 | [ScriptConstant] | ||
201 | public const int PHYS_AXIS_LIMIT_ANGULAR_X = 14709; | ||
202 | [ScriptConstant] | ||
203 | public const int PHYS_AXIS_LOCK_ANGULAR_Y = 14710; | ||
204 | [ScriptConstant] | ||
205 | public const int PHYS_AXIS_LIMIT_ANGULAR_Y = 14711; | ||
206 | [ScriptConstant] | ||
207 | public const int PHYS_AXIS_LOCK_ANGULAR_Z = 14712; | ||
208 | [ScriptConstant] | ||
209 | public const int PHYS_AXIS_LIMIT_ANGULAR_Z = 14713; | ||
210 | [ScriptConstant] | ||
211 | public const int PHYS_AXIS_UNLOCK_LINEAR = 14714; | ||
212 | [ScriptConstant] | ||
213 | public const int PHYS_AXIS_UNLOCK_LINEAR_X = 14715; | ||
214 | [ScriptConstant] | ||
215 | public const int PHYS_AXIS_UNLOCK_LINEAR_Y = 14716; | ||
216 | [ScriptConstant] | ||
217 | public const int PHYS_AXIS_UNLOCK_LINEAR_Z = 14717; | ||
218 | [ScriptConstant] | ||
219 | public const int PHYS_AXIS_UNLOCK_ANGULAR = 14718; | ||
220 | [ScriptConstant] | ||
221 | public const int PHYS_AXIS_UNLOCK_ANGULAR_X = 14719; | ||
222 | [ScriptConstant] | ||
223 | public const int PHYS_AXIS_UNLOCK_ANGULAR_Y = 14720; | ||
224 | [ScriptConstant] | ||
225 | public const int PHYS_AXIS_UNLOCK_ANGULAR_Z = 14721; | ||
226 | [ScriptConstant] | ||
227 | public const int PHYS_AXIS_UNLOCK = 14722; | ||
228 | // physAxisLockLimits() | ||
229 | [ScriptInvocation] | ||
230 | public int physAxisLock(UUID hostID, UUID scriptID, object[] parms) | ||
231 | { | ||
232 | int ret = -1; | ||
233 | if (!Enabled) return ret; | ||
234 | |||
235 | PhysicsActor rootPhysActor; | ||
236 | if (GetRootPhysActor(hostID, out rootPhysActor)) | ||
237 | { | ||
238 | object[] parms2 = AddToBeginningOfArray(rootPhysActor, null, parms); | ||
239 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctAxisLockLimits, parms2)); | ||
240 | } | ||
241 | |||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | [ScriptConstant] | ||
246 | public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0; | ||
247 | [ScriptConstant] | ||
248 | public const int PHYS_LINKSET_TYPE_COMPOUND = 1; | ||
249 | [ScriptConstant] | ||
250 | public const int PHYS_LINKSET_TYPE_MANUAL = 2; | ||
251 | |||
252 | [ScriptInvocation] | ||
253 | public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) | ||
254 | { | ||
255 | int ret = -1; | ||
256 | if (!Enabled) return ret; | ||
257 | |||
258 | // The part that is requesting the change. | ||
259 | SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); | ||
260 | |||
261 | if (requestingPart != null) | ||
262 | { | ||
263 | // The change is always made to the root of a linkset. | ||
264 | SceneObjectGroup containingGroup = requestingPart.ParentGroup; | ||
265 | SceneObjectPart rootPart = containingGroup.RootPart; | ||
266 | |||
267 | if (rootPart != null) | ||
268 | { | ||
269 | PhysicsActor rootPhysActor = rootPart.PhysActor; | ||
270 | if (rootPhysActor != null) | ||
271 | { | ||
272 | if (rootPhysActor.IsPhysical) | ||
273 | { | ||
274 | // Change a physical linkset by making non-physical, waiting for one heartbeat so all | ||
275 | // the prim and linkset state is updated, changing the type and making the | ||
276 | // linkset physical again. | ||
277 | containingGroup.ScriptSetPhysicsStatus(false); | ||
278 | Thread.Sleep(150); // longer than one heartbeat tick | ||
279 | |||
280 | // A kludge for the moment. | ||
281 | // Since compound linksets move the children but don't generate position updates to the | ||
282 | // simulator, it is possible for compound linkset children to have out-of-sync simulator | ||
283 | // and physical positions. The following causes the simulator to push the real child positions | ||
284 | // down into the physics engine to get everything synced. | ||
285 | containingGroup.UpdateGroupPosition(containingGroup.AbsolutePosition); | ||
286 | containingGroup.UpdateGroupRotationR(containingGroup.GroupRotation); | ||
287 | |||
288 | object[] parms2 = { rootPhysActor, null, linksetType }; | ||
289 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctSetLinksetType, parms2)); | ||
290 | Thread.Sleep(150); // longer than one heartbeat tick | ||
291 | |||
292 | containingGroup.ScriptSetPhysicsStatus(true); | ||
293 | } | ||
294 | else | ||
295 | { | ||
296 | // Non-physical linksets don't have a physical instantiation so there is no state to | ||
297 | // worry about being updated. | ||
298 | object[] parms2 = { rootPhysActor, null, linksetType }; | ||
299 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctSetLinksetType, parms2)); | ||
300 | } | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | m_log.WarnFormat("{0} physSetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}", | ||
305 | LogHeader, rootPart.Name, hostID); | ||
306 | } | ||
307 | } | ||
308 | else | ||
309 | { | ||
310 | m_log.WarnFormat("{0} physSetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}", | ||
311 | LogHeader, requestingPart.Name, hostID); | ||
312 | } | ||
313 | } | ||
314 | else | ||
315 | { | ||
316 | m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID); | ||
317 | } | ||
318 | return ret; | ||
319 | } | ||
320 | |||
321 | [ScriptInvocation] | ||
322 | public int physGetLinksetType(UUID hostID, UUID scriptID) | ||
323 | { | ||
324 | int ret = -1; | ||
325 | if (!Enabled) return ret; | ||
326 | |||
327 | PhysicsActor rootPhysActor; | ||
328 | if (GetRootPhysActor(hostID, out rootPhysActor)) | ||
329 | { | ||
330 | object[] parms2 = { rootPhysActor, null }; | ||
331 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2)); | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | m_log.WarnFormat("{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID); | ||
336 | } | ||
337 | return ret; | ||
338 | } | ||
339 | |||
340 | [ScriptConstant] | ||
341 | public const int PHYS_LINK_TYPE_FIXED = 1234; | ||
342 | [ScriptConstant] | ||
343 | public const int PHYS_LINK_TYPE_HINGE = 4; | ||
344 | [ScriptConstant] | ||
345 | public const int PHYS_LINK_TYPE_SPRING = 9; | ||
346 | [ScriptConstant] | ||
347 | public const int PHYS_LINK_TYPE_6DOF = 6; | ||
348 | [ScriptConstant] | ||
349 | public const int PHYS_LINK_TYPE_SLIDER = 7; | ||
350 | |||
351 | // physChangeLinkType(integer linkNum, integer typeCode) | ||
352 | [ScriptInvocation] | ||
353 | public int physChangeLinkType(UUID hostID, UUID scriptID, int linkNum, int typeCode) | ||
354 | { | ||
355 | int ret = -1; | ||
356 | if (!Enabled) return ret; | ||
357 | |||
358 | PhysicsActor rootPhysActor; | ||
359 | PhysicsActor childPhysActor; | ||
360 | |||
361 | if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor)) | ||
362 | { | ||
363 | object[] parms2 = { rootPhysActor, childPhysActor, typeCode }; | ||
364 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkType, parms2)); | ||
365 | } | ||
366 | |||
367 | return ret; | ||
368 | } | ||
369 | |||
370 | // physGetLinkType(integer linkNum) | ||
371 | [ScriptInvocation] | ||
372 | public int physGetLinkType(UUID hostID, UUID scriptID, int linkNum) | ||
373 | { | ||
374 | int ret = -1; | ||
375 | if (!Enabled) return ret; | ||
376 | |||
377 | PhysicsActor rootPhysActor; | ||
378 | PhysicsActor childPhysActor; | ||
379 | |||
380 | if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor)) | ||
381 | { | ||
382 | object[] parms2 = { rootPhysActor, childPhysActor }; | ||
383 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinkType, parms2)); | ||
384 | } | ||
385 | |||
386 | return ret; | ||
387 | } | ||
388 | |||
389 | // physChangeLinkFixed(integer linkNum) | ||
390 | // Change the link between the root and the linkNum into a fixed, static physical connection. | ||
391 | [ScriptInvocation] | ||
392 | public int physChangeLinkFixed(UUID hostID, UUID scriptID, int linkNum) | ||
393 | { | ||
394 | int ret = -1; | ||
395 | if (!Enabled) return ret; | ||
396 | |||
397 | PhysicsActor rootPhysActor; | ||
398 | PhysicsActor childPhysActor; | ||
399 | |||
400 | if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor)) | ||
401 | { | ||
402 | object[] parms2 = { rootPhysActor, childPhysActor , PHYS_LINK_TYPE_FIXED }; | ||
403 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkType, parms2)); | ||
404 | } | ||
405 | |||
406 | return ret; | ||
407 | } | ||
408 | |||
409 | // Code for specifying params. | ||
410 | // The choice if 14400 is arbitrary and only serves to catch parameter code misuse. | ||
411 | public const int PHYS_PARAM_MIN = 14401; | ||
412 | |||
413 | [ScriptConstant] | ||
414 | public const int PHYS_PARAM_FRAMEINA_LOC = 14401; | ||
415 | [ScriptConstant] | ||
416 | public const int PHYS_PARAM_FRAMEINA_ROT = 14402; | ||
417 | [ScriptConstant] | ||
418 | public const int PHYS_PARAM_FRAMEINB_LOC = 14403; | ||
419 | [ScriptConstant] | ||
420 | public const int PHYS_PARAM_FRAMEINB_ROT = 14404; | ||
421 | [ScriptConstant] | ||
422 | public const int PHYS_PARAM_LINEAR_LIMIT_LOW = 14405; | ||
423 | [ScriptConstant] | ||
424 | public const int PHYS_PARAM_LINEAR_LIMIT_HIGH = 14406; | ||
425 | [ScriptConstant] | ||
426 | public const int PHYS_PARAM_ANGULAR_LIMIT_LOW = 14407; | ||
427 | [ScriptConstant] | ||
428 | public const int PHYS_PARAM_ANGULAR_LIMIT_HIGH = 14408; | ||
429 | [ScriptConstant] | ||
430 | public const int PHYS_PARAM_USE_FRAME_OFFSET = 14409; | ||
431 | [ScriptConstant] | ||
432 | public const int PHYS_PARAM_ENABLE_TRANSMOTOR = 14410; | ||
433 | [ScriptConstant] | ||
434 | public const int PHYS_PARAM_TRANSMOTOR_MAXVEL = 14411; | ||
435 | [ScriptConstant] | ||
436 | public const int PHYS_PARAM_TRANSMOTOR_MAXFORCE = 14412; | ||
437 | [ScriptConstant] | ||
438 | public const int PHYS_PARAM_CFM = 14413; | ||
439 | [ScriptConstant] | ||
440 | public const int PHYS_PARAM_ERP = 14414; | ||
441 | [ScriptConstant] | ||
442 | public const int PHYS_PARAM_SOLVER_ITERATIONS = 14415; | ||
443 | [ScriptConstant] | ||
444 | public const int PHYS_PARAM_SPRING_AXIS_ENABLE = 14416; | ||
445 | [ScriptConstant] | ||
446 | public const int PHYS_PARAM_SPRING_DAMPING = 14417; | ||
447 | [ScriptConstant] | ||
448 | public const int PHYS_PARAM_SPRING_STIFFNESS = 14418; | ||
449 | [ScriptConstant] | ||
450 | public const int PHYS_PARAM_LINK_TYPE = 14419; | ||
451 | [ScriptConstant] | ||
452 | public const int PHYS_PARAM_USE_LINEAR_FRAMEA = 14420; | ||
453 | [ScriptConstant] | ||
454 | public const int PHYS_PARAM_SPRING_EQUILIBRIUM_POINT = 14421; | ||
455 | |||
456 | public const int PHYS_PARAM_MAX = 14421; | ||
457 | |||
458 | // Used when specifying a parameter that has settings for the three linear and three angular axis | ||
459 | [ScriptConstant] | ||
460 | public const int PHYS_AXIS_ALL = -1; | ||
461 | [ScriptConstant] | ||
462 | public const int PHYS_AXIS_LINEAR_ALL = -2; | ||
463 | [ScriptConstant] | ||
464 | public const int PHYS_AXIS_ANGULAR_ALL = -3; | ||
465 | [ScriptConstant] | ||
466 | public const int PHYS_AXIS_LINEAR_X = 0; | ||
467 | [ScriptConstant] | ||
468 | public const int PHYS_AXIS_LINEAR_Y = 1; | ||
469 | [ScriptConstant] | ||
470 | public const int PHYS_AXIS_LINEAR_Z = 2; | ||
471 | [ScriptConstant] | ||
472 | public const int PHYS_AXIS_ANGULAR_X = 3; | ||
473 | [ScriptConstant] | ||
474 | public const int PHYS_AXIS_ANGULAR_Y = 4; | ||
475 | [ScriptConstant] | ||
476 | public const int PHYS_AXIS_ANGULAR_Z = 5; | ||
477 | |||
478 | // physChangeLinkParams(integer linkNum, [ PHYS_PARAM_*, value, PHYS_PARAM_*, value, ...]) | ||
479 | [ScriptInvocation] | ||
480 | public int physChangeLinkParams(UUID hostID, UUID scriptID, int linkNum, object[] parms) | ||
481 | { | ||
482 | int ret = -1; | ||
483 | if (!Enabled) return ret; | ||
484 | |||
485 | PhysicsActor rootPhysActor; | ||
486 | PhysicsActor childPhysActor; | ||
487 | |||
488 | if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor)) | ||
489 | { | ||
490 | object[] parms2 = AddToBeginningOfArray(rootPhysActor, childPhysActor, parms); | ||
491 | ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkParams, parms2)); | ||
492 | } | ||
493 | |||
494 | return ret; | ||
495 | } | ||
496 | |||
497 | private bool GetRootPhysActor(UUID hostID, out PhysicsActor rootPhysActor) | ||
498 | { | ||
499 | SceneObjectGroup containingGroup; | ||
500 | SceneObjectPart rootPart; | ||
501 | return GetRootPhysActor(hostID, out containingGroup, out rootPart, out rootPhysActor); | ||
502 | } | ||
503 | |||
504 | private bool GetRootPhysActor(UUID hostID, out SceneObjectGroup containingGroup, out SceneObjectPart rootPart, out PhysicsActor rootPhysActor) | ||
505 | { | ||
506 | bool ret = false; | ||
507 | rootPhysActor = null; | ||
508 | containingGroup = null; | ||
509 | rootPart = null; | ||
510 | |||
511 | SceneObjectPart requestingPart; | ||
512 | |||
513 | requestingPart = BaseScene.GetSceneObjectPart(hostID); | ||
514 | if (requestingPart != null) | ||
515 | { | ||
516 | // The type is is always on the root of a linkset. | ||
517 | containingGroup = requestingPart.ParentGroup; | ||
518 | if (containingGroup != null && !containingGroup.IsDeleted) | ||
519 | { | ||
520 | rootPart = containingGroup.RootPart; | ||
521 | if (rootPart != null) | ||
522 | { | ||
523 | rootPhysActor = rootPart.PhysActor; | ||
524 | if (rootPhysActor != null) | ||
525 | { | ||
526 | ret = true; | ||
527 | } | ||
528 | else | ||
529 | { | ||
530 | m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}", | ||
531 | LogHeader, rootPart.Name, hostID); | ||
532 | } | ||
533 | } | ||
534 | else | ||
535 | { | ||
536 | m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not exist. RequestingPartName={1}, hostID={2}", | ||
537 | LogHeader, requestingPart.Name, hostID); | ||
538 | } | ||
539 | } | ||
540 | else | ||
541 | { | ||
542 | m_log.WarnFormat("{0} GetRootAndChildPhysActors: Containing group missing or deleted. hostID={1}", LogHeader, hostID); | ||
543 | } | ||
544 | } | ||
545 | else | ||
546 | { | ||
547 | m_log.WarnFormat("{0} GetRootAndChildPhysActors: cannot find script object in scene. hostID={1}", LogHeader, hostID); | ||
548 | } | ||
549 | |||
550 | return ret; | ||
551 | } | ||
552 | |||
553 | // Find the root and child PhysActors based on the linkNum. | ||
554 | // Return 'true' if both are found and returned. | ||
555 | private bool GetRootAndChildPhysActors(UUID hostID, int linkNum, out PhysicsActor rootPhysActor, out PhysicsActor childPhysActor) | ||
556 | { | ||
557 | bool ret = false; | ||
558 | rootPhysActor = null; | ||
559 | childPhysActor = null; | ||
560 | |||
561 | SceneObjectGroup containingGroup; | ||
562 | SceneObjectPart rootPart; | ||
563 | |||
564 | if (GetRootPhysActor(hostID, out containingGroup, out rootPart, out rootPhysActor)) | ||
565 | { | ||
566 | SceneObjectPart linkPart = containingGroup.GetLinkNumPart(linkNum); | ||
567 | if (linkPart != null) | ||
568 | { | ||
569 | childPhysActor = linkPart.PhysActor; | ||
570 | if (childPhysActor != null) | ||
571 | { | ||
572 | ret = true; | ||
573 | } | ||
574 | else | ||
575 | { | ||
576 | m_log.WarnFormat("{0} GetRootAndChildPhysActors: Link part has no physical actor. rootName={1}, hostID={2}, linknum={3}", | ||
577 | LogHeader, rootPart.Name, hostID, linkNum); | ||
578 | } | ||
579 | } | ||
580 | else | ||
581 | { | ||
582 | m_log.WarnFormat("{0} GetRootAndChildPhysActors: Could not find linknum part. rootName={1}, hostID={2}, linknum={3}", | ||
583 | LogHeader, rootPart.Name, hostID, linkNum); | ||
584 | } | ||
585 | } | ||
586 | else | ||
587 | { | ||
588 | m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}", | ||
589 | LogHeader, rootPart.Name, hostID); | ||
590 | } | ||
591 | |||
592 | return ret; | ||
593 | } | ||
594 | |||
595 | // Return an array of objects with the passed object as the first object of a new array | ||
596 | private object[] AddToBeginningOfArray(object firstOne, object secondOne, object[] prevArray) | ||
597 | { | ||
598 | object[] newArray = new object[2 + prevArray.Length]; | ||
599 | newArray[0] = firstOne; | ||
600 | newArray[1] = secondOne; | ||
601 | prevArray.CopyTo(newArray, 2); | ||
602 | return newArray; | ||
603 | } | ||
604 | |||
605 | // Extension() returns an object. Convert that object into the integer error we expect to return. | ||
606 | private int MakeIntError(object extensionRet) | ||
607 | { | ||
608 | int ret = -1; | ||
609 | if (extensionRet != null) | ||
610 | { | ||
611 | try | ||
612 | { | ||
613 | ret = (int)extensionRet; | ||
614 | } | ||
615 | catch | ||
616 | { | ||
617 | ret = -1; | ||
618 | } | ||
619 | } | ||
620 | return ret; | ||
621 | } | ||
622 | } | ||
623 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs new file mode 100644 index 0000000..c38bb3e --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs | |||
@@ -0,0 +1,765 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors | ||
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 OpenSim 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 | using Mono.Addins; | ||
28 | |||
29 | using System; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | using System.Text; | ||
33 | using System.Net; | ||
34 | using System.Net.Sockets; | ||
35 | using log4net; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenMetaverse.StructuredData; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Region.Framework.Interfaces; | ||
41 | using OpenSim.Region.Framework.Scenes; | ||
42 | using System.Collections.Generic; | ||
43 | using System.Text.RegularExpressions; | ||
44 | |||
45 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | ||
46 | { | ||
47 | public class JsonStore | ||
48 | { | ||
49 | private static readonly ILog m_log = | ||
50 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
51 | |||
52 | protected virtual OSD ValueStore { get; set; } | ||
53 | |||
54 | protected class TakeValueCallbackClass | ||
55 | { | ||
56 | public string Path { get; set; } | ||
57 | public bool UseJson { get; set; } | ||
58 | public TakeValueCallback Callback { get; set; } | ||
59 | |||
60 | public TakeValueCallbackClass(string spath, bool usejson, TakeValueCallback cback) | ||
61 | { | ||
62 | Path = spath; | ||
63 | UseJson = usejson; | ||
64 | Callback = cback; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | protected List<TakeValueCallbackClass> m_TakeStore; | ||
69 | protected List<TakeValueCallbackClass> m_ReadStore; | ||
70 | |||
71 | // add separators for quoted paths and array references | ||
72 | protected static Regex m_ParsePassOne = new Regex("({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])"); | ||
73 | |||
74 | // add quotes to bare identifiers which are limited to alphabetic characters | ||
75 | protected static Regex m_ParsePassThree = new Regex("(?<!{[^}]*)\\.([a-zA-Z]+)(?=\\.)"); | ||
76 | |||
77 | // remove extra separator characters | ||
78 | protected static Regex m_ParsePassFour = new Regex("\\.+"); | ||
79 | |||
80 | // expression used to validate the full path, this is canonical representation | ||
81 | protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)*$"); | ||
82 | |||
83 | // expression used to match path components | ||
84 | protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])"); | ||
85 | |||
86 | // extract the internals of an array reference | ||
87 | protected static Regex m_SimpleArrayPattern = new Regex("^\\[([0-9]+)\\]$"); | ||
88 | protected static Regex m_ArrayPattern = new Regex("^\\[([0-9]+|\\+)\\]$"); | ||
89 | |||
90 | // extract the internals of a has reference | ||
91 | protected static Regex m_HashPattern = new Regex("^{([^}]+)}$"); | ||
92 | |||
93 | // ----------------------------------------------------------------- | ||
94 | /// <summary> | ||
95 | /// This is a simple estimator for the size of the stored data, it | ||
96 | /// is not precise, but should be close enough to implement reasonable | ||
97 | /// limits on the storage space used | ||
98 | /// </summary> | ||
99 | // ----------------------------------------------------------------- | ||
100 | public int StringSpace { get; set; } | ||
101 | |||
102 | // ----------------------------------------------------------------- | ||
103 | /// <summary> | ||
104 | /// | ||
105 | /// </summary> | ||
106 | // ----------------------------------------------------------------- | ||
107 | public static bool CanonicalPathExpression(string ipath, out string opath) | ||
108 | { | ||
109 | Stack<string> path; | ||
110 | if (! ParsePathExpression(ipath,out path)) | ||
111 | { | ||
112 | opath = ""; | ||
113 | return false; | ||
114 | } | ||
115 | |||
116 | opath = PathExpressionToKey(path); | ||
117 | return true; | ||
118 | } | ||
119 | |||
120 | // ----------------------------------------------------------------- | ||
121 | /// <summary> | ||
122 | /// | ||
123 | /// </summary> | ||
124 | // ----------------------------------------------------------------- | ||
125 | public JsonStore() | ||
126 | { | ||
127 | StringSpace = 0; | ||
128 | m_TakeStore = new List<TakeValueCallbackClass>(); | ||
129 | m_ReadStore = new List<TakeValueCallbackClass>(); | ||
130 | } | ||
131 | |||
132 | public JsonStore(string value) : this() | ||
133 | { | ||
134 | // This is going to throw an exception if the value is not | ||
135 | // a valid JSON chunk. Calling routines should catch the | ||
136 | // exception and handle it appropriately | ||
137 | if (String.IsNullOrEmpty(value)) | ||
138 | ValueStore = new OSDMap(); | ||
139 | else | ||
140 | ValueStore = OSDParser.DeserializeJson(value); | ||
141 | } | ||
142 | |||
143 | // ----------------------------------------------------------------- | ||
144 | /// <summary> | ||
145 | /// | ||
146 | /// </summary> | ||
147 | // ----------------------------------------------------------------- | ||
148 | public JsonStoreNodeType GetNodeType(string expr) | ||
149 | { | ||
150 | Stack<string> path; | ||
151 | if (! ParsePathExpression(expr,out path)) | ||
152 | return JsonStoreNodeType.Undefined; | ||
153 | |||
154 | OSD result = ProcessPathExpression(ValueStore,path); | ||
155 | |||
156 | if (result == null) | ||
157 | return JsonStoreNodeType.Undefined; | ||
158 | |||
159 | if (result is OSDMap) | ||
160 | return JsonStoreNodeType.Object; | ||
161 | |||
162 | if (result is OSDArray) | ||
163 | return JsonStoreNodeType.Array; | ||
164 | |||
165 | if (OSDBaseType(result.Type)) | ||
166 | return JsonStoreNodeType.Value; | ||
167 | |||
168 | return JsonStoreNodeType.Undefined; | ||
169 | } | ||
170 | |||
171 | // ----------------------------------------------------------------- | ||
172 | /// <summary> | ||
173 | /// | ||
174 | /// </summary> | ||
175 | // ----------------------------------------------------------------- | ||
176 | public JsonStoreValueType GetValueType(string expr) | ||
177 | { | ||
178 | Stack<string> path; | ||
179 | if (! ParsePathExpression(expr,out path)) | ||
180 | return JsonStoreValueType.Undefined; | ||
181 | |||
182 | OSD result = ProcessPathExpression(ValueStore,path); | ||
183 | |||
184 | if (result == null) | ||
185 | return JsonStoreValueType.Undefined; | ||
186 | |||
187 | if (result is OSDMap) | ||
188 | return JsonStoreValueType.Undefined; | ||
189 | |||
190 | if (result is OSDArray) | ||
191 | return JsonStoreValueType.Undefined; | ||
192 | |||
193 | if (result is OSDBoolean) | ||
194 | return JsonStoreValueType.Boolean; | ||
195 | |||
196 | if (result is OSDInteger) | ||
197 | return JsonStoreValueType.Integer; | ||
198 | |||
199 | if (result is OSDReal) | ||
200 | return JsonStoreValueType.Float; | ||
201 | |||
202 | if (result is OSDString) | ||
203 | return JsonStoreValueType.String; | ||
204 | |||
205 | return JsonStoreValueType.Undefined; | ||
206 | } | ||
207 | |||
208 | // ----------------------------------------------------------------- | ||
209 | /// <summary> | ||
210 | /// | ||
211 | /// </summary> | ||
212 | // ----------------------------------------------------------------- | ||
213 | public int ArrayLength(string expr) | ||
214 | { | ||
215 | Stack<string> path; | ||
216 | if (! ParsePathExpression(expr,out path)) | ||
217 | return -1; | ||
218 | |||
219 | OSD result = ProcessPathExpression(ValueStore,path); | ||
220 | if (result != null && result.Type == OSDType.Array) | ||
221 | { | ||
222 | OSDArray arr = result as OSDArray; | ||
223 | return arr.Count; | ||
224 | } | ||
225 | |||
226 | return -1; | ||
227 | } | ||
228 | |||
229 | // ----------------------------------------------------------------- | ||
230 | /// <summary> | ||
231 | /// | ||
232 | /// </summary> | ||
233 | // ----------------------------------------------------------------- | ||
234 | public bool GetValue(string expr, out string value, bool useJson) | ||
235 | { | ||
236 | Stack<string> path; | ||
237 | if (! ParsePathExpression(expr,out path)) | ||
238 | { | ||
239 | value = ""; | ||
240 | return false; | ||
241 | } | ||
242 | |||
243 | OSD result = ProcessPathExpression(ValueStore,path); | ||
244 | return ConvertOutputValue(result,out value,useJson); | ||
245 | } | ||
246 | |||
247 | |||
248 | // ----------------------------------------------------------------- | ||
249 | /// <summary> | ||
250 | /// | ||
251 | /// </summary> | ||
252 | // ----------------------------------------------------------------- | ||
253 | public bool RemoveValue(string expr) | ||
254 | { | ||
255 | return SetValueFromExpression(expr,null); | ||
256 | } | ||
257 | |||
258 | // ----------------------------------------------------------------- | ||
259 | /// <summary> | ||
260 | /// | ||
261 | /// </summary> | ||
262 | // ----------------------------------------------------------------- | ||
263 | public bool SetValue(string expr, string value, bool useJson) | ||
264 | { | ||
265 | OSD ovalue; | ||
266 | |||
267 | // One note of caution... if you use an empty string in the | ||
268 | // structure it will be assumed to be a default value and will | ||
269 | // not be seialized in the json | ||
270 | |||
271 | if (useJson) | ||
272 | { | ||
273 | // There doesn't appear to be a good way to determine if the | ||
274 | // value is valid Json other than to let the parser crash | ||
275 | try | ||
276 | { | ||
277 | ovalue = OSDParser.DeserializeJson(value); | ||
278 | } | ||
279 | catch (Exception) | ||
280 | { | ||
281 | if (value.StartsWith("'") && value.EndsWith("'")) | ||
282 | { | ||
283 | ovalue = new OSDString(value.Substring(1,value.Length - 2)); | ||
284 | } | ||
285 | else | ||
286 | { | ||
287 | return false; | ||
288 | } | ||
289 | } | ||
290 | } | ||
291 | else | ||
292 | { | ||
293 | ovalue = new OSDString(value); | ||
294 | } | ||
295 | |||
296 | return SetValueFromExpression(expr,ovalue); | ||
297 | } | ||
298 | |||
299 | // ----------------------------------------------------------------- | ||
300 | /// <summary> | ||
301 | /// | ||
302 | /// </summary> | ||
303 | // ----------------------------------------------------------------- | ||
304 | public bool TakeValue(string expr, bool useJson, TakeValueCallback cback) | ||
305 | { | ||
306 | Stack<string> path; | ||
307 | if (! ParsePathExpression(expr,out path)) | ||
308 | return false; | ||
309 | |||
310 | string pexpr = PathExpressionToKey(path); | ||
311 | |||
312 | OSD result = ProcessPathExpression(ValueStore,path); | ||
313 | if (result == null) | ||
314 | { | ||
315 | m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); | ||
316 | return false; | ||
317 | } | ||
318 | |||
319 | string value = String.Empty; | ||
320 | if (! ConvertOutputValue(result,out value,useJson)) | ||
321 | { | ||
322 | // the structure does not match the request so i guess we'll wait | ||
323 | m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); | ||
324 | return false; | ||
325 | } | ||
326 | |||
327 | SetValueFromExpression(expr,null); | ||
328 | cback(value); | ||
329 | |||
330 | return true; | ||
331 | } | ||
332 | |||
333 | // ----------------------------------------------------------------- | ||
334 | /// <summary> | ||
335 | /// | ||
336 | /// </summary> | ||
337 | // ----------------------------------------------------------------- | ||
338 | public bool ReadValue(string expr, bool useJson, TakeValueCallback cback) | ||
339 | { | ||
340 | Stack<string> path; | ||
341 | if (! ParsePathExpression(expr,out path)) | ||
342 | return false; | ||
343 | |||
344 | string pexpr = PathExpressionToKey(path); | ||
345 | |||
346 | OSD result = ProcessPathExpression(ValueStore,path); | ||
347 | if (result == null) | ||
348 | { | ||
349 | m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); | ||
350 | return false; | ||
351 | } | ||
352 | |||
353 | string value = String.Empty; | ||
354 | if (! ConvertOutputValue(result,out value,useJson)) | ||
355 | { | ||
356 | // the structure does not match the request so i guess we'll wait | ||
357 | m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); | ||
358 | return false; | ||
359 | } | ||
360 | |||
361 | cback(value); | ||
362 | |||
363 | return true; | ||
364 | } | ||
365 | |||
366 | // ----------------------------------------------------------------- | ||
367 | /// <summary> | ||
368 | /// | ||
369 | /// </summary> | ||
370 | // ----------------------------------------------------------------- | ||
371 | protected bool SetValueFromExpression(string expr, OSD ovalue) | ||
372 | { | ||
373 | Stack<string> path; | ||
374 | if (! ParsePathExpression(expr,out path)) | ||
375 | return false; | ||
376 | |||
377 | if (path.Count == 0) | ||
378 | { | ||
379 | ValueStore = ovalue; | ||
380 | StringSpace = 0; | ||
381 | return true; | ||
382 | } | ||
383 | |||
384 | // pkey will be the final element in the path, we pull it out here to make sure | ||
385 | // that the assignment works correctly | ||
386 | string pkey = path.Pop(); | ||
387 | string pexpr = PathExpressionToKey(path); | ||
388 | if (pexpr != "") | ||
389 | pexpr += "."; | ||
390 | |||
391 | OSD result = ProcessPathExpression(ValueStore,path); | ||
392 | if (result == null) | ||
393 | return false; | ||
394 | |||
395 | // Check pkey, the last element in the path, for and extract array references | ||
396 | MatchCollection amatches = m_ArrayPattern.Matches(pkey,0); | ||
397 | if (amatches.Count > 0) | ||
398 | { | ||
399 | if (result.Type != OSDType.Array) | ||
400 | return false; | ||
401 | |||
402 | OSDArray amap = result as OSDArray; | ||
403 | |||
404 | Match match = amatches[0]; | ||
405 | GroupCollection groups = match.Groups; | ||
406 | string akey = groups[1].Value; | ||
407 | |||
408 | if (akey == "+") | ||
409 | { | ||
410 | string npkey = String.Format("[{0}]",amap.Count); | ||
411 | |||
412 | if (ovalue != null) | ||
413 | { | ||
414 | StringSpace += ComputeSizeOf(ovalue); | ||
415 | |||
416 | amap.Add(ovalue); | ||
417 | InvokeNextCallback(pexpr + npkey); | ||
418 | } | ||
419 | return true; | ||
420 | } | ||
421 | |||
422 | int aval = Convert.ToInt32(akey); | ||
423 | if (0 <= aval && aval < amap.Count) | ||
424 | { | ||
425 | if (ovalue == null) | ||
426 | { | ||
427 | StringSpace -= ComputeSizeOf(amap[aval]); | ||
428 | amap.RemoveAt(aval); | ||
429 | } | ||
430 | else | ||
431 | { | ||
432 | StringSpace -= ComputeSizeOf(amap[aval]); | ||
433 | StringSpace += ComputeSizeOf(ovalue); | ||
434 | amap[aval] = ovalue; | ||
435 | InvokeNextCallback(pexpr + pkey); | ||
436 | } | ||
437 | return true; | ||
438 | } | ||
439 | |||
440 | return false; | ||
441 | } | ||
442 | |||
443 | // Check for and extract hash references | ||
444 | MatchCollection hmatches = m_HashPattern.Matches(pkey,0); | ||
445 | if (hmatches.Count > 0) | ||
446 | { | ||
447 | Match match = hmatches[0]; | ||
448 | GroupCollection groups = match.Groups; | ||
449 | string hkey = groups[1].Value; | ||
450 | |||
451 | if (result is OSDMap) | ||
452 | { | ||
453 | // this is the assignment case | ||
454 | OSDMap hmap = result as OSDMap; | ||
455 | if (ovalue != null) | ||
456 | { | ||
457 | StringSpace -= ComputeSizeOf(hmap[hkey]); | ||
458 | StringSpace += ComputeSizeOf(ovalue); | ||
459 | |||
460 | hmap[hkey] = ovalue; | ||
461 | InvokeNextCallback(pexpr + pkey); | ||
462 | return true; | ||
463 | } | ||
464 | |||
465 | // this is the remove case | ||
466 | if (hmap.ContainsKey(hkey)) | ||
467 | { | ||
468 | StringSpace -= ComputeSizeOf(hmap[hkey]); | ||
469 | hmap.Remove(hkey); | ||
470 | return true; | ||
471 | } | ||
472 | |||
473 | return false; | ||
474 | } | ||
475 | |||
476 | return false; | ||
477 | } | ||
478 | |||
479 | // Shouldn't get here if the path was checked correctly | ||
480 | m_log.WarnFormat("[JsonStore] invalid path expression"); | ||
481 | return false; | ||
482 | } | ||
483 | |||
484 | // ----------------------------------------------------------------- | ||
485 | /// <summary> | ||
486 | /// | ||
487 | /// </summary> | ||
488 | // ----------------------------------------------------------------- | ||
489 | protected bool InvokeNextCallback(string pexpr) | ||
490 | { | ||
491 | // Process all of the reads that match the expression first | ||
492 | List<TakeValueCallbackClass> reads = | ||
493 | m_ReadStore.FindAll(delegate(TakeValueCallbackClass tb) { return pexpr.StartsWith(tb.Path); }); | ||
494 | |||
495 | foreach (TakeValueCallbackClass readcb in reads) | ||
496 | { | ||
497 | m_ReadStore.Remove(readcb); | ||
498 | ReadValue(readcb.Path,readcb.UseJson,readcb.Callback); | ||
499 | } | ||
500 | |||
501 | // Process one take next | ||
502 | TakeValueCallbackClass takecb = | ||
503 | m_TakeStore.Find(delegate(TakeValueCallbackClass tb) { return pexpr.StartsWith(tb.Path); }); | ||
504 | |||
505 | if (takecb != null) | ||
506 | { | ||
507 | m_TakeStore.Remove(takecb); | ||
508 | TakeValue(takecb.Path,takecb.UseJson,takecb.Callback); | ||
509 | |||
510 | return true; | ||
511 | } | ||
512 | |||
513 | return false; | ||
514 | } | ||
515 | |||
516 | // ----------------------------------------------------------------- | ||
517 | /// <summary> | ||
518 | /// Parse the path expression and put the components into a stack. We | ||
519 | /// use a stack because we process the path in inverse order later | ||
520 | /// </summary> | ||
521 | // ----------------------------------------------------------------- | ||
522 | protected static bool ParsePathExpression(string expr, out Stack<string> path) | ||
523 | { | ||
524 | path = new Stack<string>(); | ||
525 | |||
526 | // add front and rear separators | ||
527 | expr = "." + expr + "."; | ||
528 | |||
529 | // add separators for quoted exprs and array references | ||
530 | expr = m_ParsePassOne.Replace(expr,".$1.",-1,0); | ||
531 | |||
532 | // add quotes to bare identifier | ||
533 | expr = m_ParsePassThree.Replace(expr,".{$1}",-1,0); | ||
534 | |||
535 | // remove extra separators | ||
536 | expr = m_ParsePassFour.Replace(expr,".",-1,0); | ||
537 | |||
538 | // validate the results (catches extra quote characters for example) | ||
539 | if (m_ValidatePath.IsMatch(expr)) | ||
540 | { | ||
541 | MatchCollection matches = m_PathComponent.Matches(expr,0); | ||
542 | foreach (Match match in matches) | ||
543 | path.Push(match.Groups[1].Value); | ||
544 | |||
545 | return true; | ||
546 | } | ||
547 | |||
548 | return false; | ||
549 | } | ||
550 | |||
551 | // ----------------------------------------------------------------- | ||
552 | /// <summary> | ||
553 | /// | ||
554 | /// </summary> | ||
555 | /// <param>path is a stack where the top level of the path is at the bottom of the stack</param> | ||
556 | // ----------------------------------------------------------------- | ||
557 | protected static OSD ProcessPathExpression(OSD map, Stack<string> path) | ||
558 | { | ||
559 | if (path.Count == 0) | ||
560 | return map; | ||
561 | |||
562 | string pkey = path.Pop(); | ||
563 | |||
564 | OSD rmap = ProcessPathExpression(map,path); | ||
565 | if (rmap == null) | ||
566 | return null; | ||
567 | |||
568 | // ---------- Check for an array index ---------- | ||
569 | MatchCollection amatches = m_SimpleArrayPattern.Matches(pkey,0); | ||
570 | |||
571 | if (amatches.Count > 0) | ||
572 | { | ||
573 | if (rmap.Type != OSDType.Array) | ||
574 | { | ||
575 | m_log.WarnFormat("[JsonStore] wrong type for key {2}, expecting {0}, got {1}",OSDType.Array,rmap.Type,pkey); | ||
576 | return null; | ||
577 | } | ||
578 | |||
579 | OSDArray amap = rmap as OSDArray; | ||
580 | |||
581 | Match match = amatches[0]; | ||
582 | GroupCollection groups = match.Groups; | ||
583 | string akey = groups[1].Value; | ||
584 | int aval = Convert.ToInt32(akey); | ||
585 | |||
586 | if (aval < amap.Count) | ||
587 | return (OSD) amap[aval]; | ||
588 | |||
589 | return null; | ||
590 | } | ||
591 | |||
592 | // ---------- Check for a hash index ---------- | ||
593 | MatchCollection hmatches = m_HashPattern.Matches(pkey,0); | ||
594 | |||
595 | if (hmatches.Count > 0) | ||
596 | { | ||
597 | if (rmap.Type != OSDType.Map) | ||
598 | { | ||
599 | m_log.WarnFormat("[JsonStore] wrong type for key {2}, expecting {0}, got {1}",OSDType.Map,rmap.Type,pkey); | ||
600 | return null; | ||
601 | } | ||
602 | |||
603 | OSDMap hmap = rmap as OSDMap; | ||
604 | |||
605 | Match match = hmatches[0]; | ||
606 | GroupCollection groups = match.Groups; | ||
607 | string hkey = groups[1].Value; | ||
608 | |||
609 | if (hmap.ContainsKey(hkey)) | ||
610 | return (OSD) hmap[hkey]; | ||
611 | |||
612 | return null; | ||
613 | } | ||
614 | |||
615 | // Shouldn't get here if the path was checked correctly | ||
616 | m_log.WarnFormat("[JsonStore] Path type (unknown) does not match the structure"); | ||
617 | return null; | ||
618 | } | ||
619 | |||
620 | // ----------------------------------------------------------------- | ||
621 | /// <summary> | ||
622 | /// | ||
623 | /// </summary> | ||
624 | // ----------------------------------------------------------------- | ||
625 | protected static bool ConvertOutputValue(OSD result, out string value, bool useJson) | ||
626 | { | ||
627 | value = String.Empty; | ||
628 | |||
629 | // If we couldn't process the path | ||
630 | if (result == null) | ||
631 | return false; | ||
632 | |||
633 | if (useJson) | ||
634 | { | ||
635 | // The path pointed to an intermediate hash structure | ||
636 | if (result.Type == OSDType.Map) | ||
637 | { | ||
638 | value = OSDParser.SerializeJsonString(result as OSDMap,true); | ||
639 | return true; | ||
640 | } | ||
641 | |||
642 | // The path pointed to an intermediate hash structure | ||
643 | if (result.Type == OSDType.Array) | ||
644 | { | ||
645 | value = OSDParser.SerializeJsonString(result as OSDArray,true); | ||
646 | return true; | ||
647 | } | ||
648 | |||
649 | value = "'" + result.AsString() + "'"; | ||
650 | return true; | ||
651 | } | ||
652 | |||
653 | if (OSDBaseType(result.Type)) | ||
654 | { | ||
655 | value = result.AsString(); | ||
656 | return true; | ||
657 | } | ||
658 | |||
659 | return false; | ||
660 | } | ||
661 | |||
662 | // ----------------------------------------------------------------- | ||
663 | /// <summary> | ||
664 | /// | ||
665 | /// </summary> | ||
666 | // ----------------------------------------------------------------- | ||
667 | protected static string PathExpressionToKey(Stack<string> path) | ||
668 | { | ||
669 | if (path.Count == 0) | ||
670 | return ""; | ||
671 | |||
672 | string pkey = ""; | ||
673 | foreach (string k in path) | ||
674 | pkey = (pkey == "") ? k : (k + "." + pkey); | ||
675 | |||
676 | return pkey; | ||
677 | } | ||
678 | |||
679 | // ----------------------------------------------------------------- | ||
680 | /// <summary> | ||
681 | /// | ||
682 | /// </summary> | ||
683 | // ----------------------------------------------------------------- | ||
684 | protected static bool OSDBaseType(OSDType type) | ||
685 | { | ||
686 | // Should be the list of base types for which AsString() returns | ||
687 | // something useful | ||
688 | if (type == OSDType.Boolean) | ||
689 | return true; | ||
690 | if (type == OSDType.Integer) | ||
691 | return true; | ||
692 | if (type == OSDType.Real) | ||
693 | return true; | ||
694 | if (type == OSDType.String) | ||
695 | return true; | ||
696 | if (type == OSDType.UUID) | ||
697 | return true; | ||
698 | if (type == OSDType.Date) | ||
699 | return true; | ||
700 | if (type == OSDType.URI) | ||
701 | return true; | ||
702 | |||
703 | return false; | ||
704 | } | ||
705 | |||
706 | // ----------------------------------------------------------------- | ||
707 | /// <summary> | ||
708 | /// | ||
709 | /// </summary> | ||
710 | // ----------------------------------------------------------------- | ||
711 | protected static int ComputeSizeOf(OSD value) | ||
712 | { | ||
713 | string sval; | ||
714 | |||
715 | if (ConvertOutputValue(value,out sval,true)) | ||
716 | return sval.Length; | ||
717 | |||
718 | return 0; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | // ----------------------------------------------------------------- | ||
723 | /// <summary> | ||
724 | /// </summary> | ||
725 | // ----------------------------------------------------------------- | ||
726 | public class JsonObjectStore : JsonStore | ||
727 | { | ||
728 | private static readonly ILog m_log = | ||
729 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
730 | |||
731 | private Scene m_scene; | ||
732 | private UUID m_objectID; | ||
733 | |||
734 | protected override OSD ValueStore | ||
735 | { | ||
736 | get | ||
737 | { | ||
738 | SceneObjectPart sop = m_scene.GetSceneObjectPart(m_objectID); | ||
739 | if (sop == null) | ||
740 | { | ||
741 | // This is bad | ||
742 | return null; | ||
743 | } | ||
744 | |||
745 | return sop.DynAttrs.TopLevelMap; | ||
746 | } | ||
747 | |||
748 | // cannot set the top level | ||
749 | set | ||
750 | { | ||
751 | m_log.InfoFormat("[JsonStore] cannot set top level value in object store"); | ||
752 | } | ||
753 | } | ||
754 | |||
755 | public JsonObjectStore(Scene scene, UUID oid) : base() | ||
756 | { | ||
757 | m_scene = scene; | ||
758 | m_objectID = oid; | ||
759 | |||
760 | // the size limit is imposed on whatever is already in the store | ||
761 | StringSpace = ComputeSizeOf(ValueStore); | ||
762 | } | ||
763 | } | ||
764 | |||
765 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreCommands.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreCommands.cs new file mode 100644 index 0000000..d4b19dd --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreCommands.cs | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors | ||
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 OpenSim 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 | using Mono.Addins; | ||
28 | |||
29 | using System; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | using System.Text; | ||
33 | using System.Net; | ||
34 | using System.Net.Sockets; | ||
35 | using log4net; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenMetaverse.StructuredData; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Region.Framework.Interfaces; | ||
41 | using OpenSim.Region.Framework.Scenes; | ||
42 | using System.Collections.Generic; | ||
43 | using System.Text.RegularExpressions; | ||
44 | |||
45 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | ||
46 | { | ||
47 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreCommandsModule")] | ||
48 | |||
49 | public class JsonStoreCommandsModule : INonSharedRegionModule | ||
50 | { | ||
51 | private static readonly ILog m_log = | ||
52 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | |||
54 | private IConfig m_config = null; | ||
55 | private bool m_enabled = false; | ||
56 | |||
57 | private Scene m_scene = null; | ||
58 | //private IJsonStoreModule m_store; | ||
59 | private JsonStoreModule m_store; | ||
60 | |||
61 | #region Region Module interface | ||
62 | |||
63 | // ----------------------------------------------------------------- | ||
64 | /// <summary> | ||
65 | /// Name of this shared module is it's class name | ||
66 | /// </summary> | ||
67 | // ----------------------------------------------------------------- | ||
68 | public string Name | ||
69 | { | ||
70 | get { return this.GetType().Name; } | ||
71 | } | ||
72 | |||
73 | // ----------------------------------------------------------------- | ||
74 | /// <summary> | ||
75 | /// Initialise this shared module | ||
76 | /// </summary> | ||
77 | /// <param name="scene">this region is getting initialised</param> | ||
78 | /// <param name="source">nini config, we are not using this</param> | ||
79 | // ----------------------------------------------------------------- | ||
80 | public void Initialise(IConfigSource config) | ||
81 | { | ||
82 | try | ||
83 | { | ||
84 | if ((m_config = config.Configs["JsonStore"]) == null) | ||
85 | { | ||
86 | // There is no configuration, the module is disabled | ||
87 | // m_log.InfoFormat("[JsonStore] no configuration info"); | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | m_enabled = m_config.GetBoolean("Enabled", m_enabled); | ||
92 | } | ||
93 | catch (Exception e) | ||
94 | { | ||
95 | m_log.Error("[JsonStore]: initialization error: {0}", e); | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | if (m_enabled) | ||
100 | m_log.DebugFormat("[JsonStore]: module is enabled"); | ||
101 | } | ||
102 | |||
103 | // ----------------------------------------------------------------- | ||
104 | /// <summary> | ||
105 | /// everything is loaded, perform post load configuration | ||
106 | /// </summary> | ||
107 | // ----------------------------------------------------------------- | ||
108 | public void PostInitialise() | ||
109 | { | ||
110 | } | ||
111 | |||
112 | // ----------------------------------------------------------------- | ||
113 | /// <summary> | ||
114 | /// Nothing to do on close | ||
115 | /// </summary> | ||
116 | // ----------------------------------------------------------------- | ||
117 | public void Close() | ||
118 | { | ||
119 | } | ||
120 | |||
121 | // ----------------------------------------------------------------- | ||
122 | /// <summary> | ||
123 | /// </summary> | ||
124 | // ----------------------------------------------------------------- | ||
125 | public void AddRegion(Scene scene) | ||
126 | { | ||
127 | if (m_enabled) | ||
128 | { | ||
129 | m_scene = scene; | ||
130 | |||
131 | } | ||
132 | } | ||
133 | |||
134 | // ----------------------------------------------------------------- | ||
135 | /// <summary> | ||
136 | /// </summary> | ||
137 | // ----------------------------------------------------------------- | ||
138 | public void RemoveRegion(Scene scene) | ||
139 | { | ||
140 | // need to remove all references to the scene in the subscription | ||
141 | // list to enable full garbage collection of the scene object | ||
142 | } | ||
143 | |||
144 | // ----------------------------------------------------------------- | ||
145 | /// <summary> | ||
146 | /// Called when all modules have been added for a region. This is | ||
147 | /// where we hook up events | ||
148 | /// </summary> | ||
149 | // ----------------------------------------------------------------- | ||
150 | public void RegionLoaded(Scene scene) | ||
151 | { | ||
152 | if (m_enabled) | ||
153 | { | ||
154 | m_scene = scene; | ||
155 | |||
156 | m_store = (JsonStoreModule) m_scene.RequestModuleInterface<IJsonStoreModule>(); | ||
157 | if (m_store == null) | ||
158 | { | ||
159 | m_log.ErrorFormat("[JsonStoreCommands]: JsonModule interface not defined"); | ||
160 | m_enabled = false; | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | scene.AddCommand("JsonStore", this, "jsonstore stats", "jsonstore stats", | ||
165 | "Display statistics about the state of the JsonStore module", "", | ||
166 | CmdStats); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | /// ----------------------------------------------------------------- | ||
171 | /// <summary> | ||
172 | /// </summary> | ||
173 | // ----------------------------------------------------------------- | ||
174 | public Type ReplaceableInterface | ||
175 | { | ||
176 | get { return null; } | ||
177 | } | ||
178 | |||
179 | #endregion | ||
180 | |||
181 | #region Commands | ||
182 | |||
183 | private void CmdStats(string module, string[] cmd) | ||
184 | { | ||
185 | if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) | ||
186 | return; | ||
187 | |||
188 | JsonStoreStats stats = m_store.GetStoreStats(); | ||
189 | MainConsole.Instance.OutputFormat("{0}\t{1}",m_scene.RegionInfo.RegionName,stats.StoreCount); | ||
190 | } | ||
191 | |||
192 | #endregion | ||
193 | |||
194 | } | ||
195 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs new file mode 100644 index 0000000..26044f0 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs | |||
@@ -0,0 +1,584 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors | ||
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 OpenSim 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 | using Mono.Addins; | ||
28 | |||
29 | using System; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | using System.Text; | ||
33 | using System.Net; | ||
34 | using System.Net.Sockets; | ||
35 | using log4net; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenMetaverse.StructuredData; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Region.Framework.Interfaces; | ||
41 | using OpenSim.Region.Framework.Scenes; | ||
42 | using System.Collections.Generic; | ||
43 | using System.Text.RegularExpressions; | ||
44 | |||
45 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | ||
46 | { | ||
47 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreModule")] | ||
48 | |||
49 | public class JsonStoreModule : INonSharedRegionModule, IJsonStoreModule | ||
50 | { | ||
51 | private static readonly ILog m_log = | ||
52 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | |||
54 | private IConfig m_config = null; | ||
55 | private bool m_enabled = false; | ||
56 | private bool m_enableObjectStore = false; | ||
57 | private int m_maxStringSpace = Int32.MaxValue; | ||
58 | |||
59 | private Scene m_scene = null; | ||
60 | |||
61 | private Dictionary<UUID,JsonStore> m_JsonValueStore; | ||
62 | |||
63 | private UUID m_sharedStore; | ||
64 | |||
65 | #region Region Module interface | ||
66 | |||
67 | // ----------------------------------------------------------------- | ||
68 | /// <summary> | ||
69 | /// Name of this shared module is it's class name | ||
70 | /// </summary> | ||
71 | // ----------------------------------------------------------------- | ||
72 | public string Name | ||
73 | { | ||
74 | get { return this.GetType().Name; } | ||
75 | } | ||
76 | |||
77 | // ----------------------------------------------------------------- | ||
78 | /// <summary> | ||
79 | /// Initialise this shared module | ||
80 | /// </summary> | ||
81 | /// <param name="scene">this region is getting initialised</param> | ||
82 | /// <param name="source">nini config, we are not using this</param> | ||
83 | // ----------------------------------------------------------------- | ||
84 | public void Initialise(IConfigSource config) | ||
85 | { | ||
86 | try | ||
87 | { | ||
88 | if ((m_config = config.Configs["JsonStore"]) == null) | ||
89 | { | ||
90 | // There is no configuration, the module is disabled | ||
91 | // m_log.InfoFormat("[JsonStore] no configuration info"); | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | m_enabled = m_config.GetBoolean("Enabled", m_enabled); | ||
96 | m_enableObjectStore = m_config.GetBoolean("EnableObjectStore", m_enableObjectStore); | ||
97 | m_maxStringSpace = m_config.GetInt("MaxStringSpace", m_maxStringSpace); | ||
98 | if (m_maxStringSpace == 0) | ||
99 | m_maxStringSpace = Int32.MaxValue; | ||
100 | } | ||
101 | catch (Exception e) | ||
102 | { | ||
103 | m_log.Error("[JsonStore]: initialization error: {0}", e); | ||
104 | return; | ||
105 | } | ||
106 | |||
107 | if (m_enabled) | ||
108 | m_log.DebugFormat("[JsonStore]: module is enabled"); | ||
109 | } | ||
110 | |||
111 | // ----------------------------------------------------------------- | ||
112 | /// <summary> | ||
113 | /// everything is loaded, perform post load configuration | ||
114 | /// </summary> | ||
115 | // ----------------------------------------------------------------- | ||
116 | public void PostInitialise() | ||
117 | { | ||
118 | } | ||
119 | |||
120 | // ----------------------------------------------------------------- | ||
121 | /// <summary> | ||
122 | /// Nothing to do on close | ||
123 | /// </summary> | ||
124 | // ----------------------------------------------------------------- | ||
125 | public void Close() | ||
126 | { | ||
127 | } | ||
128 | |||
129 | // ----------------------------------------------------------------- | ||
130 | /// <summary> | ||
131 | /// </summary> | ||
132 | // ----------------------------------------------------------------- | ||
133 | public void AddRegion(Scene scene) | ||
134 | { | ||
135 | if (m_enabled) | ||
136 | { | ||
137 | m_scene = scene; | ||
138 | m_scene.RegisterModuleInterface<IJsonStoreModule>(this); | ||
139 | |||
140 | m_sharedStore = UUID.Zero; | ||
141 | m_JsonValueStore = new Dictionary<UUID,JsonStore>(); | ||
142 | m_JsonValueStore.Add(m_sharedStore,new JsonStore("")); | ||
143 | |||
144 | scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | // ----------------------------------------------------------------- | ||
149 | /// <summary> | ||
150 | /// </summary> | ||
151 | // ----------------------------------------------------------------- | ||
152 | public void RemoveRegion(Scene scene) | ||
153 | { | ||
154 | scene.EventManager.OnObjectBeingRemovedFromScene -= EventManagerOnObjectBeingRemovedFromScene; | ||
155 | |||
156 | // need to remove all references to the scene in the subscription | ||
157 | // list to enable full garbage collection of the scene object | ||
158 | } | ||
159 | |||
160 | // ----------------------------------------------------------------- | ||
161 | /// <summary> | ||
162 | /// Called when all modules have been added for a region. This is | ||
163 | /// where we hook up events | ||
164 | /// </summary> | ||
165 | // ----------------------------------------------------------------- | ||
166 | public void RegionLoaded(Scene scene) | ||
167 | { | ||
168 | if (m_enabled) | ||
169 | { | ||
170 | } | ||
171 | } | ||
172 | |||
173 | /// ----------------------------------------------------------------- | ||
174 | /// <summary> | ||
175 | /// </summary> | ||
176 | // ----------------------------------------------------------------- | ||
177 | public Type ReplaceableInterface | ||
178 | { | ||
179 | get { return null; } | ||
180 | } | ||
181 | |||
182 | #endregion | ||
183 | |||
184 | #region SceneEvents | ||
185 | // ----------------------------------------------------------------- | ||
186 | /// <summary> | ||
187 | /// | ||
188 | /// </summary> | ||
189 | // ----------------------------------------------------------------- | ||
190 | public void EventManagerOnObjectBeingRemovedFromScene(SceneObjectGroup obj) | ||
191 | { | ||
192 | obj.ForEachPart(delegate(SceneObjectPart sop) { DestroyStore(sop.UUID); } ); | ||
193 | } | ||
194 | |||
195 | #endregion | ||
196 | |||
197 | #region ScriptInvocationInteface | ||
198 | |||
199 | |||
200 | // ----------------------------------------------------------------- | ||
201 | /// <summary> | ||
202 | /// | ||
203 | /// </summary> | ||
204 | // ----------------------------------------------------------------- | ||
205 | public JsonStoreStats GetStoreStats() | ||
206 | { | ||
207 | JsonStoreStats stats; | ||
208 | |||
209 | lock (m_JsonValueStore) | ||
210 | { | ||
211 | stats.StoreCount = m_JsonValueStore.Count; | ||
212 | } | ||
213 | |||
214 | return stats; | ||
215 | } | ||
216 | |||
217 | // ----------------------------------------------------------------- | ||
218 | /// <summary> | ||
219 | /// | ||
220 | /// </summary> | ||
221 | // ----------------------------------------------------------------- | ||
222 | public bool AttachObjectStore(UUID objectID) | ||
223 | { | ||
224 | if (! m_enabled) return false; | ||
225 | if (! m_enableObjectStore) return false; | ||
226 | |||
227 | SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID); | ||
228 | if (sop == null) | ||
229 | { | ||
230 | m_log.ErrorFormat("[JsonStore] unable to attach to unknown object; {0}", objectID); | ||
231 | return false; | ||
232 | } | ||
233 | |||
234 | lock (m_JsonValueStore) | ||
235 | { | ||
236 | if (m_JsonValueStore.ContainsKey(objectID)) | ||
237 | return true; | ||
238 | |||
239 | JsonStore map = new JsonObjectStore(m_scene,objectID); | ||
240 | m_JsonValueStore.Add(objectID,map); | ||
241 | } | ||
242 | |||
243 | return true; | ||
244 | } | ||
245 | |||
246 | // ----------------------------------------------------------------- | ||
247 | /// <summary> | ||
248 | /// | ||
249 | /// </summary> | ||
250 | // ----------------------------------------------------------------- | ||
251 | public bool CreateStore(string value, ref UUID result) | ||
252 | { | ||
253 | if (result == UUID.Zero) | ||
254 | result = UUID.Random(); | ||
255 | |||
256 | JsonStore map = null; | ||
257 | |||
258 | if (! m_enabled) return false; | ||
259 | |||
260 | |||
261 | try | ||
262 | { | ||
263 | map = new JsonStore(value); | ||
264 | } | ||
265 | catch (Exception) | ||
266 | { | ||
267 | m_log.ErrorFormat("[JsonStore]: Unable to initialize store from {0}", value); | ||
268 | return false; | ||
269 | } | ||
270 | |||
271 | lock (m_JsonValueStore) | ||
272 | m_JsonValueStore.Add(result,map); | ||
273 | |||
274 | return true; | ||
275 | } | ||
276 | |||
277 | // ----------------------------------------------------------------- | ||
278 | /// <summary> | ||
279 | /// | ||
280 | /// </summary> | ||
281 | // ----------------------------------------------------------------- | ||
282 | public bool DestroyStore(UUID storeID) | ||
283 | { | ||
284 | if (! m_enabled) return false; | ||
285 | |||
286 | lock (m_JsonValueStore) | ||
287 | return m_JsonValueStore.Remove(storeID); | ||
288 | } | ||
289 | |||
290 | // ----------------------------------------------------------------- | ||
291 | /// <summary> | ||
292 | /// | ||
293 | /// </summary> | ||
294 | // ----------------------------------------------------------------- | ||
295 | public bool TestStore(UUID storeID) | ||
296 | { | ||
297 | if (! m_enabled) return false; | ||
298 | |||
299 | lock (m_JsonValueStore) | ||
300 | return m_JsonValueStore.ContainsKey(storeID); | ||
301 | } | ||
302 | |||
303 | // ----------------------------------------------------------------- | ||
304 | /// <summary> | ||
305 | /// | ||
306 | /// </summary> | ||
307 | // ----------------------------------------------------------------- | ||
308 | public JsonStoreNodeType GetNodeType(UUID storeID, string path) | ||
309 | { | ||
310 | if (! m_enabled) return JsonStoreNodeType.Undefined; | ||
311 | |||
312 | JsonStore map = null; | ||
313 | lock (m_JsonValueStore) | ||
314 | { | ||
315 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | ||
316 | { | ||
317 | m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); | ||
318 | return JsonStoreNodeType.Undefined; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | try | ||
323 | { | ||
324 | lock (map) | ||
325 | return map.GetNodeType(path); | ||
326 | } | ||
327 | catch (Exception e) | ||
328 | { | ||
329 | m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e); | ||
330 | } | ||
331 | |||
332 | return JsonStoreNodeType.Undefined; | ||
333 | } | ||
334 | |||
335 | // ----------------------------------------------------------------- | ||
336 | /// <summary> | ||
337 | /// | ||
338 | /// </summary> | ||
339 | // ----------------------------------------------------------------- | ||
340 | public JsonStoreValueType GetValueType(UUID storeID, string path) | ||
341 | { | ||
342 | if (! m_enabled) return JsonStoreValueType.Undefined; | ||
343 | |||
344 | JsonStore map = null; | ||
345 | lock (m_JsonValueStore) | ||
346 | { | ||
347 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | ||
348 | { | ||
349 | m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); | ||
350 | return JsonStoreValueType.Undefined; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | try | ||
355 | { | ||
356 | lock (map) | ||
357 | return map.GetValueType(path); | ||
358 | } | ||
359 | catch (Exception e) | ||
360 | { | ||
361 | m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e); | ||
362 | } | ||
363 | |||
364 | return JsonStoreValueType.Undefined; | ||
365 | } | ||
366 | |||
367 | // ----------------------------------------------------------------- | ||
368 | /// <summary> | ||
369 | /// | ||
370 | /// </summary> | ||
371 | // ----------------------------------------------------------------- | ||
372 | public bool SetValue(UUID storeID, string path, string value, bool useJson) | ||
373 | { | ||
374 | if (! m_enabled) return false; | ||
375 | |||
376 | JsonStore map = null; | ||
377 | lock (m_JsonValueStore) | ||
378 | { | ||
379 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | ||
380 | { | ||
381 | m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); | ||
382 | return false; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | try | ||
387 | { | ||
388 | lock (map) | ||
389 | { | ||
390 | if (map.StringSpace > m_maxStringSpace) | ||
391 | { | ||
392 | m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit", | ||
393 | storeID,map.StringSpace,m_maxStringSpace); | ||
394 | return false; | ||
395 | } | ||
396 | |||
397 | return map.SetValue(path,value,useJson); | ||
398 | } | ||
399 | } | ||
400 | catch (Exception e) | ||
401 | { | ||
402 | m_log.Error(string.Format("[JsonStore]: Unable to assign {0} to {1} in {2}", value, path, storeID), e); | ||
403 | } | ||
404 | |||
405 | return false; | ||
406 | } | ||
407 | |||
408 | // ----------------------------------------------------------------- | ||
409 | /// <summary> | ||
410 | /// | ||
411 | /// </summary> | ||
412 | // ----------------------------------------------------------------- | ||
413 | public bool RemoveValue(UUID storeID, string path) | ||
414 | { | ||
415 | if (! m_enabled) return false; | ||
416 | |||
417 | JsonStore map = null; | ||
418 | lock (m_JsonValueStore) | ||
419 | { | ||
420 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | ||
421 | { | ||
422 | m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); | ||
423 | return false; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | try | ||
428 | { | ||
429 | lock (map) | ||
430 | return map.RemoveValue(path); | ||
431 | } | ||
432 | catch (Exception e) | ||
433 | { | ||
434 | m_log.Error(string.Format("[JsonStore]: Unable to remove {0} in {1}", path, storeID), e); | ||
435 | } | ||
436 | |||
437 | return false; | ||
438 | } | ||
439 | |||
440 | // ----------------------------------------------------------------- | ||
441 | /// <summary> | ||
442 | /// | ||
443 | /// </summary> | ||
444 | // ----------------------------------------------------------------- | ||
445 | public int GetArrayLength(UUID storeID, string path) | ||
446 | { | ||
447 | if (! m_enabled) return -1; | ||
448 | |||
449 | JsonStore map = null; | ||
450 | lock (m_JsonValueStore) | ||
451 | { | ||
452 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | ||
453 | return -1; | ||
454 | } | ||
455 | |||
456 | try | ||
457 | { | ||
458 | lock (map) | ||
459 | { | ||
460 | return map.ArrayLength(path); | ||
461 | } | ||
462 | } | ||
463 | catch (Exception e) | ||
464 | { | ||
465 | m_log.Error("[JsonStore]: unable to retrieve value", e); | ||
466 | } | ||
467 | |||
468 | return -1; | ||
469 | } | ||
470 | |||
471 | // ----------------------------------------------------------------- | ||
472 | /// <summary> | ||
473 | /// | ||
474 | /// </summary> | ||
475 | // ----------------------------------------------------------------- | ||
476 | public bool GetValue(UUID storeID, string path, bool useJson, out string value) | ||
477 | { | ||
478 | value = String.Empty; | ||
479 | |||
480 | if (! m_enabled) return false; | ||
481 | |||
482 | JsonStore map = null; | ||
483 | lock (m_JsonValueStore) | ||
484 | { | ||
485 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | ||
486 | return false; | ||
487 | } | ||
488 | |||
489 | try | ||
490 | { | ||
491 | lock (map) | ||
492 | { | ||
493 | return map.GetValue(path, out value, useJson); | ||
494 | } | ||
495 | } | ||
496 | catch (Exception e) | ||
497 | { | ||
498 | m_log.Error("[JsonStore]: unable to retrieve value", e); | ||
499 | } | ||
500 | |||
501 | return false; | ||
502 | } | ||
503 | |||
504 | // ----------------------------------------------------------------- | ||
505 | /// <summary> | ||
506 | /// | ||
507 | /// </summary> | ||
508 | // ----------------------------------------------------------------- | ||
509 | public void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback) | ||
510 | { | ||
511 | if (! m_enabled) | ||
512 | { | ||
513 | cback(String.Empty); | ||
514 | return; | ||
515 | } | ||
516 | |||
517 | JsonStore map = null; | ||
518 | lock (m_JsonValueStore) | ||
519 | { | ||
520 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | ||
521 | { | ||
522 | cback(String.Empty); | ||
523 | return; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | try | ||
528 | { | ||
529 | lock (map) | ||
530 | { | ||
531 | map.TakeValue(path, useJson, cback); | ||
532 | return; | ||
533 | } | ||
534 | } | ||
535 | catch (Exception e) | ||
536 | { | ||
537 | m_log.Error("[JsonStore] unable to retrieve value", e); | ||
538 | } | ||
539 | |||
540 | cback(String.Empty); | ||
541 | } | ||
542 | |||
543 | // ----------------------------------------------------------------- | ||
544 | /// <summary> | ||
545 | /// | ||
546 | /// </summary> | ||
547 | // ----------------------------------------------------------------- | ||
548 | public void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback) | ||
549 | { | ||
550 | if (! m_enabled) | ||
551 | { | ||
552 | cback(String.Empty); | ||
553 | return; | ||
554 | } | ||
555 | |||
556 | JsonStore map = null; | ||
557 | lock (m_JsonValueStore) | ||
558 | { | ||
559 | if (! m_JsonValueStore.TryGetValue(storeID,out map)) | ||
560 | { | ||
561 | cback(String.Empty); | ||
562 | return; | ||
563 | } | ||
564 | } | ||
565 | |||
566 | try | ||
567 | { | ||
568 | lock (map) | ||
569 | { | ||
570 | map.ReadValue(path, useJson, cback); | ||
571 | return; | ||
572 | } | ||
573 | } | ||
574 | catch (Exception e) | ||
575 | { | ||
576 | m_log.Error("[JsonStore]: unable to retrieve value", e); | ||
577 | } | ||
578 | |||
579 | cback(String.Empty); | ||
580 | } | ||
581 | |||
582 | #endregion | ||
583 | } | ||
584 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs new file mode 100644 index 0000000..edf51a2 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | |||
@@ -0,0 +1,808 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors | ||
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 OpenSim 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 | using Mono.Addins; | ||
28 | |||
29 | using System; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | using System.Text; | ||
33 | using System.Net; | ||
34 | using System.Net.Sockets; | ||
35 | using log4net; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenMetaverse.StructuredData; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Region.Framework.Interfaces; | ||
41 | using OpenSim.Region.Framework.Scenes; | ||
42 | using OpenSim.Region.Framework.Scenes.Scripting; | ||
43 | using System.Collections.Generic; | ||
44 | using System.Text.RegularExpressions; | ||
45 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
46 | |||
47 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | ||
48 | { | ||
49 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreScriptModule")] | ||
50 | |||
51 | public class JsonStoreScriptModule : INonSharedRegionModule | ||
52 | { | ||
53 | private static readonly ILog m_log = | ||
54 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
55 | |||
56 | private IConfig m_config = null; | ||
57 | private bool m_enabled = false; | ||
58 | private Scene m_scene = null; | ||
59 | |||
60 | private IScriptModuleComms m_comms; | ||
61 | private IJsonStoreModule m_store; | ||
62 | |||
63 | private Dictionary<UUID,HashSet<UUID>> m_scriptStores = new Dictionary<UUID,HashSet<UUID>>(); | ||
64 | |||
65 | #region Region Module interface | ||
66 | |||
67 | // ----------------------------------------------------------------- | ||
68 | /// <summary> | ||
69 | /// Name of this shared module is it's class name | ||
70 | /// </summary> | ||
71 | // ----------------------------------------------------------------- | ||
72 | public string Name | ||
73 | { | ||
74 | get { return this.GetType().Name; } | ||
75 | } | ||
76 | |||
77 | // ----------------------------------------------------------------- | ||
78 | /// <summary> | ||
79 | /// Initialise this shared module | ||
80 | /// </summary> | ||
81 | /// <param name="scene">this region is getting initialised</param> | ||
82 | /// <param name="source">nini config, we are not using this</param> | ||
83 | // ----------------------------------------------------------------- | ||
84 | public void Initialise(IConfigSource config) | ||
85 | { | ||
86 | try | ||
87 | { | ||
88 | if ((m_config = config.Configs["JsonStore"]) == null) | ||
89 | { | ||
90 | // There is no configuration, the module is disabled | ||
91 | // m_log.InfoFormat("[JsonStoreScripts] no configuration info"); | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | m_enabled = m_config.GetBoolean("Enabled", m_enabled); | ||
96 | } | ||
97 | catch (Exception e) | ||
98 | { | ||
99 | m_log.ErrorFormat("[JsonStoreScripts]: initialization error: {0}", e.Message); | ||
100 | return; | ||
101 | } | ||
102 | |||
103 | if (m_enabled) | ||
104 | m_log.DebugFormat("[JsonStoreScripts]: module is enabled"); | ||
105 | } | ||
106 | |||
107 | // ----------------------------------------------------------------- | ||
108 | /// <summary> | ||
109 | /// everything is loaded, perform post load configuration | ||
110 | /// </summary> | ||
111 | // ----------------------------------------------------------------- | ||
112 | public void PostInitialise() | ||
113 | { | ||
114 | } | ||
115 | |||
116 | // ----------------------------------------------------------------- | ||
117 | /// <summary> | ||
118 | /// Nothing to do on close | ||
119 | /// </summary> | ||
120 | // ----------------------------------------------------------------- | ||
121 | public void Close() | ||
122 | { | ||
123 | } | ||
124 | |||
125 | // ----------------------------------------------------------------- | ||
126 | /// <summary> | ||
127 | /// </summary> | ||
128 | // ----------------------------------------------------------------- | ||
129 | public void AddRegion(Scene scene) | ||
130 | { | ||
131 | scene.EventManager.OnScriptReset += HandleScriptReset; | ||
132 | scene.EventManager.OnRemoveScript += HandleScriptReset; | ||
133 | } | ||
134 | |||
135 | // ----------------------------------------------------------------- | ||
136 | /// <summary> | ||
137 | /// </summary> | ||
138 | // ----------------------------------------------------------------- | ||
139 | public void RemoveRegion(Scene scene) | ||
140 | { | ||
141 | scene.EventManager.OnScriptReset -= HandleScriptReset; | ||
142 | scene.EventManager.OnRemoveScript -= HandleScriptReset; | ||
143 | |||
144 | // need to remove all references to the scene in the subscription | ||
145 | // list to enable full garbage collection of the scene object | ||
146 | } | ||
147 | |||
148 | // ----------------------------------------------------------------- | ||
149 | /// <summary> | ||
150 | /// </summary> | ||
151 | // ----------------------------------------------------------------- | ||
152 | private void HandleScriptReset(uint localID, UUID itemID) | ||
153 | { | ||
154 | HashSet<UUID> stores; | ||
155 | |||
156 | lock (m_scriptStores) | ||
157 | { | ||
158 | if (! m_scriptStores.TryGetValue(itemID, out stores)) | ||
159 | return; | ||
160 | m_scriptStores.Remove(itemID); | ||
161 | } | ||
162 | |||
163 | foreach (UUID id in stores) | ||
164 | m_store.DestroyStore(id); | ||
165 | } | ||
166 | |||
167 | // ----------------------------------------------------------------- | ||
168 | /// <summary> | ||
169 | /// Called when all modules have been added for a region. This is | ||
170 | /// where we hook up events | ||
171 | /// </summary> | ||
172 | // ----------------------------------------------------------------- | ||
173 | public void RegionLoaded(Scene scene) | ||
174 | { | ||
175 | if (m_enabled) | ||
176 | { | ||
177 | m_scene = scene; | ||
178 | m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>(); | ||
179 | if (m_comms == null) | ||
180 | { | ||
181 | m_log.ErrorFormat("[JsonStoreScripts]: ScriptModuleComms interface not defined"); | ||
182 | m_enabled = false; | ||
183 | return; | ||
184 | } | ||
185 | |||
186 | m_store = m_scene.RequestModuleInterface<IJsonStoreModule>(); | ||
187 | if (m_store == null) | ||
188 | { | ||
189 | m_log.ErrorFormat("[JsonStoreScripts]: JsonModule interface not defined"); | ||
190 | m_enabled = false; | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | try | ||
195 | { | ||
196 | m_comms.RegisterScriptInvocations(this); | ||
197 | m_comms.RegisterConstants(this); | ||
198 | } | ||
199 | catch (Exception e) | ||
200 | { | ||
201 | // See http://opensimulator.org/mantis/view.php?id=5971 for more information | ||
202 | m_log.WarnFormat("[JsonStoreScripts]: script method registration failed; {0}", e.Message); | ||
203 | m_enabled = false; | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | |||
208 | /// ----------------------------------------------------------------- | ||
209 | /// <summary> | ||
210 | /// </summary> | ||
211 | // ----------------------------------------------------------------- | ||
212 | public Type ReplaceableInterface | ||
213 | { | ||
214 | get { return null; } | ||
215 | } | ||
216 | |||
217 | #endregion | ||
218 | |||
219 | #region ScriptConstantsInterface | ||
220 | |||
221 | [ScriptConstant] | ||
222 | public static readonly int JSON_NODETYPE_UNDEF = (int)JsonStoreNodeType.Undefined; | ||
223 | |||
224 | [ScriptConstant] | ||
225 | public static readonly int JSON_NODETYPE_OBJECT = (int)JsonStoreNodeType.Object; | ||
226 | |||
227 | [ScriptConstant] | ||
228 | public static readonly int JSON_NODETYPE_ARRAY = (int)JsonStoreNodeType.Array; | ||
229 | |||
230 | [ScriptConstant] | ||
231 | public static readonly int JSON_NODETYPE_VALUE = (int)JsonStoreNodeType.Value; | ||
232 | |||
233 | [ScriptConstant] | ||
234 | public static readonly int JSON_VALUETYPE_UNDEF = (int)JsonStoreValueType.Undefined; | ||
235 | |||
236 | [ScriptConstant] | ||
237 | public static readonly int JSON_VALUETYPE_BOOLEAN = (int)JsonStoreValueType.Boolean; | ||
238 | |||
239 | [ScriptConstant] | ||
240 | public static readonly int JSON_VALUETYPE_INTEGER = (int)JsonStoreValueType.Integer; | ||
241 | |||
242 | [ScriptConstant] | ||
243 | public static readonly int JSON_VALUETYPE_FLOAT = (int)JsonStoreValueType.Float; | ||
244 | |||
245 | [ScriptConstant] | ||
246 | public static readonly int JSON_VALUETYPE_STRING = (int)JsonStoreValueType.String; | ||
247 | |||
248 | |||
249 | #endregion | ||
250 | |||
251 | #region ScriptInvocationInteface | ||
252 | // ----------------------------------------------------------------- | ||
253 | /// <summary> | ||
254 | /// | ||
255 | /// </summary> | ||
256 | // ----------------------------------------------------------------- | ||
257 | [ScriptInvocation] | ||
258 | public UUID JsonAttachObjectStore(UUID hostID, UUID scriptID) | ||
259 | { | ||
260 | UUID uuid = UUID.Zero; | ||
261 | if (! m_store.AttachObjectStore(hostID)) | ||
262 | GenerateRuntimeError("Failed to create Json store"); | ||
263 | |||
264 | return hostID; | ||
265 | } | ||
266 | |||
267 | // ----------------------------------------------------------------- | ||
268 | /// <summary> | ||
269 | /// | ||
270 | /// </summary> | ||
271 | // ----------------------------------------------------------------- | ||
272 | [ScriptInvocation] | ||
273 | public UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) | ||
274 | { | ||
275 | UUID uuid = UUID.Zero; | ||
276 | if (! m_store.CreateStore(value, ref uuid)) | ||
277 | GenerateRuntimeError("Failed to create Json store"); | ||
278 | |||
279 | lock (m_scriptStores) | ||
280 | { | ||
281 | if (! m_scriptStores.ContainsKey(scriptID)) | ||
282 | m_scriptStores[scriptID] = new HashSet<UUID>(); | ||
283 | |||
284 | m_scriptStores[scriptID].Add(uuid); | ||
285 | } | ||
286 | return uuid; | ||
287 | } | ||
288 | |||
289 | // ----------------------------------------------------------------- | ||
290 | /// <summary> | ||
291 | /// | ||
292 | /// </summary> | ||
293 | // ----------------------------------------------------------------- | ||
294 | [ScriptInvocation] | ||
295 | public int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) | ||
296 | { | ||
297 | lock(m_scriptStores) | ||
298 | { | ||
299 | if (m_scriptStores.ContainsKey(scriptID)) | ||
300 | m_scriptStores[scriptID].Remove(storeID); | ||
301 | } | ||
302 | |||
303 | return m_store.DestroyStore(storeID) ? 1 : 0; | ||
304 | } | ||
305 | |||
306 | // ----------------------------------------------------------------- | ||
307 | /// <summary> | ||
308 | /// | ||
309 | /// </summary> | ||
310 | // ----------------------------------------------------------------- | ||
311 | [ScriptInvocation] | ||
312 | public int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID) | ||
313 | { | ||
314 | return m_store.TestStore(storeID) ? 1 : 0; | ||
315 | } | ||
316 | |||
317 | // ----------------------------------------------------------------- | ||
318 | /// <summary> | ||
319 | /// | ||
320 | /// </summary> | ||
321 | // ----------------------------------------------------------------- | ||
322 | [ScriptInvocation] | ||
323 | public UUID JsonRezAtRoot(UUID hostID, UUID scriptID, string item, Vector3 pos, Vector3 vel, Quaternion rot, string param) | ||
324 | { | ||
325 | UUID reqID = UUID.Random(); | ||
326 | Util.FireAndForget( | ||
327 | o => DoJsonRezObject(hostID, scriptID, reqID, item, pos, vel, rot, param), null, "JsonStoreScriptModule.DoJsonRezObject"); | ||
328 | return reqID; | ||
329 | } | ||
330 | |||
331 | // ----------------------------------------------------------------- | ||
332 | /// <summary> | ||
333 | /// | ||
334 | /// </summary> | ||
335 | // ----------------------------------------------------------------- | ||
336 | [ScriptInvocation] | ||
337 | public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) | ||
338 | { | ||
339 | UUID reqID = UUID.Random(); | ||
340 | Util.FireAndForget( | ||
341 | o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier), null, "JsonStoreScriptModule.JsonReadNotecard"); | ||
342 | return reqID; | ||
343 | } | ||
344 | |||
345 | // ----------------------------------------------------------------- | ||
346 | /// <summary> | ||
347 | /// | ||
348 | /// </summary> | ||
349 | // ----------------------------------------------------------------- | ||
350 | [ScriptInvocation] | ||
351 | public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) | ||
352 | { | ||
353 | UUID reqID = UUID.Random(); | ||
354 | Util.FireAndForget( | ||
355 | o => DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name), null, "JsonStoreScriptModule.DoJsonWriteNotecard"); | ||
356 | return reqID; | ||
357 | } | ||
358 | |||
359 | // ----------------------------------------------------------------- | ||
360 | /// <summary> | ||
361 | /// | ||
362 | /// </summary> | ||
363 | // ----------------------------------------------------------------- | ||
364 | [ScriptInvocation] | ||
365 | public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist) | ||
366 | { | ||
367 | string ipath = ConvertList2Path(pathlist); | ||
368 | string opath; | ||
369 | |||
370 | if (JsonStore.CanonicalPathExpression(ipath,out opath)) | ||
371 | return opath; | ||
372 | |||
373 | // This won't parse if passed to the other routines as opposed to | ||
374 | // returning an empty string which is a valid path and would overwrite | ||
375 | // the entire store | ||
376 | return "**INVALID**"; | ||
377 | } | ||
378 | |||
379 | // ----------------------------------------------------------------- | ||
380 | /// <summary> | ||
381 | /// | ||
382 | /// </summary> | ||
383 | // ----------------------------------------------------------------- | ||
384 | [ScriptInvocation] | ||
385 | public int JsonGetNodeType(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
386 | { | ||
387 | return (int)m_store.GetNodeType(storeID,path); | ||
388 | } | ||
389 | |||
390 | // ----------------------------------------------------------------- | ||
391 | /// <summary> | ||
392 | /// | ||
393 | /// </summary> | ||
394 | // ----------------------------------------------------------------- | ||
395 | [ScriptInvocation] | ||
396 | public int JsonGetValueType(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
397 | { | ||
398 | return (int)m_store.GetValueType(storeID,path); | ||
399 | } | ||
400 | |||
401 | // ----------------------------------------------------------------- | ||
402 | /// <summary> | ||
403 | /// | ||
404 | /// </summary> | ||
405 | // ----------------------------------------------------------------- | ||
406 | [ScriptInvocation] | ||
407 | public int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) | ||
408 | { | ||
409 | return m_store.SetValue(storeID,path,value,false) ? 1 : 0; | ||
410 | } | ||
411 | |||
412 | [ScriptInvocation] | ||
413 | public int JsonSetJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) | ||
414 | { | ||
415 | return m_store.SetValue(storeID,path,value,true) ? 1 : 0; | ||
416 | } | ||
417 | |||
418 | // ----------------------------------------------------------------- | ||
419 | /// <summary> | ||
420 | /// | ||
421 | /// </summary> | ||
422 | // ----------------------------------------------------------------- | ||
423 | [ScriptInvocation] | ||
424 | public int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
425 | { | ||
426 | return m_store.RemoveValue(storeID,path) ? 1 : 0; | ||
427 | } | ||
428 | |||
429 | // ----------------------------------------------------------------- | ||
430 | /// <summary> | ||
431 | /// | ||
432 | /// </summary> | ||
433 | // ----------------------------------------------------------------- | ||
434 | [ScriptInvocation] | ||
435 | public int JsonGetArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
436 | { | ||
437 | return m_store.GetArrayLength(storeID,path); | ||
438 | } | ||
439 | |||
440 | // ----------------------------------------------------------------- | ||
441 | /// <summary> | ||
442 | /// | ||
443 | /// </summary> | ||
444 | // ----------------------------------------------------------------- | ||
445 | [ScriptInvocation] | ||
446 | public string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
447 | { | ||
448 | string value = String.Empty; | ||
449 | m_store.GetValue(storeID,path,false,out value); | ||
450 | return value; | ||
451 | } | ||
452 | |||
453 | [ScriptInvocation] | ||
454 | public string JsonGetJson(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
455 | { | ||
456 | string value = String.Empty; | ||
457 | m_store.GetValue(storeID,path,true, out value); | ||
458 | return value; | ||
459 | } | ||
460 | |||
461 | // ----------------------------------------------------------------- | ||
462 | /// <summary> | ||
463 | /// | ||
464 | /// </summary> | ||
465 | // ----------------------------------------------------------------- | ||
466 | [ScriptInvocation] | ||
467 | public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
468 | { | ||
469 | UUID reqID = UUID.Random(); | ||
470 | Util.FireAndForget( | ||
471 | o => DoJsonTakeValue(scriptID,reqID,storeID,path,false), null, "JsonStoreScriptModule.DoJsonTakeValue"); | ||
472 | return reqID; | ||
473 | } | ||
474 | |||
475 | [ScriptInvocation] | ||
476 | public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
477 | { | ||
478 | UUID reqID = UUID.Random(); | ||
479 | Util.FireAndForget( | ||
480 | o => DoJsonTakeValue(scriptID,reqID,storeID,path,true), null, "JsonStoreScriptModule.DoJsonTakeValueJson"); | ||
481 | return reqID; | ||
482 | } | ||
483 | |||
484 | // ----------------------------------------------------------------- | ||
485 | /// <summary> | ||
486 | /// | ||
487 | /// </summary> | ||
488 | // ----------------------------------------------------------------- | ||
489 | [ScriptInvocation] | ||
490 | public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
491 | { | ||
492 | UUID reqID = UUID.Random(); | ||
493 | Util.FireAndForget( | ||
494 | o => DoJsonReadValue(scriptID,reqID,storeID,path,false), null, "JsonStoreScriptModule.DoJsonReadValue"); | ||
495 | return reqID; | ||
496 | } | ||
497 | |||
498 | [ScriptInvocation] | ||
499 | public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) | ||
500 | { | ||
501 | UUID reqID = UUID.Random(); | ||
502 | Util.FireAndForget( | ||
503 | o => DoJsonReadValue(scriptID,reqID,storeID,path,true), null, "JsonStoreScriptModule.DoJsonReadValueJson"); | ||
504 | return reqID; | ||
505 | } | ||
506 | |||
507 | #endregion | ||
508 | |||
509 | // ----------------------------------------------------------------- | ||
510 | /// <summary> | ||
511 | /// | ||
512 | /// </summary> | ||
513 | // ----------------------------------------------------------------- | ||
514 | protected void GenerateRuntimeError(string msg) | ||
515 | { | ||
516 | m_log.InfoFormat("[JsonStore] runtime error: {0}",msg); | ||
517 | throw new Exception("JsonStore Runtime Error: " + msg); | ||
518 | } | ||
519 | |||
520 | // ----------------------------------------------------------------- | ||
521 | /// <summary> | ||
522 | /// | ||
523 | /// </summary> | ||
524 | // ----------------------------------------------------------------- | ||
525 | protected void DispatchValue(UUID scriptID, UUID reqID, string value) | ||
526 | { | ||
527 | m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); | ||
528 | } | ||
529 | |||
530 | // ----------------------------------------------------------------- | ||
531 | /// <summary> | ||
532 | /// | ||
533 | /// </summary> | ||
534 | // ----------------------------------------------------------------- | ||
535 | private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) | ||
536 | { | ||
537 | try | ||
538 | { | ||
539 | m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); | ||
540 | return; | ||
541 | } | ||
542 | catch (Exception e) | ||
543 | { | ||
544 | m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString()); | ||
545 | } | ||
546 | |||
547 | DispatchValue(scriptID,reqID,String.Empty); | ||
548 | } | ||
549 | |||
550 | |||
551 | // ----------------------------------------------------------------- | ||
552 | /// <summary> | ||
553 | /// | ||
554 | /// </summary> | ||
555 | // ----------------------------------------------------------------- | ||
556 | private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) | ||
557 | { | ||
558 | try | ||
559 | { | ||
560 | m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); | ||
561 | return; | ||
562 | } | ||
563 | catch (Exception e) | ||
564 | { | ||
565 | m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString()); | ||
566 | } | ||
567 | |||
568 | DispatchValue(scriptID,reqID,String.Empty); | ||
569 | } | ||
570 | |||
571 | // ----------------------------------------------------------------- | ||
572 | /// <summary> | ||
573 | /// | ||
574 | /// </summary> | ||
575 | // ----------------------------------------------------------------- | ||
576 | private void DoJsonReadNotecard( | ||
577 | UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) | ||
578 | { | ||
579 | UUID assetID; | ||
580 | |||
581 | if (!UUID.TryParse(notecardIdentifier, out assetID)) | ||
582 | { | ||
583 | SceneObjectPart part = m_scene.GetSceneObjectPart(hostID); | ||
584 | assetID = ScriptUtils.GetAssetIdFromItemName(part, notecardIdentifier, (int)AssetType.Notecard); | ||
585 | } | ||
586 | |||
587 | AssetBase a = m_scene.AssetService.Get(assetID.ToString()); | ||
588 | if (a == null) | ||
589 | GenerateRuntimeError(String.Format("Unable to find notecard asset {0}", assetID)); | ||
590 | |||
591 | if (a.Type != (sbyte)AssetType.Notecard) | ||
592 | GenerateRuntimeError(String.Format("Invalid notecard asset {0}", assetID)); | ||
593 | |||
594 | m_log.DebugFormat("[JsonStoreScripts]: read notecard in context {0}",storeID); | ||
595 | |||
596 | try | ||
597 | { | ||
598 | string jsondata = SLUtil.ParseNotecardToString(a.Data); | ||
599 | int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; | ||
600 | m_comms.DispatchReply(scriptID, result, "", reqID.ToString()); | ||
601 | return; | ||
602 | } | ||
603 | catch(SLUtil.NotANotecardFormatException e) | ||
604 | { | ||
605 | m_log.WarnFormat("[JsonStoreScripts]: Notecard parsing failed; assetId {0} at line number {1}", assetID.ToString(), e.lineNumber); | ||
606 | } | ||
607 | catch (Exception e) | ||
608 | { | ||
609 | m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message); | ||
610 | } | ||
611 | |||
612 | GenerateRuntimeError(String.Format("Json parsing failed for {0}", assetID)); | ||
613 | m_comms.DispatchReply(scriptID, 0, "", reqID.ToString()); | ||
614 | } | ||
615 | |||
616 | // ----------------------------------------------------------------- | ||
617 | /// <summary> | ||
618 | /// | ||
619 | /// </summary> | ||
620 | // ----------------------------------------------------------------- | ||
621 | private void DoJsonWriteNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string name) | ||
622 | { | ||
623 | string data; | ||
624 | if (! m_store.GetValue(storeID,path,true, out data)) | ||
625 | { | ||
626 | m_comms.DispatchReply(scriptID,0,UUID.Zero.ToString(),reqID.ToString()); | ||
627 | return; | ||
628 | } | ||
629 | |||
630 | SceneObjectPart host = m_scene.GetSceneObjectPart(hostID); | ||
631 | |||
632 | // Create new asset | ||
633 | UUID assetID = UUID.Random(); | ||
634 | AssetBase asset = new AssetBase(assetID, name, (sbyte)AssetType.Notecard, host.OwnerID.ToString()); | ||
635 | asset.Description = "Json store"; | ||
636 | |||
637 | int textLength = data.Length; | ||
638 | data = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " | ||
639 | + textLength.ToString() + "\n" + data + "}\n"; | ||
640 | |||
641 | asset.Data = Util.UTF8.GetBytes(data); | ||
642 | m_scene.AssetService.Store(asset); | ||
643 | |||
644 | // Create Task Entry | ||
645 | TaskInventoryItem taskItem = new TaskInventoryItem(); | ||
646 | |||
647 | taskItem.ResetIDs(host.UUID); | ||
648 | taskItem.ParentID = host.UUID; | ||
649 | taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch(); | ||
650 | taskItem.Name = asset.Name; | ||
651 | taskItem.Description = asset.Description; | ||
652 | taskItem.Type = (int)AssetType.Notecard; | ||
653 | taskItem.InvType = (int)InventoryType.Notecard; | ||
654 | taskItem.OwnerID = host.OwnerID; | ||
655 | taskItem.CreatorID = host.OwnerID; | ||
656 | taskItem.BasePermissions = (uint)PermissionMask.All; | ||
657 | taskItem.CurrentPermissions = (uint)PermissionMask.All; | ||
658 | taskItem.EveryonePermissions = 0; | ||
659 | taskItem.NextPermissions = (uint)PermissionMask.All; | ||
660 | taskItem.GroupID = host.GroupID; | ||
661 | taskItem.GroupPermissions = 0; | ||
662 | taskItem.Flags = 0; | ||
663 | taskItem.PermsGranter = UUID.Zero; | ||
664 | taskItem.PermsMask = 0; | ||
665 | taskItem.AssetID = asset.FullID; | ||
666 | |||
667 | host.Inventory.AddInventoryItem(taskItem, false); | ||
668 | |||
669 | m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); | ||
670 | } | ||
671 | |||
672 | // ----------------------------------------------------------------- | ||
673 | /// <summary> | ||
674 | /// Convert a list of values that are path components to a single string path | ||
675 | /// </summary> | ||
676 | // ----------------------------------------------------------------- | ||
677 | protected static Regex m_ArrayPattern = new Regex("^([0-9]+|\\+)$"); | ||
678 | private string ConvertList2Path(object[] pathlist) | ||
679 | { | ||
680 | string path = ""; | ||
681 | for (int i = 0; i < pathlist.Length; i++) | ||
682 | { | ||
683 | string token = ""; | ||
684 | |||
685 | if (pathlist[i] is string) | ||
686 | { | ||
687 | token = pathlist[i].ToString(); | ||
688 | |||
689 | // Check to see if this is a bare number which would not be a valid | ||
690 | // identifier otherwise | ||
691 | if (m_ArrayPattern.IsMatch(token)) | ||
692 | token = '[' + token + ']'; | ||
693 | } | ||
694 | else if (pathlist[i] is int) | ||
695 | { | ||
696 | token = "[" + pathlist[i].ToString() + "]"; | ||
697 | } | ||
698 | else | ||
699 | { | ||
700 | token = "." + pathlist[i].ToString() + "."; | ||
701 | } | ||
702 | |||
703 | path += token + "."; | ||
704 | } | ||
705 | |||
706 | return path; | ||
707 | } | ||
708 | |||
709 | // ----------------------------------------------------------------- | ||
710 | /// <summary> | ||
711 | /// | ||
712 | /// </summary> | ||
713 | // ----------------------------------------------------------------- | ||
714 | private void DoJsonRezObject(UUID hostID, UUID scriptID, UUID reqID, string name, Vector3 pos, Vector3 vel, Quaternion rot, string param) | ||
715 | { | ||
716 | if (Double.IsNaN(rot.X) || Double.IsNaN(rot.Y) || Double.IsNaN(rot.Z) || Double.IsNaN(rot.W)) | ||
717 | { | ||
718 | GenerateRuntimeError("Invalid rez rotation"); | ||
719 | return; | ||
720 | } | ||
721 | |||
722 | SceneObjectGroup host = m_scene.GetSceneObjectGroup(hostID); | ||
723 | if (host == null) | ||
724 | { | ||
725 | GenerateRuntimeError(String.Format("Unable to find rezzing host '{0}'",hostID)); | ||
726 | return; | ||
727 | } | ||
728 | |||
729 | // hpos = host.RootPart.GetWorldPosition() | ||
730 | // float dist = (float)llVecDist(hpos, pos); | ||
731 | // if (dist > m_ScriptDistanceFactor * 10.0f) | ||
732 | // return; | ||
733 | |||
734 | TaskInventoryItem item = host.RootPart.Inventory.GetInventoryItem(name); | ||
735 | if (item == null) | ||
736 | { | ||
737 | GenerateRuntimeError(String.Format("Unable to find object to rez '{0}'",name)); | ||
738 | return; | ||
739 | } | ||
740 | |||
741 | if (item.InvType != (int)InventoryType.Object) | ||
742 | { | ||
743 | GenerateRuntimeError("Can't create requested object; object is missing from database"); | ||
744 | return; | ||
745 | } | ||
746 | |||
747 | List<SceneObjectGroup> objlist; | ||
748 | List<Vector3> veclist; | ||
749 | |||
750 | bool success = host.RootPart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist); | ||
751 | if (! success) | ||
752 | { | ||
753 | GenerateRuntimeError("Failed to create object"); | ||
754 | return; | ||
755 | } | ||
756 | |||
757 | int totalPrims = 0; | ||
758 | foreach (SceneObjectGroup group in objlist) | ||
759 | totalPrims += group.PrimCount; | ||
760 | |||
761 | if (! m_scene.Permissions.CanRezObject(totalPrims, item.OwnerID, pos)) | ||
762 | { | ||
763 | GenerateRuntimeError("Not allowed to create the object"); | ||
764 | return; | ||
765 | } | ||
766 | |||
767 | if (! m_scene.Permissions.BypassPermissions()) | ||
768 | { | ||
769 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
770 | host.RootPart.Inventory.RemoveInventoryItem(item.ItemID); | ||
771 | } | ||
772 | |||
773 | for (int i = 0; i < objlist.Count; i++) | ||
774 | { | ||
775 | SceneObjectGroup group = objlist[i]; | ||
776 | Vector3 curpos = pos + veclist[i]; | ||
777 | |||
778 | if (group.IsAttachment == false && group.RootPart.Shape.State != 0) | ||
779 | { | ||
780 | group.RootPart.AttachedPos = group.AbsolutePosition; | ||
781 | group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; | ||
782 | } | ||
783 | |||
784 | group.FromPartID = host.RootPart.UUID; | ||
785 | m_scene.AddNewSceneObject(group, true, curpos, rot, vel); | ||
786 | |||
787 | UUID storeID = group.UUID; | ||
788 | if (! m_store.CreateStore(param, ref storeID)) | ||
789 | { | ||
790 | GenerateRuntimeError("Unable to create jsonstore for new object"); | ||
791 | continue; | ||
792 | } | ||
793 | |||
794 | // We can only call this after adding the scene object, since the scene object references the scene | ||
795 | // to find out if scripts should be activated at all. | ||
796 | group.RootPart.SetDieAtEdge(true); | ||
797 | group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3); | ||
798 | group.ResumeScripts(); | ||
799 | |||
800 | group.ScheduleGroupForFullUpdate(); | ||
801 | |||
802 | // send the reply back to the host object, use the integer param to indicate the number | ||
803 | // of remaining objects | ||
804 | m_comms.DispatchReply(scriptID, objlist.Count-i-1, group.RootPart.UUID.ToString(), reqID.ToString()); | ||
805 | } | ||
806 | } | ||
807 | } | ||
808 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs new file mode 100644 index 0000000..99a7076 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | |||
@@ -0,0 +1,900 @@ | |||
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.Reflection; | ||
31 | using System.Text; | ||
32 | using log4net; | ||
33 | using Nini.Config; | ||
34 | using NUnit.Framework; | ||
35 | using OpenMetaverse; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.CoreModules.Scripting.ScriptModuleComms; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | using OpenSim.Region.ScriptEngine.Shared; | ||
40 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
41 | using OpenSim.Services.Interfaces; | ||
42 | using OpenSim.Tests.Common; | ||
43 | |||
44 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests | ||
45 | { | ||
46 | /// <summary> | ||
47 | /// Tests for inventory functions in LSL | ||
48 | /// </summary> | ||
49 | [TestFixture] | ||
50 | public class JsonStoreScriptModuleTests : OpenSimTestCase | ||
51 | { | ||
52 | private Scene m_scene; | ||
53 | private MockScriptEngine m_engine; | ||
54 | private ScriptModuleCommsModule m_smcm; | ||
55 | private JsonStoreScriptModule m_jssm; | ||
56 | |||
57 | [TestFixtureSetUp] | ||
58 | public void FixtureInit() | ||
59 | { | ||
60 | // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. | ||
61 | Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; | ||
62 | } | ||
63 | |||
64 | [TestFixtureTearDown] | ||
65 | public void TearDown() | ||
66 | { | ||
67 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | ||
68 | // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression | ||
69 | // tests really shouldn't). | ||
70 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | ||
71 | } | ||
72 | |||
73 | [SetUp] | ||
74 | public override void SetUp() | ||
75 | { | ||
76 | base.SetUp(); | ||
77 | |||
78 | IConfigSource configSource = new IniConfigSource(); | ||
79 | IConfig jsonStoreConfig = configSource.AddConfig("JsonStore"); | ||
80 | jsonStoreConfig.Set("Enabled", "true"); | ||
81 | |||
82 | m_engine = new MockScriptEngine(); | ||
83 | m_smcm = new ScriptModuleCommsModule(); | ||
84 | JsonStoreModule jsm = new JsonStoreModule(); | ||
85 | m_jssm = new JsonStoreScriptModule(); | ||
86 | |||
87 | m_scene = new SceneHelpers().SetupScene(); | ||
88 | SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, m_jssm); | ||
89 | |||
90 | try | ||
91 | { | ||
92 | m_smcm.RegisterScriptInvocation(this, "DummyTestMethod"); | ||
93 | } | ||
94 | catch (ArgumentException) | ||
95 | { | ||
96 | Assert.Ignore("Ignoring test since running on .NET 3.5 or earlier."); | ||
97 | } | ||
98 | |||
99 | // XXX: Unfortunately, ICommsModule currently has no way of deregistering methods. | ||
100 | } | ||
101 | |||
102 | private object InvokeOp(string name, params object[] args) | ||
103 | { | ||
104 | return InvokeOpOnHost(name, UUID.Zero, args); | ||
105 | } | ||
106 | |||
107 | private object InvokeOpOnHost(string name, UUID hostId, params object[] args) | ||
108 | { | ||
109 | return m_smcm.InvokeOperation(hostId, UUID.Zero, name, args); | ||
110 | } | ||
111 | |||
112 | [Test] | ||
113 | public void TestJsonCreateStore() | ||
114 | { | ||
115 | TestHelpers.InMethod(); | ||
116 | // TestHelpers.EnableLogging(); | ||
117 | |||
118 | // Test blank store | ||
119 | { | ||
120 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
121 | Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); | ||
122 | } | ||
123 | |||
124 | // Test single element store | ||
125 | { | ||
126 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); | ||
127 | Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); | ||
128 | } | ||
129 | |||
130 | // Test with an integer value | ||
131 | { | ||
132 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 42.15 }"); | ||
133 | Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); | ||
134 | |||
135 | string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); | ||
136 | Assert.That(value, Is.EqualTo("42.15")); | ||
137 | } | ||
138 | |||
139 | // Test with an array as the root node | ||
140 | { | ||
141 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "[ 'one', 'two', 'three' ]"); | ||
142 | Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); | ||
143 | |||
144 | string value = (string)InvokeOp("JsonGetValue", storeId, "[1]"); | ||
145 | Assert.That(value, Is.EqualTo("two")); | ||
146 | } | ||
147 | } | ||
148 | |||
149 | [Test] | ||
150 | public void TestJsonDestroyStore() | ||
151 | { | ||
152 | TestHelpers.InMethod(); | ||
153 | // TestHelpers.EnableLogging(); | ||
154 | |||
155 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); | ||
156 | int dsrv = (int)InvokeOp("JsonDestroyStore", storeId); | ||
157 | |||
158 | Assert.That(dsrv, Is.EqualTo(1)); | ||
159 | |||
160 | int tprv = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); | ||
161 | Assert.That(tprv, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
162 | } | ||
163 | |||
164 | [Test] | ||
165 | public void TestJsonDestroyStoreNotExists() | ||
166 | { | ||
167 | TestHelpers.InMethod(); | ||
168 | // TestHelpers.EnableLogging(); | ||
169 | |||
170 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
171 | |||
172 | int dsrv = (int)InvokeOp("JsonDestroyStore", fakeStoreId); | ||
173 | |||
174 | Assert.That(dsrv, Is.EqualTo(0)); | ||
175 | } | ||
176 | |||
177 | [Test] | ||
178 | public void TestJsonGetValue() | ||
179 | { | ||
180 | TestHelpers.InMethod(); | ||
181 | // TestHelpers.EnableLogging(); | ||
182 | |||
183 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); | ||
184 | |||
185 | { | ||
186 | string value = (string)InvokeOp("JsonGetValue", storeId, "Hello.World"); | ||
187 | Assert.That(value, Is.EqualTo("Two")); | ||
188 | } | ||
189 | |||
190 | // Test get of path section instead of leaf | ||
191 | { | ||
192 | string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); | ||
193 | Assert.That(value, Is.EqualTo("")); | ||
194 | } | ||
195 | |||
196 | // Test get of non-existing value | ||
197 | { | ||
198 | string fakeValueGet = (string)InvokeOp("JsonGetValue", storeId, "foo"); | ||
199 | Assert.That(fakeValueGet, Is.EqualTo("")); | ||
200 | } | ||
201 | |||
202 | // Test get from non-existing store | ||
203 | { | ||
204 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
205 | string fakeStoreValueGet = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); | ||
206 | Assert.That(fakeStoreValueGet, Is.EqualTo("")); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | [Test] | ||
211 | public void TestJsonGetJson() | ||
212 | { | ||
213 | TestHelpers.InMethod(); | ||
214 | // TestHelpers.EnableLogging(); | ||
215 | |||
216 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); | ||
217 | |||
218 | { | ||
219 | string value = (string)InvokeOp("JsonGetJson", storeId, "Hello.World"); | ||
220 | Assert.That(value, Is.EqualTo("'Two'")); | ||
221 | } | ||
222 | |||
223 | // Test get of path section instead of leaf | ||
224 | { | ||
225 | string value = (string)InvokeOp("JsonGetJson", storeId, "Hello"); | ||
226 | Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}")); | ||
227 | } | ||
228 | |||
229 | // Test get of non-existing value | ||
230 | { | ||
231 | string fakeValueGet = (string)InvokeOp("JsonGetJson", storeId, "foo"); | ||
232 | Assert.That(fakeValueGet, Is.EqualTo("")); | ||
233 | } | ||
234 | |||
235 | // Test get from non-existing store | ||
236 | { | ||
237 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
238 | string fakeStoreValueGet = (string)InvokeOp("JsonGetJson", fakeStoreId, "Hello"); | ||
239 | Assert.That(fakeStoreValueGet, Is.EqualTo("")); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | // [Test] | ||
244 | // public void TestJsonTakeValue() | ||
245 | // { | ||
246 | // TestHelpers.InMethod(); | ||
247 | //// TestHelpers.EnableLogging(); | ||
248 | // | ||
249 | // UUID storeId | ||
250 | // = (UUID)m_smcm.InvokeOperation( | ||
251 | // UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); | ||
252 | // | ||
253 | // string value | ||
254 | // = (string)m_smcm.InvokeOperation( | ||
255 | // UUID.Zero, UUID.Zero, "JsonTakeValue", new object[] { storeId, "Hello" }); | ||
256 | // | ||
257 | // Assert.That(value, Is.EqualTo("World")); | ||
258 | // | ||
259 | // string value2 | ||
260 | // = (string)m_smcm.InvokeOperation( | ||
261 | // UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" }); | ||
262 | // | ||
263 | // Assert.That(value, Is.Null); | ||
264 | // } | ||
265 | |||
266 | [Test] | ||
267 | public void TestJsonRemoveValue() | ||
268 | { | ||
269 | TestHelpers.InMethod(); | ||
270 | // TestHelpers.EnableLogging(); | ||
271 | |||
272 | // Test remove of node in object pointing to a string | ||
273 | { | ||
274 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); | ||
275 | |||
276 | int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); | ||
277 | Assert.That(returnValue, Is.EqualTo(1)); | ||
278 | |||
279 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); | ||
280 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
281 | |||
282 | string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello"); | ||
283 | Assert.That(returnValue2, Is.EqualTo("")); | ||
284 | } | ||
285 | |||
286 | // Test remove of node in object pointing to another object | ||
287 | { | ||
288 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Wally' } }"); | ||
289 | |||
290 | int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); | ||
291 | Assert.That(returnValue, Is.EqualTo(1)); | ||
292 | |||
293 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); | ||
294 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
295 | |||
296 | string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello"); | ||
297 | Assert.That(returnValue2, Is.EqualTo("")); | ||
298 | } | ||
299 | |||
300 | // Test remove of node in an array | ||
301 | { | ||
302 | UUID storeId | ||
303 | = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : [ 'value1', 'value2' ] }"); | ||
304 | |||
305 | int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]"); | ||
306 | Assert.That(returnValue, Is.EqualTo(1)); | ||
307 | |||
308 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[0]"); | ||
309 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); | ||
310 | |||
311 | result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[1]"); | ||
312 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
313 | |||
314 | string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]"); | ||
315 | Assert.That(stringReturnValue, Is.EqualTo("value2")); | ||
316 | |||
317 | stringReturnValue = (string)InvokeOp("JsonGetJson", storeId, "Hello[1]"); | ||
318 | Assert.That(stringReturnValue, Is.EqualTo("")); | ||
319 | } | ||
320 | |||
321 | // Test remove of non-existing value | ||
322 | { | ||
323 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); | ||
324 | |||
325 | int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Cheese"); | ||
326 | Assert.That(fakeValueRemove, Is.EqualTo(0)); | ||
327 | } | ||
328 | |||
329 | { | ||
330 | // Test get from non-existing store | ||
331 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
332 | int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello"); | ||
333 | Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); | ||
334 | } | ||
335 | } | ||
336 | |||
337 | // [Test] | ||
338 | // public void TestJsonTestPath() | ||
339 | // { | ||
340 | // TestHelpers.InMethod(); | ||
341 | //// TestHelpers.EnableLogging(); | ||
342 | // | ||
343 | // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); | ||
344 | // | ||
345 | // { | ||
346 | // int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World"); | ||
347 | // Assert.That(result, Is.EqualTo(1)); | ||
348 | // } | ||
349 | // | ||
350 | // // Test for path which does not resolve to a value. | ||
351 | // { | ||
352 | // int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); | ||
353 | // Assert.That(result, Is.EqualTo(0)); | ||
354 | // } | ||
355 | // | ||
356 | // { | ||
357 | // int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo"); | ||
358 | // Assert.That(result2, Is.EqualTo(0)); | ||
359 | // } | ||
360 | // | ||
361 | // // Test with fake store | ||
362 | // { | ||
363 | // UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
364 | // int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello"); | ||
365 | // Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); | ||
366 | // } | ||
367 | // } | ||
368 | |||
369 | // [Test] | ||
370 | // public void TestJsonTestPathJson() | ||
371 | // { | ||
372 | // TestHelpers.InMethod(); | ||
373 | //// TestHelpers.EnableLogging(); | ||
374 | // | ||
375 | // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); | ||
376 | // | ||
377 | // { | ||
378 | // int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World"); | ||
379 | // Assert.That(result, Is.EqualTo(1)); | ||
380 | // } | ||
381 | // | ||
382 | // // Test for path which does not resolve to a value. | ||
383 | // { | ||
384 | // int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello"); | ||
385 | // Assert.That(result, Is.EqualTo(1)); | ||
386 | // } | ||
387 | // | ||
388 | // { | ||
389 | // int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo"); | ||
390 | // Assert.That(result2, Is.EqualTo(0)); | ||
391 | // } | ||
392 | // | ||
393 | // // Test with fake store | ||
394 | // { | ||
395 | // UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
396 | // int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello"); | ||
397 | // Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); | ||
398 | // } | ||
399 | // } | ||
400 | |||
401 | [Test] | ||
402 | public void TestJsonGetArrayLength() | ||
403 | { | ||
404 | TestHelpers.InMethod(); | ||
405 | // TestHelpers.EnableLogging(); | ||
406 | |||
407 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); | ||
408 | |||
409 | { | ||
410 | int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello.World"); | ||
411 | Assert.That(result, Is.EqualTo(2)); | ||
412 | } | ||
413 | |||
414 | // Test path which is not an array | ||
415 | { | ||
416 | int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello"); | ||
417 | Assert.That(result, Is.EqualTo(-1)); | ||
418 | } | ||
419 | |||
420 | // Test fake path | ||
421 | { | ||
422 | int result = (int)InvokeOp("JsonGetArrayLength", storeId, "foo"); | ||
423 | Assert.That(result, Is.EqualTo(-1)); | ||
424 | } | ||
425 | |||
426 | // Test fake store | ||
427 | { | ||
428 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
429 | int result = (int)InvokeOp("JsonGetArrayLength", fakeStoreId, "Hello.World"); | ||
430 | Assert.That(result, Is.EqualTo(-1)); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | [Test] | ||
435 | public void TestJsonGetNodeType() | ||
436 | { | ||
437 | TestHelpers.InMethod(); | ||
438 | // TestHelpers.EnableLogging(); | ||
439 | |||
440 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); | ||
441 | |||
442 | { | ||
443 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "."); | ||
444 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT)); | ||
445 | } | ||
446 | |||
447 | { | ||
448 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); | ||
449 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT)); | ||
450 | } | ||
451 | |||
452 | { | ||
453 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World"); | ||
454 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_ARRAY)); | ||
455 | } | ||
456 | |||
457 | { | ||
458 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[0]"); | ||
459 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); | ||
460 | } | ||
461 | |||
462 | { | ||
463 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[1]"); | ||
464 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); | ||
465 | } | ||
466 | |||
467 | // Test for non-existent path | ||
468 | { | ||
469 | int result = (int)InvokeOp("JsonGetNodeType", storeId, "foo"); | ||
470 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
471 | } | ||
472 | |||
473 | // Test for non-existent store | ||
474 | { | ||
475 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
476 | int result = (int)InvokeOp("JsonGetNodeType", fakeStoreId, "."); | ||
477 | Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); | ||
478 | } | ||
479 | } | ||
480 | |||
481 | [Test] | ||
482 | public void TestJsonList2Path() | ||
483 | { | ||
484 | TestHelpers.InMethod(); | ||
485 | // TestHelpers.EnableLogging(); | ||
486 | |||
487 | // Invoking these methods directly since I just couldn't get comms module invocation to work for some reason | ||
488 | // - some confusion with the methods that take a params object[] invocation. | ||
489 | { | ||
490 | string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo" }); | ||
491 | Assert.That(result, Is.EqualTo("{foo}")); | ||
492 | } | ||
493 | |||
494 | { | ||
495 | string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", "bar" }); | ||
496 | Assert.That(result, Is.EqualTo("{foo}.{bar}")); | ||
497 | } | ||
498 | |||
499 | { | ||
500 | string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", 1, "bar" }); | ||
501 | Assert.That(result, Is.EqualTo("{foo}.[1].{bar}")); | ||
502 | } | ||
503 | } | ||
504 | |||
505 | [Test] | ||
506 | public void TestJsonSetValue() | ||
507 | { | ||
508 | TestHelpers.InMethod(); | ||
509 | // TestHelpers.EnableLogging(); | ||
510 | |||
511 | { | ||
512 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
513 | |||
514 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times"); | ||
515 | Assert.That(result, Is.EqualTo(1)); | ||
516 | |||
517 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); | ||
518 | Assert.That(value, Is.EqualTo("Times")); | ||
519 | } | ||
520 | |||
521 | // Test setting a key containing periods with delineation | ||
522 | { | ||
523 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
524 | |||
525 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times"); | ||
526 | Assert.That(result, Is.EqualTo(1)); | ||
527 | |||
528 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}"); | ||
529 | Assert.That(value, Is.EqualTo("Times")); | ||
530 | } | ||
531 | |||
532 | // *** Test [] *** | ||
533 | |||
534 | // Test setting a key containing unbalanced ] without delineation. Expecting failure | ||
535 | { | ||
536 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
537 | |||
538 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun]Circus", "Times"); | ||
539 | Assert.That(result, Is.EqualTo(0)); | ||
540 | |||
541 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun]Circus"); | ||
542 | Assert.That(value, Is.EqualTo("")); | ||
543 | } | ||
544 | |||
545 | // Test setting a key containing unbalanced [ without delineation. Expecting failure | ||
546 | { | ||
547 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
548 | |||
549 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[Circus", "Times"); | ||
550 | Assert.That(result, Is.EqualTo(0)); | ||
551 | |||
552 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[Circus"); | ||
553 | Assert.That(value, Is.EqualTo("")); | ||
554 | } | ||
555 | |||
556 | // Test setting a key containing unbalanced [] without delineation. Expecting failure | ||
557 | { | ||
558 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
559 | |||
560 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[]Circus", "Times"); | ||
561 | Assert.That(result, Is.EqualTo(0)); | ||
562 | |||
563 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[]Circus"); | ||
564 | Assert.That(value, Is.EqualTo("")); | ||
565 | } | ||
566 | |||
567 | // Test setting a key containing unbalanced ] with delineation | ||
568 | { | ||
569 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
570 | |||
571 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun]Circus}", "Times"); | ||
572 | Assert.That(result, Is.EqualTo(1)); | ||
573 | |||
574 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun]Circus}"); | ||
575 | Assert.That(value, Is.EqualTo("Times")); | ||
576 | } | ||
577 | |||
578 | // Test setting a key containing unbalanced [ with delineation | ||
579 | { | ||
580 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
581 | |||
582 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[Circus}", "Times"); | ||
583 | Assert.That(result, Is.EqualTo(1)); | ||
584 | |||
585 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[Circus}"); | ||
586 | Assert.That(value, Is.EqualTo("Times")); | ||
587 | } | ||
588 | |||
589 | // Test setting a key containing empty balanced [] with delineation | ||
590 | { | ||
591 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
592 | |||
593 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[]Circus}", "Times"); | ||
594 | Assert.That(result, Is.EqualTo(1)); | ||
595 | |||
596 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}"); | ||
597 | Assert.That(value, Is.EqualTo("Times")); | ||
598 | } | ||
599 | |||
600 | // // Commented out as this currently unexpectedly fails. | ||
601 | // // Test setting a key containing brackets around an integer with delineation | ||
602 | // { | ||
603 | // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
604 | // | ||
605 | // int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[0]Circus}", "Times"); | ||
606 | // Assert.That(result, Is.EqualTo(1)); | ||
607 | // | ||
608 | // string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[0]Circus}"); | ||
609 | // Assert.That(value, Is.EqualTo("Times")); | ||
610 | // } | ||
611 | |||
612 | // *** Test {} *** | ||
613 | |||
614 | // Test setting a key containing unbalanced } without delineation. Expecting failure (?) | ||
615 | { | ||
616 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
617 | |||
618 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun}Circus", "Times"); | ||
619 | Assert.That(result, Is.EqualTo(0)); | ||
620 | |||
621 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus"); | ||
622 | Assert.That(value, Is.EqualTo("")); | ||
623 | } | ||
624 | |||
625 | // Test setting a key containing unbalanced { without delineation. Expecting failure (?) | ||
626 | { | ||
627 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
628 | |||
629 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun{Circus", "Times"); | ||
630 | Assert.That(result, Is.EqualTo(0)); | ||
631 | |||
632 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus"); | ||
633 | Assert.That(value, Is.EqualTo("")); | ||
634 | } | ||
635 | |||
636 | // // Commented out as this currently unexpectedly fails. | ||
637 | // // Test setting a key containing unbalanced } | ||
638 | // { | ||
639 | // UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
640 | // | ||
641 | // int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun}Circus}", "Times"); | ||
642 | // Assert.That(result, Is.EqualTo(0)); | ||
643 | // } | ||
644 | |||
645 | // Test setting a key containing unbalanced { with delineation | ||
646 | { | ||
647 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
648 | |||
649 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Circus}", "Times"); | ||
650 | Assert.That(result, Is.EqualTo(1)); | ||
651 | |||
652 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Circus}"); | ||
653 | Assert.That(value, Is.EqualTo("Times")); | ||
654 | } | ||
655 | |||
656 | // Test setting a key containing balanced {} with delineation. This should fail. | ||
657 | { | ||
658 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
659 | |||
660 | int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Filled}Circus}", "Times"); | ||
661 | Assert.That(result, Is.EqualTo(0)); | ||
662 | |||
663 | string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Filled}Circus}"); | ||
664 | Assert.That(value, Is.EqualTo("")); | ||
665 | } | ||
666 | |||
667 | // Test setting to location that does not exist. This should fail. | ||
668 | { | ||
669 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
670 | |||
671 | int result = (int)InvokeOp("JsonSetValue", storeId, "Fun.Circus", "Times"); | ||
672 | Assert.That(result, Is.EqualTo(0)); | ||
673 | |||
674 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus"); | ||
675 | Assert.That(value, Is.EqualTo("")); | ||
676 | } | ||
677 | |||
678 | // Test with fake store | ||
679 | { | ||
680 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
681 | int fakeStoreValueSet = (int)InvokeOp("JsonSetValue", fakeStoreId, "Hello", "World"); | ||
682 | Assert.That(fakeStoreValueSet, Is.EqualTo(0)); | ||
683 | } | ||
684 | } | ||
685 | |||
686 | [Test] | ||
687 | public void TestJsonSetJson() | ||
688 | { | ||
689 | TestHelpers.InMethod(); | ||
690 | // TestHelpers.EnableLogging(); | ||
691 | |||
692 | // Single quoted token case | ||
693 | { | ||
694 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); | ||
695 | |||
696 | int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "'Times'"); | ||
697 | Assert.That(result, Is.EqualTo(1)); | ||
698 | |||
699 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); | ||
700 | Assert.That(value, Is.EqualTo("Times")); | ||
701 | } | ||
702 | |||
703 | // Sub-tree case | ||
704 | { | ||
705 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); | ||
706 | |||
707 | int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "{ 'Filled' : 'Times' }"); | ||
708 | Assert.That(result, Is.EqualTo(1)); | ||
709 | |||
710 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled"); | ||
711 | Assert.That(value, Is.EqualTo("Times")); | ||
712 | } | ||
713 | |||
714 | // If setting single strings in JsonSetValueJson, these must be single quoted tokens, not bare strings. | ||
715 | { | ||
716 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); | ||
717 | |||
718 | int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "Times"); | ||
719 | Assert.That(result, Is.EqualTo(0)); | ||
720 | |||
721 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); | ||
722 | Assert.That(value, Is.EqualTo("")); | ||
723 | } | ||
724 | |||
725 | // Test setting to location that does not exist. This should fail. | ||
726 | { | ||
727 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); | ||
728 | |||
729 | int result = (int)InvokeOp("JsonSetJson", storeId, "Fun.Circus", "'Times'"); | ||
730 | Assert.That(result, Is.EqualTo(0)); | ||
731 | |||
732 | string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus"); | ||
733 | Assert.That(value, Is.EqualTo("")); | ||
734 | } | ||
735 | |||
736 | // Test with fake store | ||
737 | { | ||
738 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
739 | int fakeStoreValueSet = (int)InvokeOp("JsonSetJson", fakeStoreId, "Hello", "'World'"); | ||
740 | Assert.That(fakeStoreValueSet, Is.EqualTo(0)); | ||
741 | } | ||
742 | } | ||
743 | |||
744 | /// <summary> | ||
745 | /// Test for writing json to a notecard | ||
746 | /// </summary> | ||
747 | /// <remarks> | ||
748 | /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching | ||
749 | /// it via the MockScriptEngine or perhaps by a dummy script instance. | ||
750 | /// </remarks> | ||
751 | [Test] | ||
752 | public void TestJsonWriteNotecard() | ||
753 | { | ||
754 | TestHelpers.InMethod(); | ||
755 | // TestHelpers.EnableLogging(); | ||
756 | |||
757 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); | ||
758 | m_scene.AddSceneObject(so); | ||
759 | |||
760 | UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); | ||
761 | |||
762 | { | ||
763 | string notecardName = "nc1"; | ||
764 | |||
765 | // Write notecard | ||
766 | UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "", notecardName); | ||
767 | Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
768 | |||
769 | TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName); | ||
770 | Assert.That(nc1Item, Is.Not.Null); | ||
771 | |||
772 | // TODO: Should independently check the contents. | ||
773 | } | ||
774 | |||
775 | // TODO: Write partial test | ||
776 | |||
777 | { | ||
778 | // Try to write notecard for a bad path | ||
779 | // In this case we do get a request id but no notecard is written. | ||
780 | string badPathNotecardName = "badPathNotecardName"; | ||
781 | |||
782 | UUID writeNotecardBadPathRequestId | ||
783 | = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "flibble", badPathNotecardName); | ||
784 | Assert.That(writeNotecardBadPathRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
785 | |||
786 | TaskInventoryItem badPathItem = so.RootPart.Inventory.GetInventoryItem(badPathNotecardName); | ||
787 | Assert.That(badPathItem, Is.Null); | ||
788 | } | ||
789 | |||
790 | { | ||
791 | // Test with fake store | ||
792 | // In this case we do get a request id but no notecard is written. | ||
793 | string fakeStoreNotecardName = "fakeStoreNotecardName"; | ||
794 | |||
795 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
796 | UUID fakeStoreWriteNotecardValue | ||
797 | = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName); | ||
798 | Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero)); | ||
799 | |||
800 | TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName); | ||
801 | Assert.That(fakeStoreItem, Is.Null); | ||
802 | } | ||
803 | } | ||
804 | |||
805 | /// <summary> | ||
806 | /// Test for reading json from a notecard | ||
807 | /// </summary> | ||
808 | /// <remarks> | ||
809 | /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching | ||
810 | /// it via the MockScriptEngine or perhaps by a dummy script instance. | ||
811 | /// </remarks> | ||
812 | [Test] | ||
813 | public void TestJsonReadNotecard() | ||
814 | { | ||
815 | TestHelpers.InMethod(); | ||
816 | // TestHelpers.EnableLogging(); | ||
817 | |||
818 | string notecardName = "nc1"; | ||
819 | |||
820 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); | ||
821 | m_scene.AddSceneObject(so); | ||
822 | |||
823 | UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); | ||
824 | |||
825 | // Write notecard | ||
826 | InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName); | ||
827 | |||
828 | { | ||
829 | // Read notecard | ||
830 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
831 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName); | ||
832 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
833 | |||
834 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
835 | Assert.That(value, Is.EqualTo("World")); | ||
836 | } | ||
837 | |||
838 | { | ||
839 | // Read notecard to new single component path | ||
840 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
841 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName); | ||
842 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
843 | |||
844 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
845 | Assert.That(value, Is.EqualTo("")); | ||
846 | |||
847 | value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello"); | ||
848 | Assert.That(value, Is.EqualTo("World")); | ||
849 | } | ||
850 | |||
851 | { | ||
852 | // Read notecard to new multi-component path. This should not work. | ||
853 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); | ||
854 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName); | ||
855 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
856 | |||
857 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
858 | Assert.That(value, Is.EqualTo("")); | ||
859 | |||
860 | value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello"); | ||
861 | Assert.That(value, Is.EqualTo("")); | ||
862 | } | ||
863 | |||
864 | { | ||
865 | // Read notecard to existing multi-component path. This should work | ||
866 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }"); | ||
867 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName); | ||
868 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
869 | |||
870 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
871 | Assert.That(value, Is.EqualTo("")); | ||
872 | |||
873 | value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello"); | ||
874 | Assert.That(value, Is.EqualTo("World")); | ||
875 | } | ||
876 | |||
877 | { | ||
878 | // Read notecard to invalid path. This should not work. | ||
879 | UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }"); | ||
880 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); | ||
881 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
882 | |||
883 | string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); | ||
884 | Assert.That(value, Is.EqualTo("")); | ||
885 | } | ||
886 | |||
887 | { | ||
888 | // Try read notecard to fake store. | ||
889 | UUID fakeStoreId = TestHelpers.ParseTail(0x500); | ||
890 | UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName); | ||
891 | Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); | ||
892 | |||
893 | string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); | ||
894 | Assert.That(value, Is.EqualTo("")); | ||
895 | } | ||
896 | } | ||
897 | |||
898 | public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } | ||
899 | } | ||
900 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/ExtensionHandler.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/ExtensionHandler.cs new file mode 100644 index 0000000..3f1bd54 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/ExtensionHandler.cs | |||
@@ -0,0 +1,66 @@ | |||
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.Text; | ||
31 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.Interfaces; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
34 | { | ||
35 | class ExtensionHandler : IExtension | ||
36 | { | ||
37 | private readonly Dictionary<Type, object> m_instances; | ||
38 | |||
39 | public ExtensionHandler(Dictionary<Type, object> instances) | ||
40 | { | ||
41 | m_instances = instances; | ||
42 | } | ||
43 | |||
44 | public T Get<T>() | ||
45 | { | ||
46 | return (T) m_instances[typeof (T)]; | ||
47 | } | ||
48 | |||
49 | public bool TryGet<T>(out T extension) | ||
50 | { | ||
51 | if (!m_instances.ContainsKey(typeof(T))) | ||
52 | { | ||
53 | extension = default(T); | ||
54 | return false; | ||
55 | } | ||
56 | |||
57 | extension = Get<T>(); | ||
58 | return true; | ||
59 | } | ||
60 | |||
61 | public bool Has<T>() | ||
62 | { | ||
63 | return m_instances.ContainsKey(typeof (T)); | ||
64 | } | ||
65 | } | ||
66 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs new file mode 100644 index 0000000..a0dc38b --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs | |||
@@ -0,0 +1,72 @@ | |||
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.Drawing; | ||
29 | using OpenMetaverse; | ||
30 | using OpenMetaverse.Imaging; | ||
31 | using OpenSim.Framework; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | |||
34 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
35 | { | ||
36 | class Graphics : System.MarshalByRefObject, IGraphics | ||
37 | { | ||
38 | private readonly Scene m_scene; | ||
39 | |||
40 | public Graphics(Scene m_scene) | ||
41 | { | ||
42 | this.m_scene = m_scene; | ||
43 | } | ||
44 | |||
45 | public UUID SaveBitmap(Bitmap data) | ||
46 | { | ||
47 | return SaveBitmap(data, false, true); | ||
48 | } | ||
49 | |||
50 | public UUID SaveBitmap(Bitmap data, bool lossless, bool temporary) | ||
51 | { | ||
52 | AssetBase asset = new AssetBase(UUID.Random(), "MRMDynamicImage", (sbyte)AssetType.Texture, m_scene.RegionInfo.RegionID.ToString()); | ||
53 | asset.Data = OpenJPEG.EncodeFromImage(data, lossless); | ||
54 | asset.Description = "MRM Image"; | ||
55 | asset.Local = false; | ||
56 | asset.Temporary = temporary; | ||
57 | m_scene.AssetService.Store(asset); | ||
58 | |||
59 | return asset.FullID; | ||
60 | } | ||
61 | |||
62 | public Bitmap LoadBitmap(UUID assetID) | ||
63 | { | ||
64 | AssetBase bmp = m_scene.AssetService.Get(assetID.ToString()); | ||
65 | ManagedImage outimg; | ||
66 | Image img; | ||
67 | OpenJPEG.DecodeToImage(bmp.Data, out outimg, out img); | ||
68 | |||
69 | return new Bitmap(img); | ||
70 | } | ||
71 | } | ||
72 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Heightmap.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Heightmap.cs new file mode 100644 index 0000000..47c3085 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Heightmap.cs | |||
@@ -0,0 +1,67 @@ | |||
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 OpenSim.Region.Framework.Scenes; | ||
29 | |||
30 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
31 | { | ||
32 | public class Heightmap : System.MarshalByRefObject, IHeightmap | ||
33 | { | ||
34 | private readonly Scene m_scene; | ||
35 | |||
36 | public Heightmap(Scene scene) | ||
37 | { | ||
38 | m_scene = scene; | ||
39 | } | ||
40 | |||
41 | public double this[int x, int y] | ||
42 | { | ||
43 | get { return Get(x, y); } | ||
44 | set { Set(x, y, value); } | ||
45 | } | ||
46 | |||
47 | public int Length | ||
48 | { | ||
49 | get { return m_scene.Heightmap.Height; } | ||
50 | } | ||
51 | |||
52 | public int Width | ||
53 | { | ||
54 | get { return m_scene.Heightmap.Width; } | ||
55 | } | ||
56 | |||
57 | protected double Get(int x, int y) | ||
58 | { | ||
59 | return m_scene.Heightmap[x, y]; | ||
60 | } | ||
61 | |||
62 | protected void Set(int x, int y, double val) | ||
63 | { | ||
64 | m_scene.Heightmap[x, y] = val; | ||
65 | } | ||
66 | } | ||
67 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Host.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Host.cs new file mode 100644 index 0000000..cbde283 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Host.cs | |||
@@ -0,0 +1,79 @@ | |||
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.Reflection; | ||
29 | using log4net; | ||
30 | using OpenSim.Region.Framework.Scenes; | ||
31 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.Interfaces; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
34 | { | ||
35 | class Host : System.MarshalByRefObject, IHost | ||
36 | { | ||
37 | private readonly IObject m_obj; | ||
38 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
39 | private readonly IGraphics m_graphics; | ||
40 | private readonly IExtension m_extend; | ||
41 | private readonly IMicrothreader m_threader; | ||
42 | //private Scene m_scene; | ||
43 | |||
44 | public Host(IObject m_obj, Scene m_scene, IExtension m_extend, IMicrothreader m_threader) | ||
45 | { | ||
46 | this.m_obj = m_obj; | ||
47 | this.m_threader = m_threader; | ||
48 | this.m_extend = m_extend; | ||
49 | //this.m_scene = m_scene; | ||
50 | |||
51 | m_graphics = new Graphics(m_scene); | ||
52 | } | ||
53 | |||
54 | public IObject Object | ||
55 | { | ||
56 | get { return m_obj; } | ||
57 | } | ||
58 | |||
59 | public ILog Console | ||
60 | { | ||
61 | get { return m_log; } | ||
62 | } | ||
63 | |||
64 | public IGraphics Graphics | ||
65 | { | ||
66 | get { return m_graphics; } | ||
67 | } | ||
68 | |||
69 | public IExtension Extensions | ||
70 | { | ||
71 | get { return m_extend; } | ||
72 | } | ||
73 | |||
74 | public IMicrothreader Microthreads | ||
75 | { | ||
76 | get { return m_threader; } | ||
77 | } | ||
78 | } | ||
79 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/IMRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/IMRMModule.cs new file mode 100644 index 0000000..e957a62 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/IMRMModule.cs | |||
@@ -0,0 +1,38 @@ | |||
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 OpenMetaverse; | ||
29 | |||
30 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
31 | { | ||
32 | public interface IMRMModule | ||
33 | { | ||
34 | void RegisterExtension<T>(T instance); | ||
35 | void InitializeMRM(MRMBase mmb, uint localID, UUID itemID); | ||
36 | void GetGlobalEnvironment(uint localID, out IWorld world, out IHost host); | ||
37 | } | ||
38 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/ISecurityCredential.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/ISecurityCredential.cs new file mode 100644 index 0000000..533d176 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/ISecurityCredential.cs | |||
@@ -0,0 +1,36 @@ | |||
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 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
29 | { | ||
30 | public interface ISecurityCredential | ||
31 | { | ||
32 | ISocialEntity owner { get; } | ||
33 | bool CanEditObject(IObject target); | ||
34 | bool CanEditTerrain(int x, int y); | ||
35 | } | ||
36 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IAvatar.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IAvatar.cs new file mode 100644 index 0000000..3d49732 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IAvatar.cs | |||
@@ -0,0 +1,51 @@ | |||
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.Text; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
34 | { | ||
35 | public interface IAvatar : IEntity | ||
36 | { | ||
37 | |||
38 | bool IsChildAgent { get; } | ||
39 | |||
40 | //// <value> | ||
41 | /// Array of worn attachments, empty but not null, if no attachments are worn | ||
42 | /// </value> | ||
43 | |||
44 | IAvatarAttachment[] Attachments { get; } | ||
45 | |||
46 | /// <summary> | ||
47 | /// Request to open an url clientside | ||
48 | /// </summary> | ||
49 | void LoadUrl(IObject sender, string message, string url); | ||
50 | } | ||
51 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IAvatarAttachment.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IAvatarAttachment.cs new file mode 100644 index 0000000..1993948 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IAvatarAttachment.cs | |||
@@ -0,0 +1,42 @@ | |||
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 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
29 | { | ||
30 | public interface IAvatarAttachment | ||
31 | { | ||
32 | //// <value> | ||
33 | /// Describes where on the avatar the attachment is located | ||
34 | /// </value> | ||
35 | int Location { get ; } | ||
36 | |||
37 | //// <value> | ||
38 | /// Accessor to the rez'ed asset, representing the attachment | ||
39 | /// </value> | ||
40 | IObject Asset { get; } | ||
41 | } | ||
42 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IEntity.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IEntity.cs new file mode 100644 index 0000000..6ea23df --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IEntity.cs | |||
@@ -0,0 +1,41 @@ | |||
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.Text; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
34 | { | ||
35 | public interface IEntity | ||
36 | { | ||
37 | string Name { get; set; } | ||
38 | UUID GlobalID { get; } | ||
39 | Vector3 WorldPosition { get; set; } | ||
40 | } | ||
41 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IExtension.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IExtension.cs new file mode 100644 index 0000000..f5beebd --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IExtension.cs | |||
@@ -0,0 +1,40 @@ | |||
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.Text; | ||
31 | |||
32 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.Interfaces | ||
33 | { | ||
34 | public interface IExtension | ||
35 | { | ||
36 | T Get<T>(); | ||
37 | bool TryGet<T>(out T extension); | ||
38 | bool Has<T>(); | ||
39 | } | ||
40 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IGraphics.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IGraphics.cs new file mode 100644 index 0000000..012cd37 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IGraphics.cs | |||
@@ -0,0 +1,39 @@ | |||
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.Drawing; | ||
29 | using OpenMetaverse; | ||
30 | |||
31 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
32 | { | ||
33 | public interface IGraphics | ||
34 | { | ||
35 | UUID SaveBitmap(Bitmap data); | ||
36 | UUID SaveBitmap(Bitmap data, bool lossless, bool temporary); | ||
37 | Bitmap LoadBitmap(UUID assetID); | ||
38 | } | ||
39 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IHeightmap.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IHeightmap.cs new file mode 100644 index 0000000..93cbc5b --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IHeightmap.cs | |||
@@ -0,0 +1,69 @@ | |||
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.Text; | ||
31 | |||
32 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
33 | { | ||
34 | public interface IHeightmap | ||
35 | { | ||
36 | /// <summary> | ||
37 | /// Returns [or sets] the heightmap value at specified coordinates. | ||
38 | /// </summary> | ||
39 | /// <param name="x">X Coordinate</param> | ||
40 | /// <param name="y">Y Coordinate</param> | ||
41 | /// <returns>A value in meters representing height. Can be negative. Value correlates with Z parameter in world coordinates</returns> | ||
42 | /// <example> | ||
43 | /// double heightVal = World.Heightmap[128,128]; | ||
44 | /// World.Heightmap[128,128] *= 5.0; | ||
45 | /// World.Heightmap[128,128] = 25; | ||
46 | /// </example> | ||
47 | double this[int x, int y] | ||
48 | { | ||
49 | get; | ||
50 | set; | ||
51 | } | ||
52 | |||
53 | /// <summary> | ||
54 | /// The maximum length of the region (Y axis), exclusive. (eg Height = 256, max Y = 255). Minimum is always 0 inclusive. | ||
55 | /// </summary> | ||
56 | /// <example> | ||
57 | /// Host.Console.Info("The terrain length of this region is " + World.Heightmap.Length); | ||
58 | /// </example> | ||
59 | int Length { get; } | ||
60 | |||
61 | /// <summary> | ||
62 | /// The maximum width of the region (X axis), exclusive. (eg Width = 256, max X = 255). Minimum is always 0 inclusive. | ||
63 | /// </summary> | ||
64 | /// <example> | ||
65 | /// Host.Console.Info("The terrain width of this region is " + World.Heightmap.Width); | ||
66 | /// </example> | ||
67 | int Width { get; } | ||
68 | } | ||
69 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IHost.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IHost.cs new file mode 100644 index 0000000..cf63fd6 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IHost.cs | |||
@@ -0,0 +1,44 @@ | |||
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.Text; | ||
31 | using log4net; | ||
32 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.Interfaces; | ||
33 | |||
34 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
35 | { | ||
36 | public interface IHost | ||
37 | { | ||
38 | IObject Object { get; } | ||
39 | ILog Console { get; } | ||
40 | IGraphics Graphics { get; } | ||
41 | IExtension Extensions { get; } | ||
42 | IMicrothreader Microthreads { get; } | ||
43 | } | ||
44 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs new file mode 100644 index 0000000..a8e545c --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs | |||
@@ -0,0 +1,43 @@ | |||
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 OpenMetaverse; | ||
30 | using OpenMetaverse.Assets; | ||
31 | |||
32 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
33 | { | ||
34 | /// <summary> | ||
35 | /// This implements the methods needed to operate on individual inventory items. | ||
36 | /// </summary> | ||
37 | public interface IInventoryItem | ||
38 | { | ||
39 | int Type { get; } | ||
40 | UUID AssetID { get; } | ||
41 | T RetrieveAsset<T>() where T : OpenMetaverse.Assets.Asset, new(); | ||
42 | } | ||
43 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IMicrothreader.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IMicrothreader.cs new file mode 100644 index 0000000..2723476 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IMicrothreader.cs | |||
@@ -0,0 +1,39 @@ | |||
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; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Text; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.Interfaces | ||
34 | { | ||
35 | public interface IMicrothreader | ||
36 | { | ||
37 | void Run(IEnumerable microthread); | ||
38 | } | ||
39 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IObject.cs new file mode 100644 index 0000000..e189489 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IObject.cs | |||
@@ -0,0 +1,245 @@ | |||
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.Drawing; | ||
30 | using OpenMetaverse; | ||
31 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.Object; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
34 | { | ||
35 | [Serializable] | ||
36 | public class TouchEventArgs : EventArgs | ||
37 | { | ||
38 | public IAvatar Avatar; | ||
39 | |||
40 | public Vector3 TouchBiNormal; | ||
41 | public Vector3 TouchNormal; | ||
42 | public Vector3 TouchPosition; | ||
43 | |||
44 | public Vector2 TouchUV; | ||
45 | public Vector2 TouchST; | ||
46 | |||
47 | public int TouchMaterialIndex; | ||
48 | } | ||
49 | |||
50 | public delegate void OnTouchDelegate(IObject sender, TouchEventArgs e); | ||
51 | |||
52 | public interface IObject : IEntity | ||
53 | { | ||
54 | #region Events | ||
55 | |||
56 | event OnTouchDelegate OnTouch; | ||
57 | |||
58 | #endregion | ||
59 | |||
60 | /// <summary> | ||
61 | /// Returns whether or not this object is still in the world. | ||
62 | /// Eg, if you store an IObject reference, however the object | ||
63 | /// is deleted before you use it, it will throw a NullReference | ||
64 | /// exception. 'Exists' allows you to check the object is still | ||
65 | /// in play before utilizing it. | ||
66 | /// </summary> | ||
67 | /// <example> | ||
68 | /// IObject deleteMe = World.Objects[0]; | ||
69 | /// | ||
70 | /// if (deleteMe.Exists) { | ||
71 | /// deleteMe.Say("Hello, I still exist!"); | ||
72 | /// } | ||
73 | /// | ||
74 | /// World.Objects.Remove(deleteMe); | ||
75 | /// | ||
76 | /// if (!deleteMe.Exists) { | ||
77 | /// Host.Console.Info("I was deleted"); | ||
78 | /// } | ||
79 | /// </example> | ||
80 | /// <remarks> | ||
81 | /// Objects should be near-guarunteed to exist for any event which | ||
82 | /// passes them as an argument. Storing an object for a longer period | ||
83 | /// of time however will limit their reliability. | ||
84 | /// | ||
85 | /// It is a good practice to use Try/Catch blocks handling for | ||
86 | /// NullReferenceException, when accessing remote objects. | ||
87 | /// </remarks> | ||
88 | bool Exists { get; } | ||
89 | |||
90 | /// <summary> | ||
91 | /// The local region-unique ID for this object. | ||
92 | /// </summary> | ||
93 | uint LocalID { get; } | ||
94 | |||
95 | /// <summary> | ||
96 | /// The description assigned to this object. | ||
97 | /// </summary> | ||
98 | String Description { get; set; } | ||
99 | |||
100 | /// <summary> | ||
101 | /// Returns the UUID of the Owner of the Object. | ||
102 | /// </summary> | ||
103 | UUID OwnerId { get; } | ||
104 | |||
105 | /// <summary> | ||
106 | /// Returns the UUID of the Creator of the Object. | ||
107 | /// </summary> | ||
108 | UUID CreatorId { get; } | ||
109 | |||
110 | /// <summary> | ||
111 | /// Returns the root object of a linkset. If this object is the root, it will return itself. | ||
112 | /// </summary> | ||
113 | IObject Root { get; } | ||
114 | |||
115 | /// <summary> | ||
116 | /// Returns a collection of objects which are linked to the current object. Does not include the root object. | ||
117 | /// </summary> | ||
118 | IObject[] Children { get; } | ||
119 | |||
120 | /// <summary> | ||
121 | /// Returns a list of materials attached to this object. Each may contain unique texture | ||
122 | /// and other visual information. For primitive based objects, this correlates with | ||
123 | /// Object Faces. For mesh based objects, this correlates with Materials. | ||
124 | /// </summary> | ||
125 | IObjectMaterial[] Materials { get; } | ||
126 | |||
127 | /// <summary> | ||
128 | /// The bounding box of the object. Primitive and Mesh objects alike are scaled to fit within these bounds. | ||
129 | /// </summary> | ||
130 | Vector3 Scale { get; set; } | ||
131 | |||
132 | /// <summary> | ||
133 | /// The rotation of the object relative to the Scene | ||
134 | /// </summary> | ||
135 | Quaternion WorldRotation { get; set; } | ||
136 | |||
137 | /// <summary> | ||
138 | /// The rotation of the object relative to a parent object | ||
139 | /// If root, works the same as WorldRotation | ||
140 | /// </summary> | ||
141 | Quaternion OffsetRotation { get; set; } | ||
142 | |||
143 | /// <summary> | ||
144 | /// The position of the object relative to a parent object | ||
145 | /// If root, works the same as WorldPosition | ||
146 | /// </summary> | ||
147 | Vector3 OffsetPosition { get; set; } | ||
148 | |||
149 | Vector3 SitTarget { get; set; } | ||
150 | String SitTargetText { get; set; } | ||
151 | |||
152 | String TouchText { get; set; } | ||
153 | |||
154 | /// <summary> | ||
155 | /// Text to be associated with this object, in the | ||
156 | /// Second Life(r) viewer, this is shown above the | ||
157 | /// object. | ||
158 | /// </summary> | ||
159 | String Text { get; set; } | ||
160 | |||
161 | bool IsRotationLockedX { get; set; } // SetStatus(!ROTATE_X) | ||
162 | bool IsRotationLockedY { get; set; } // SetStatus(!ROTATE_Y) | ||
163 | bool IsRotationLockedZ { get; set; } // SetStatus(!ROTATE_Z) | ||
164 | bool IsSandboxed { get; set; } // SetStatus(SANDBOX) | ||
165 | bool IsImmotile { get; set; } // SetStatus(BLOCK_GRAB) | ||
166 | bool IsAlwaysReturned { get; set; } // SetStatus(!DIE_AT_EDGE) | ||
167 | bool IsTemporary { get; set; } // TEMP_ON_REZ | ||
168 | |||
169 | bool IsFlexible { get; set; } | ||
170 | |||
171 | IObjectShape Shape { get; } | ||
172 | |||
173 | // TODO: | ||
174 | // PrimHole | ||
175 | // Repeats, Offsets, Cut/Dimple/ProfileCut | ||
176 | // Hollow, Twist, HoleSize, | ||
177 | // Taper[A+B], Shear[A+B], Revolutions, | ||
178 | // RadiusOffset, Skew | ||
179 | |||
180 | PhysicsMaterial PhysicsMaterial { get; set; } | ||
181 | |||
182 | IObjectPhysics Physics { get; } | ||
183 | |||
184 | IObjectSound Sound { get; } | ||
185 | |||
186 | /// <summary> | ||
187 | /// Causes the object to speak to its surroundings, | ||
188 | /// equivilent to LSL/OSSL llSay | ||
189 | /// </summary> | ||
190 | /// <param name="msg">The message to send to the user</param> | ||
191 | void Say(string msg); | ||
192 | |||
193 | /// <summary> | ||
194 | /// Causes the object to speak to on a specific channel, | ||
195 | /// equivilent to LSL/OSSL llSay | ||
196 | /// </summary> | ||
197 | /// <param name="msg">The message to send to the user</param> | ||
198 | /// <param name="channel">The channel on which to send the message</param> | ||
199 | void Say(string msg,int channel); | ||
200 | |||
201 | /// <summary> | ||
202 | /// Opens a Dialog Panel in the Users Viewer, | ||
203 | /// equivilent to LSL/OSSL llDialog | ||
204 | /// </summary> | ||
205 | /// <param name="avatar">The UUID of the Avatar to which the Dialog should be send</param> | ||
206 | /// <param name="message">The Message to display at the top of the Dialog</param> | ||
207 | /// <param name="buttons">The Strings that act as label/value of the Bottons in the Dialog</param> | ||
208 | /// <param name="chat_channel">The channel on which to send the response</param> | ||
209 | void Dialog(UUID avatar, string message, string[] buttons, int chat_channel); | ||
210 | |||
211 | //// <value> | ||
212 | /// Grants access to the objects inventory | ||
213 | /// </value> | ||
214 | IObjectInventory Inventory { get; } | ||
215 | } | ||
216 | |||
217 | public enum PhysicsMaterial | ||
218 | { | ||
219 | Default, | ||
220 | Glass, | ||
221 | Metal, | ||
222 | Plastic, | ||
223 | Wood, | ||
224 | Rubber, | ||
225 | Stone, | ||
226 | Flesh | ||
227 | } | ||
228 | |||
229 | public enum TextureMapping | ||
230 | { | ||
231 | Default, | ||
232 | Planar | ||
233 | } | ||
234 | |||
235 | public interface IObjectMaterial | ||
236 | { | ||
237 | Color Color { get; set; } | ||
238 | UUID Texture { get; set; } | ||
239 | TextureMapping Mapping { get; set; } // SetPrimParms(PRIM_TEXGEN) | ||
240 | bool Bright { get; set; } // SetPrimParms(FULLBRIGHT) | ||
241 | double Bloom { get; set; } // SetPrimParms(GLOW) | ||
242 | bool Shiny { get; set; } // SetPrimParms(SHINY) | ||
243 | bool BumpMap { get; set; } // SetPrimParms(BUMPMAP) [DEPRECATE IN FAVOUR OF UUID?] | ||
244 | } | ||
245 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IObjectAccessor.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IObjectAccessor.cs new file mode 100644 index 0000000..a6c8c36 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IObjectAccessor.cs | |||
@@ -0,0 +1,41 @@ | |||
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.Collections.Generic; | ||
29 | using OpenMetaverse; | ||
30 | |||
31 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
32 | { | ||
33 | public interface IObjectAccessor : ICollection<IObject> | ||
34 | { | ||
35 | IObject this[int index] { get; } | ||
36 | IObject this[uint index] { get; } | ||
37 | IObject this[UUID index] { get; } | ||
38 | IObject Create(Vector3 position); | ||
39 | IObject Create(Vector3 position, Quaternion rotation); | ||
40 | } | ||
41 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IParcel.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IParcel.cs new file mode 100644 index 0000000..759b26d --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IParcel.cs | |||
@@ -0,0 +1,42 @@ | |||
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.Text; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
34 | { | ||
35 | public interface IParcel | ||
36 | { | ||
37 | string Name { get; set; } | ||
38 | string Description { get; set; } | ||
39 | ISocialEntity Owner { get; set; } | ||
40 | bool[,] Bitmap { get; } | ||
41 | } | ||
42 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IPersistence.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IPersistence.cs new file mode 100644 index 0000000..17bb6e7 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IPersistence.cs | |||
@@ -0,0 +1,56 @@ | |||
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.Text; | ||
31 | |||
32 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
33 | { | ||
34 | interface IPersistence | ||
35 | { | ||
36 | T Get<T>(Guid storageID); | ||
37 | T Get<T>(); | ||
38 | |||
39 | /// <summary> | ||
40 | /// Stores 'data' into the persistence system | ||
41 | /// associated with this object, however saved | ||
42 | /// under the ID 'storageID'. This data may | ||
43 | /// be accessed by other scripts however. | ||
44 | /// </summary> | ||
45 | /// <param name="storageID"></param> | ||
46 | /// <param name="data"></param> | ||
47 | void Put<T>(Guid storageID, T data); | ||
48 | |||
49 | /// <summary> | ||
50 | /// Stores 'data' into the persistence system | ||
51 | /// using the default ID for this script. | ||
52 | /// </summary> | ||
53 | /// <param name="data"></param> | ||
54 | void Put<T>(T data); | ||
55 | } | ||
56 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IScheduler.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IScheduler.cs new file mode 100644 index 0000000..13e7934 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IScheduler.cs | |||
@@ -0,0 +1,79 @@ | |||
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 | |||
30 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
31 | { | ||
32 | interface IScheduler | ||
33 | { | ||
34 | /// <summary> | ||
35 | /// Schedule an event callback to occur | ||
36 | /// when 'time' is elapsed. | ||
37 | /// </summary> | ||
38 | /// <param name="time">The period to wait before executing</param> | ||
39 | void RunIn(TimeSpan time); | ||
40 | |||
41 | /// <summary> | ||
42 | /// Schedule an event callback to fire | ||
43 | /// every "time". Equivilent to a repeating | ||
44 | /// timer. | ||
45 | /// </summary> | ||
46 | /// <param name="time">The period to wait between executions</param> | ||
47 | void RunAndRepeat(TimeSpan time); | ||
48 | |||
49 | /// <summary> | ||
50 | /// Fire this scheduler only when the region has | ||
51 | /// a user in it. | ||
52 | /// </summary> | ||
53 | bool IfOccupied { get; set; } | ||
54 | |||
55 | /// <summary> | ||
56 | /// Fire this only when simulator performance | ||
57 | /// is reasonable. (eg sysload <= 1.0) | ||
58 | /// </summary> | ||
59 | bool IfHealthy { get; set; } | ||
60 | |||
61 | /// <summary> | ||
62 | /// Fire this event only when the region is visible | ||
63 | /// to a child agent, or there is a full agent | ||
64 | /// in this region. | ||
65 | /// </summary> | ||
66 | bool IfVisible { get; set; } | ||
67 | |||
68 | /// <summary> | ||
69 | /// Determines whether this runs in the master scheduler thread, or a new thread | ||
70 | /// is spawned to handle your request. Running in scheduler may mean that your | ||
71 | /// code does not execute perfectly on time, however will result in better | ||
72 | /// region performance. | ||
73 | /// </summary> | ||
74 | /// <remarks> | ||
75 | /// Default: true | ||
76 | /// </remarks> | ||
77 | bool Schedule { get; set; } | ||
78 | } | ||
79 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/ISocialEntity.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/ISocialEntity.cs new file mode 100644 index 0000000..400367f --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/ISocialEntity.cs | |||
@@ -0,0 +1,41 @@ | |||
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.Text; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
34 | { | ||
35 | public interface ISocialEntity | ||
36 | { | ||
37 | UUID GlobalID { get; } | ||
38 | string Name { get; } | ||
39 | bool IsUser { get; } | ||
40 | } | ||
41 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IWorld.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IWorld.cs new file mode 100644 index 0000000..3b3b3d0 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IWorld.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 OpenSim.Region.OptionalModules.Scripting.Minimodule.WorldX; | ||
30 | |||
31 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
32 | { | ||
33 | public class NewUserEventArgs : EventArgs | ||
34 | { | ||
35 | public IAvatar Avatar; | ||
36 | } | ||
37 | |||
38 | public delegate void OnNewUserDelegate(IWorld sender, NewUserEventArgs e); | ||
39 | |||
40 | public class ChatEventArgs : EventArgs | ||
41 | { | ||
42 | public string Text; | ||
43 | public IEntity Sender; | ||
44 | public int Channel; | ||
45 | } | ||
46 | |||
47 | public delegate void OnChatDelegate(IWorld sender, ChatEventArgs e); | ||
48 | |||
49 | public interface IWorld | ||
50 | { | ||
51 | IObjectAccessor Objects { get; } | ||
52 | IAvatar[] Avatars { get; } | ||
53 | IParcel[] Parcels { get; } | ||
54 | IHeightmap Terrain { get; } | ||
55 | IWorldAudio Audio { get; } | ||
56 | |||
57 | |||
58 | event OnChatDelegate OnChat; | ||
59 | event OnNewUserDelegate OnNewUser; | ||
60 | } | ||
61 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs new file mode 100644 index 0000000..bf85cbc --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs | |||
@@ -0,0 +1,98 @@ | |||
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.Text; | ||
30 | |||
31 | using OpenSim.Framework; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | //using OpenSim.Services.AssetService; | ||
34 | using OpenMetaverse; | ||
35 | using OpenMetaverse.Assets; | ||
36 | |||
37 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
38 | { | ||
39 | public class InventoryItem : IInventoryItem | ||
40 | { | ||
41 | TaskInventoryItem m_privateItem; | ||
42 | Scene m_rootScene; | ||
43 | |||
44 | public InventoryItem(Scene rootScene, TaskInventoryItem internalItem) | ||
45 | { | ||
46 | m_rootScene = rootScene; | ||
47 | m_privateItem = internalItem; | ||
48 | } | ||
49 | |||
50 | // Marked internal, to prevent scripts from accessing the internal type | ||
51 | internal TaskInventoryItem ToTaskInventoryItem() | ||
52 | { | ||
53 | return m_privateItem; | ||
54 | } | ||
55 | |||
56 | /// <summary> | ||
57 | /// This will attempt to convert from an IInventoryItem to an InventoryItem object | ||
58 | /// </summary> | ||
59 | /// <description> | ||
60 | /// In order for this to work the object which implements IInventoryItem must inherit from InventoryItem, otherwise | ||
61 | /// an exception is thrown. | ||
62 | /// </description> | ||
63 | /// <param name="i"> | ||
64 | /// The interface to upcast <see cref="IInventoryItem"/> | ||
65 | /// </param> | ||
66 | /// <returns> | ||
67 | /// The object backing the interface implementation <see cref="InventoryItem"/> | ||
68 | /// </returns> | ||
69 | internal static InventoryItem FromInterface(IInventoryItem i) | ||
70 | { | ||
71 | if (typeof(InventoryItem).IsAssignableFrom(i.GetType())) | ||
72 | { | ||
73 | return (InventoryItem)i; | ||
74 | } | ||
75 | else | ||
76 | { | ||
77 | throw new ApplicationException("[MRM] There is no legal conversion from IInventoryItem to InventoryItem"); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | public int Type { get { return m_privateItem.Type; } } | ||
82 | public UUID AssetID { get { return m_privateItem.AssetID; } } | ||
83 | |||
84 | // This method exposes OpenSim/OpenMetaverse internals and needs to be replaced with a IAsset specific to MRM. | ||
85 | public T RetrieveAsset<T>() where T : OpenMetaverse.Assets.Asset, new() | ||
86 | { | ||
87 | AssetBase a = m_rootScene.AssetService.Get(AssetID.ToString()); | ||
88 | T result = new T(); | ||
89 | |||
90 | if ((sbyte)result.AssetType != a.Type) | ||
91 | throw new ApplicationException("[MRM] The supplied asset class does not match the found asset"); | ||
92 | |||
93 | result.AssetData = a.Data; | ||
94 | result.Decode(); | ||
95 | return result; | ||
96 | } | ||
97 | } | ||
98 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/LOParcel.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/LOParcel.cs new file mode 100644 index 0000000..c898da6 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/LOParcel.cs | |||
@@ -0,0 +1,73 @@ | |||
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 OpenSim.Framework; | ||
29 | using OpenSim.Region.Framework.Interfaces; | ||
30 | using OpenSim.Region.Framework.Scenes; | ||
31 | |||
32 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
33 | { | ||
34 | class LOParcel : System.MarshalByRefObject, IParcel | ||
35 | { | ||
36 | private readonly Scene m_scene; | ||
37 | private readonly int m_parcelID; | ||
38 | |||
39 | public LOParcel(Scene m_scene, int m_parcelID) | ||
40 | { | ||
41 | this.m_scene = m_scene; | ||
42 | this.m_parcelID = m_parcelID; | ||
43 | } | ||
44 | |||
45 | private ILandObject GetLO() | ||
46 | { | ||
47 | return m_scene.LandChannel.GetLandObject(m_parcelID); | ||
48 | } | ||
49 | |||
50 | public string Name | ||
51 | { | ||
52 | get { return GetLO().LandData.Name; } | ||
53 | set { GetLO().LandData.Name = value; } | ||
54 | } | ||
55 | |||
56 | public string Description | ||
57 | { | ||
58 | get { return GetLO().LandData.Description; } | ||
59 | set { GetLO().LandData.Description = value; } | ||
60 | } | ||
61 | |||
62 | public ISocialEntity Owner | ||
63 | { | ||
64 | get { throw new System.NotImplementedException(); } | ||
65 | set { throw new System.NotImplementedException(); } | ||
66 | } | ||
67 | |||
68 | public bool[,] Bitmap | ||
69 | { | ||
70 | get { return GetLO().LandBitmap; } | ||
71 | } | ||
72 | } | ||
73 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMBase.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMBase.cs new file mode 100644 index 0000000..6a23f5d --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMBase.cs | |||
@@ -0,0 +1,63 @@ | |||
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 OpenMetaverse; | ||
29 | |||
30 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
31 | { | ||
32 | public abstract class MRMBase : System.MarshalByRefObject | ||
33 | { | ||
34 | private IWorld m_world; | ||
35 | private IHost m_host; | ||
36 | private UUID m_id; | ||
37 | |||
38 | public void InitMiniModule(IWorld world, IHost host, UUID uniqueID) | ||
39 | { | ||
40 | m_world = world; | ||
41 | m_host = host; | ||
42 | m_id = uniqueID; | ||
43 | } | ||
44 | |||
45 | protected IWorld World | ||
46 | { | ||
47 | get { return m_world; } | ||
48 | } | ||
49 | |||
50 | protected IHost Host | ||
51 | { | ||
52 | get { return m_host; } | ||
53 | } | ||
54 | |||
55 | public UUID ID | ||
56 | { | ||
57 | get { return m_id; } | ||
58 | } | ||
59 | |||
60 | public abstract void Start(); | ||
61 | public abstract void Stop(); | ||
62 | } | ||
63 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs new file mode 100644 index 0000000..4bafe2f --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs | |||
@@ -0,0 +1,521 @@ | |||
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.CodeDom.Compiler; | ||
30 | using System.Collections; | ||
31 | using System.Collections.Generic; | ||
32 | using System.Diagnostics; | ||
33 | using System.IO; | ||
34 | using System.Reflection; | ||
35 | using System.Security; | ||
36 | using System.Security.Permissions; | ||
37 | using System.Security.Policy; | ||
38 | using System.Text; | ||
39 | using log4net; | ||
40 | using Microsoft.CSharp; | ||
41 | using Nini.Config; | ||
42 | using OpenMetaverse; | ||
43 | using OpenSim.Framework; | ||
44 | using OpenSim.Region.Framework.Interfaces; | ||
45 | using OpenSim.Region.Framework.Scenes; | ||
46 | using Mono.Addins; | ||
47 | |||
48 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
49 | { | ||
50 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MRMModule")] | ||
51 | public class MRMModule : INonSharedRegionModule, IMRMModule | ||
52 | { | ||
53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
54 | private Scene m_scene; | ||
55 | private bool m_Enabled; | ||
56 | private bool m_Hidden; | ||
57 | |||
58 | private readonly Dictionary<UUID,MRMBase> m_scripts = new Dictionary<UUID, MRMBase>(); | ||
59 | |||
60 | private readonly Dictionary<Type,object> m_extensions = new Dictionary<Type, object>(); | ||
61 | |||
62 | private static readonly CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); | ||
63 | |||
64 | private readonly MicroScheduler m_microthreads = new MicroScheduler(); | ||
65 | |||
66 | |||
67 | private IConfig m_config; | ||
68 | |||
69 | public void RegisterExtension<T>(T instance) | ||
70 | { | ||
71 | m_extensions[typeof (T)] = instance; | ||
72 | } | ||
73 | |||
74 | #region INonSharedRegionModule | ||
75 | |||
76 | public void Initialise(IConfigSource source) | ||
77 | { | ||
78 | if (source.Configs["MRM"] != null) | ||
79 | { | ||
80 | m_config = source.Configs["MRM"]; | ||
81 | |||
82 | if (source.Configs["MRM"].GetBoolean("Enabled", false)) | ||
83 | { | ||
84 | m_log.Info("[MRM]: Enabling MRM Module"); | ||
85 | m_Enabled = true; | ||
86 | m_Hidden = source.Configs["MRM"].GetBoolean("Hidden", false); | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | |||
91 | public void AddRegion(Scene scene) | ||
92 | { | ||
93 | if (!m_Enabled) | ||
94 | return; | ||
95 | |||
96 | m_scene = scene; | ||
97 | |||
98 | // when hidden, we don't listen for client initiated script events | ||
99 | // only making the MRM engine available for region modules | ||
100 | if (!m_Hidden) | ||
101 | { | ||
102 | scene.EventManager.OnRezScript += EventManager_OnRezScript; | ||
103 | scene.EventManager.OnStopScript += EventManager_OnStopScript; | ||
104 | } | ||
105 | |||
106 | scene.EventManager.OnFrame += EventManager_OnFrame; | ||
107 | |||
108 | scene.RegisterModuleInterface<IMRMModule>(this); | ||
109 | } | ||
110 | |||
111 | public void RegionLoaded(Scene scene) | ||
112 | { | ||
113 | } | ||
114 | |||
115 | public void RemoveRegion(Scene scene) | ||
116 | { | ||
117 | } | ||
118 | |||
119 | public void Close() | ||
120 | { | ||
121 | foreach (KeyValuePair<UUID, MRMBase> pair in m_scripts) | ||
122 | { | ||
123 | pair.Value.Stop(); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | public string Name | ||
128 | { | ||
129 | get { return "MiniRegionModule"; } | ||
130 | } | ||
131 | |||
132 | public Type ReplaceableInterface | ||
133 | { | ||
134 | get { return null; } | ||
135 | } | ||
136 | |||
137 | #endregion | ||
138 | |||
139 | void EventManager_OnStopScript(uint localID, UUID itemID) | ||
140 | { | ||
141 | if (m_scripts.ContainsKey(itemID)) | ||
142 | { | ||
143 | m_scripts[itemID].Stop(); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | void EventManager_OnFrame() | ||
148 | { | ||
149 | m_microthreads.Tick(1000); | ||
150 | } | ||
151 | |||
152 | static string ConvertMRMKeywords(string script) | ||
153 | { | ||
154 | script = script.Replace("microthreaded void", "IEnumerable"); | ||
155 | script = script.Replace("relax;", "yield return null;"); | ||
156 | |||
157 | return script; | ||
158 | } | ||
159 | |||
160 | /// <summary> | ||
161 | /// Create an AppDomain that contains policy restricting code to execute | ||
162 | /// with only the permissions granted by a named permission set | ||
163 | /// </summary> | ||
164 | /// <param name="permissionSetName">name of the permission set to restrict to</param> | ||
165 | /// <param name="appDomainName">'friendly' name of the appdomain to be created</param> | ||
166 | /// <exception cref="ArgumentNullException"> | ||
167 | /// if <paramref name="permissionSetName"/> is null | ||
168 | /// </exception> | ||
169 | /// <exception cref="ArgumentOutOfRangeException"> | ||
170 | /// if <paramref name="permissionSetName"/> is empty | ||
171 | /// </exception> | ||
172 | /// <returns>AppDomain with a restricted security policy</returns> | ||
173 | /// <remarks>Substantial portions of this function from: http://blogs.msdn.com/shawnfa/archive/2004/10/25/247379.aspx | ||
174 | /// Valid permissionSetName values are: | ||
175 | /// * FullTrust | ||
176 | /// * SkipVerification | ||
177 | /// * Execution | ||
178 | /// * Nothing | ||
179 | /// * LocalIntranet | ||
180 | /// * Internet | ||
181 | /// * Everything | ||
182 | /// </remarks> | ||
183 | #pragma warning disable 0618 | ||
184 | public static AppDomain CreateRestrictedDomain(string permissionSetName, string appDomainName) | ||
185 | { | ||
186 | if (permissionSetName == null) | ||
187 | throw new ArgumentNullException("permissionSetName"); | ||
188 | if (permissionSetName.Length == 0) | ||
189 | throw new ArgumentOutOfRangeException("permissionSetName", permissionSetName, | ||
190 | "Cannot have an empty permission set name"); | ||
191 | |||
192 | // Default to all code getting nothing | ||
193 | PolicyStatement emptyPolicy = new PolicyStatement(new PermissionSet(PermissionState.None)); | ||
194 | UnionCodeGroup policyRoot = new UnionCodeGroup(new AllMembershipCondition(), emptyPolicy); | ||
195 | |||
196 | bool foundName = false; | ||
197 | PermissionSet setIntersection = new PermissionSet(PermissionState.Unrestricted); | ||
198 | |||
199 | // iterate over each policy level | ||
200 | IEnumerator levelEnumerator = SecurityManager.PolicyHierarchy(); | ||
201 | while (levelEnumerator.MoveNext()) | ||
202 | { | ||
203 | PolicyLevel level = levelEnumerator.Current as PolicyLevel; | ||
204 | |||
205 | // if this level has defined a named permission set with the | ||
206 | // given name, then intersect it with what we've retrieved | ||
207 | // from all the previous levels | ||
208 | if (level != null) | ||
209 | { | ||
210 | PermissionSet levelSet = level.GetNamedPermissionSet(permissionSetName); | ||
211 | if (levelSet != null) | ||
212 | { | ||
213 | foundName = true; | ||
214 | if (setIntersection != null) | ||
215 | setIntersection = setIntersection.Intersect(levelSet); | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | |||
220 | // Intersect() can return null for an empty set, so convert that | ||
221 | // to an empty set object. Also return an empty set if we didn't find | ||
222 | // the named permission set we were looking for | ||
223 | if (setIntersection == null || !foundName) | ||
224 | setIntersection = new PermissionSet(PermissionState.None); | ||
225 | else | ||
226 | setIntersection = new NamedPermissionSet(permissionSetName, setIntersection); | ||
227 | |||
228 | // if no named permission sets were found, return an empty set, | ||
229 | // otherwise return the set that was found | ||
230 | PolicyStatement permissions = new PolicyStatement(setIntersection); | ||
231 | policyRoot.AddChild(new UnionCodeGroup(new AllMembershipCondition(), permissions)); | ||
232 | |||
233 | // create an AppDomain policy level for the policy tree | ||
234 | PolicyLevel appDomainLevel = PolicyLevel.CreateAppDomainLevel(); | ||
235 | appDomainLevel.RootCodeGroup = policyRoot; | ||
236 | |||
237 | // create an AppDomain where this policy will be in effect | ||
238 | string domainName = appDomainName; | ||
239 | AppDomain restrictedDomain = AppDomain.CreateDomain(domainName); | ||
240 | restrictedDomain.SetAppDomainPolicy(appDomainLevel); | ||
241 | |||
242 | return restrictedDomain; | ||
243 | } | ||
244 | #pragma warning restore 0618 | ||
245 | |||
246 | |||
247 | void EventManager_OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource) | ||
248 | { | ||
249 | if (script.StartsWith("//MRM:C#")) | ||
250 | { | ||
251 | if (m_config.GetBoolean("OwnerOnly", true)) | ||
252 | if (m_scene.GetSceneObjectPart(localID).OwnerID != m_scene.RegionInfo.EstateSettings.EstateOwner | ||
253 | || m_scene.GetSceneObjectPart(localID).CreatorID != m_scene.RegionInfo.EstateSettings.EstateOwner) | ||
254 | return; | ||
255 | |||
256 | script = ConvertMRMKeywords(script); | ||
257 | |||
258 | try | ||
259 | { | ||
260 | AppDomain target; | ||
261 | if (m_config.GetBoolean("Sandboxed", true)) | ||
262 | { | ||
263 | m_log.Info("[MRM] Found C# MRM - Starting in AppDomain with " + | ||
264 | m_config.GetString("SandboxLevel", "Internet") + "-level security."); | ||
265 | |||
266 | string domainName = UUID.Random().ToString(); | ||
267 | target = CreateRestrictedDomain(m_config.GetString("SandboxLevel", "Internet"), | ||
268 | domainName); | ||
269 | } | ||
270 | else | ||
271 | { | ||
272 | m_log.Info("[MRM] Found C# MRM - Starting in current AppDomain"); | ||
273 | m_log.Warn( | ||
274 | "[MRM] Security Risk: AppDomain is run in current context. Use only in trusted environments."); | ||
275 | target = AppDomain.CurrentDomain; | ||
276 | } | ||
277 | |||
278 | m_log.Info("[MRM] Unwrapping into target AppDomain"); | ||
279 | MRMBase mmb = (MRMBase) target.CreateInstanceFromAndUnwrap( | ||
280 | CompileFromDotNetText(script, itemID.ToString()), | ||
281 | "OpenSim.MiniModule"); | ||
282 | |||
283 | m_log.Info("[MRM] Initialising MRM Globals"); | ||
284 | InitializeMRM(mmb, localID, itemID); | ||
285 | |||
286 | m_scripts[itemID] = mmb; | ||
287 | |||
288 | m_log.Info("[MRM] Starting MRM"); | ||
289 | mmb.Start(); | ||
290 | } | ||
291 | catch (UnauthorizedAccessException e) | ||
292 | { | ||
293 | m_log.Error("[MRM] UAE " + e.Message); | ||
294 | m_log.Error("[MRM] " + e.StackTrace); | ||
295 | |||
296 | if (e.InnerException != null) | ||
297 | m_log.Error("[MRM] " + e.InnerException); | ||
298 | |||
299 | m_scene.ForEachClient(delegate(IClientAPI user) | ||
300 | { | ||
301 | user.SendAlertMessage( | ||
302 | "MRM UnAuthorizedAccess: " + e); | ||
303 | }); | ||
304 | } | ||
305 | catch (Exception e) | ||
306 | { | ||
307 | m_log.Info("[MRM] Error: " + e); | ||
308 | m_scene.ForEachClient(delegate(IClientAPI user) | ||
309 | { | ||
310 | user.SendAlertMessage( | ||
311 | "Compile error while building MRM script, check OpenSim console for more information."); | ||
312 | }); | ||
313 | } | ||
314 | } | ||
315 | } | ||
316 | |||
317 | public void GetGlobalEnvironment(uint localID, out IWorld world, out IHost host) | ||
318 | { | ||
319 | // UUID should be changed to object owner. | ||
320 | UUID owner = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
321 | SEUser securityUser = new SEUser(owner, "Name Unassigned"); | ||
322 | SecurityCredential creds = new SecurityCredential(securityUser, m_scene); | ||
323 | |||
324 | world = new World(m_scene, creds); | ||
325 | host = new Host(new SOPObject(m_scene, localID, creds), m_scene, new ExtensionHandler(m_extensions), | ||
326 | m_microthreads); | ||
327 | } | ||
328 | |||
329 | public void InitializeMRM(MRMBase mmb, uint localID, UUID itemID) | ||
330 | { | ||
331 | m_log.Info("[MRM] Created MRM Instance"); | ||
332 | |||
333 | IWorld world; | ||
334 | IHost host; | ||
335 | |||
336 | GetGlobalEnvironment(localID, out world, out host); | ||
337 | |||
338 | mmb.InitMiniModule(world, host, itemID); | ||
339 | } | ||
340 | |||
341 | /// <summary> | ||
342 | /// Stolen from ScriptEngine Common | ||
343 | /// </summary> | ||
344 | /// <param name="Script"></param> | ||
345 | /// <param name="uuid">Unique ID for this module</param> | ||
346 | /// <returns></returns> | ||
347 | internal string CompileFromDotNetText(string Script, string uuid) | ||
348 | { | ||
349 | m_log.Info("MRM 1"); | ||
350 | const string ext = ".cs"; | ||
351 | const string FilePrefix = "MiniModule"; | ||
352 | |||
353 | // Output assembly name | ||
354 | string OutFile = Path.Combine("MiniModules", Path.Combine( | ||
355 | m_scene.RegionInfo.RegionID.ToString(), | ||
356 | FilePrefix + "_compiled_" + uuid + "_" + | ||
357 | Util.RandomClass.Next(9000) + ".dll")); | ||
358 | |||
359 | // Create Directories for Assemblies | ||
360 | if (!Directory.Exists("MiniModules")) | ||
361 | Directory.CreateDirectory("MiniModules"); | ||
362 | string tmp = Path.Combine("MiniModules", m_scene.RegionInfo.RegionID.ToString()); | ||
363 | if (!Directory.Exists(tmp)) | ||
364 | Directory.CreateDirectory(tmp); | ||
365 | |||
366 | m_log.Info("MRM 2"); | ||
367 | |||
368 | try | ||
369 | { | ||
370 | File.Delete(OutFile); | ||
371 | } | ||
372 | catch (UnauthorizedAccessException e) | ||
373 | { | ||
374 | throw new Exception("Unable to delete old existing " + | ||
375 | "script-file before writing new. Compile aborted: " + | ||
376 | e); | ||
377 | } | ||
378 | catch (IOException e) | ||
379 | { | ||
380 | throw new Exception("Unable to delete old existing " + | ||
381 | "script-file before writing new. Compile aborted: " + | ||
382 | e); | ||
383 | } | ||
384 | |||
385 | m_log.Info("MRM 3"); | ||
386 | |||
387 | // DEBUG - write source to disk | ||
388 | string srcFileName = FilePrefix + "_source_" + | ||
389 | Path.GetFileNameWithoutExtension(OutFile) + ext; | ||
390 | try | ||
391 | { | ||
392 | File.WriteAllText(Path.Combine(Path.Combine( | ||
393 | "MiniModules", | ||
394 | m_scene.RegionInfo.RegionID.ToString()), | ||
395 | srcFileName), Script); | ||
396 | } | ||
397 | catch (Exception ex) //NOTLEGIT - Should be just FileIOException | ||
398 | { | ||
399 | m_log.Error("[Compiler]: Exception while " + | ||
400 | "trying to write script source to file \"" + | ||
401 | srcFileName + "\": " + ex); | ||
402 | } | ||
403 | |||
404 | m_log.Info("MRM 4"); | ||
405 | |||
406 | // Do actual compile | ||
407 | CompilerParameters parameters = new CompilerParameters(); | ||
408 | |||
409 | parameters.IncludeDebugInformation = true; | ||
410 | |||
411 | string rootPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); | ||
412 | |||
413 | List<string> libraries = new List<string>(); | ||
414 | string[] lines = Script.Split(new string[] {"\n"}, StringSplitOptions.RemoveEmptyEntries); | ||
415 | foreach (string s in lines) | ||
416 | { | ||
417 | if (s.StartsWith("//@DEPENDS:")) | ||
418 | { | ||
419 | libraries.Add(s.Replace("//@DEPENDS:", "")); | ||
420 | } | ||
421 | } | ||
422 | |||
423 | libraries.Add("OpenSim.Region.OptionalModules.dll"); | ||
424 | libraries.Add("OpenMetaverseTypes.dll"); | ||
425 | libraries.Add("log4net.dll"); | ||
426 | |||
427 | foreach (string library in libraries) | ||
428 | { | ||
429 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, library)); | ||
430 | } | ||
431 | |||
432 | parameters.GenerateExecutable = false; | ||
433 | parameters.OutputAssembly = OutFile; | ||
434 | parameters.IncludeDebugInformation = true; | ||
435 | parameters.TreatWarningsAsErrors = false; | ||
436 | |||
437 | m_log.Info("MRM 5"); | ||
438 | |||
439 | CompilerResults results = CScodeProvider.CompileAssemblyFromSource( | ||
440 | parameters, Script); | ||
441 | |||
442 | m_log.Info("MRM 6"); | ||
443 | |||
444 | int display = 5; | ||
445 | if (results.Errors.Count > 0) | ||
446 | { | ||
447 | string errtext = String.Empty; | ||
448 | foreach (CompilerError CompErr in results.Errors) | ||
449 | { | ||
450 | // Show 5 errors max | ||
451 | // | ||
452 | if (display <= 0) | ||
453 | break; | ||
454 | display--; | ||
455 | |||
456 | string severity = "Error"; | ||
457 | if (CompErr.IsWarning) | ||
458 | { | ||
459 | severity = "Warning"; | ||
460 | } | ||
461 | |||
462 | string text = CompErr.ErrorText; | ||
463 | |||
464 | // The Second Life viewer's script editor begins | ||
465 | // countingn lines and columns at 0, so we subtract 1. | ||
466 | errtext += String.Format("Line ({0},{1}): {4} {2}: {3}\n", | ||
467 | CompErr.Line - 1, CompErr.Column - 1, | ||
468 | CompErr.ErrorNumber, text, severity); | ||
469 | } | ||
470 | |||
471 | if (!File.Exists(OutFile)) | ||
472 | { | ||
473 | throw new Exception(errtext); | ||
474 | } | ||
475 | } | ||
476 | |||
477 | m_log.Info("MRM 7"); | ||
478 | |||
479 | if (!File.Exists(OutFile)) | ||
480 | { | ||
481 | string errtext = String.Empty; | ||
482 | errtext += "No compile error. But not able to locate compiled file."; | ||
483 | throw new Exception(errtext); | ||
484 | } | ||
485 | |||
486 | FileInfo fi = new FileInfo(OutFile); | ||
487 | |||
488 | Byte[] data = new Byte[fi.Length]; | ||
489 | |||
490 | try | ||
491 | { | ||
492 | FileStream fs = File.Open(OutFile, FileMode.Open, FileAccess.Read); | ||
493 | fs.Read(data, 0, data.Length); | ||
494 | fs.Close(); | ||
495 | } | ||
496 | catch (IOException) | ||
497 | { | ||
498 | string errtext = String.Empty; | ||
499 | errtext += "No compile error. But not able to open file."; | ||
500 | throw new Exception(errtext); | ||
501 | } | ||
502 | |||
503 | m_log.Info("MRM 8"); | ||
504 | |||
505 | // Convert to base64 | ||
506 | // | ||
507 | string filetext = Convert.ToBase64String(data); | ||
508 | Byte[] buf = Encoding.ASCII.GetBytes(filetext); | ||
509 | |||
510 | m_log.Info("MRM 9"); | ||
511 | |||
512 | FileStream sfs = File.Create(OutFile + ".cil.b64"); | ||
513 | sfs.Write(buf, 0, buf.Length); | ||
514 | sfs.Close(); | ||
515 | |||
516 | m_log.Info("MRM 10"); | ||
517 | |||
518 | return OutFile; | ||
519 | } | ||
520 | } | ||
521 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MicroScheduler.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MicroScheduler.cs new file mode 100644 index 0000000..73fe8b8 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MicroScheduler.cs | |||
@@ -0,0 +1,69 @@ | |||
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; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | using System.Text; | ||
33 | using log4net; | ||
34 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.Interfaces; | ||
35 | |||
36 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
37 | { | ||
38 | public class MicroScheduler : System.MarshalByRefObject, IMicrothreader | ||
39 | { | ||
40 | private readonly List<IEnumerator> m_threads = new List<IEnumerator>(); | ||
41 | |||
42 | public void Run(IEnumerable microthread) | ||
43 | { | ||
44 | lock (m_threads) | ||
45 | m_threads.Add(microthread.GetEnumerator()); | ||
46 | } | ||
47 | |||
48 | public void Tick(int count) | ||
49 | { | ||
50 | lock (m_threads) | ||
51 | { | ||
52 | if (m_threads.Count == 0) | ||
53 | return; | ||
54 | |||
55 | int i = 0; | ||
56 | while (m_threads.Count > 0 && i < count) | ||
57 | { | ||
58 | i++; | ||
59 | |||
60 | bool running = m_threads[i%m_threads.Count].MoveNext(); | ||
61 | |||
62 | |||
63 | if (!running) | ||
64 | m_threads.Remove(m_threads[i%m_threads.Count]); | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectInventory.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectInventory.cs new file mode 100644 index 0000000..bb85d06 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectInventory.cs | |||
@@ -0,0 +1,42 @@ | |||
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 | |||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.Object | ||
34 | { | ||
35 | /// <summary> | ||
36 | /// This implements the methods neccesary to operate on the inventory of an object | ||
37 | /// </summary> | ||
38 | public interface IObjectInventory : IDictionary<UUID, IInventoryItem> | ||
39 | { | ||
40 | IInventoryItem this[string name] { get; } | ||
41 | } | ||
42 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectPhysics.cs new file mode 100644 index 0000000..45bf25e --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectPhysics.cs | |||
@@ -0,0 +1,66 @@ | |||
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.Text; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.Object | ||
34 | { | ||
35 | /// <summary> | ||
36 | /// This implements an interface similar to that provided by physics engines to OpenSim internally. | ||
37 | /// Eg, PhysicsActor. It is capable of setting and getting properties related to the current | ||
38 | /// physics scene representation of this object. | ||
39 | /// </summary> | ||
40 | public interface IObjectPhysics | ||
41 | { | ||
42 | bool Enabled { get; set; } | ||
43 | |||
44 | bool Phantom { get; set; } | ||
45 | bool PhantomCollisions { get; set; } | ||
46 | |||
47 | double Density { get; set; } | ||
48 | double Mass { get; set; } | ||
49 | double Buoyancy { get; set; } | ||
50 | |||
51 | Vector3 GeometricCenter { get; } | ||
52 | Vector3 CenterOfMass { get; } | ||
53 | |||
54 | Vector3 RotationalVelocity { get; set; } | ||
55 | Vector3 Velocity { get; set; } | ||
56 | Vector3 Torque { get; set; } | ||
57 | Vector3 Acceleration { get; } | ||
58 | Vector3 Force { get; set; } | ||
59 | |||
60 | bool FloatOnWater { set; } | ||
61 | |||
62 | void AddForce(Vector3 force, bool pushforce); | ||
63 | void AddAngularForce(Vector3 force, bool pushforce); | ||
64 | void SetMomentum(Vector3 momentum); | ||
65 | } | ||
66 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectShape.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectShape.cs new file mode 100644 index 0000000..27cf279 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectShape.cs | |||
@@ -0,0 +1,75 @@ | |||
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.Text; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.Object | ||
34 | { | ||
35 | public enum SculptType | ||
36 | { | ||
37 | Default = 1, | ||
38 | Sphere = 1, | ||
39 | Torus = 2, | ||
40 | Plane = 3, | ||
41 | Cylinder = 4 | ||
42 | } | ||
43 | |||
44 | public enum HoleShape | ||
45 | { | ||
46 | Default = 0x00, | ||
47 | Circle = 0x10, | ||
48 | Square = 0x20, | ||
49 | Triangle = 0x30 | ||
50 | } | ||
51 | |||
52 | public enum PrimType | ||
53 | { | ||
54 | NotPrimitive = 255, | ||
55 | Box = 0, | ||
56 | Cylinder = 1, | ||
57 | Prism = 2, | ||
58 | Sphere = 3, | ||
59 | Torus = 4, | ||
60 | Tube = 5, | ||
61 | Ring = 6, | ||
62 | Sculpt = 7 | ||
63 | } | ||
64 | |||
65 | public interface IObjectShape | ||
66 | { | ||
67 | UUID SculptMap { get; set; } | ||
68 | SculptType SculptType { get; set; } | ||
69 | |||
70 | HoleShape HoleType { get; set; } | ||
71 | Double HoleSize { get; set; } | ||
72 | PrimType PrimType { get; set; } | ||
73 | |||
74 | } | ||
75 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectSound.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectSound.cs new file mode 100644 index 0000000..d623c51 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Object/IObjectSound.cs | |||
@@ -0,0 +1,39 @@ | |||
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.Text; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.Object | ||
34 | { | ||
35 | public interface IObjectSound | ||
36 | { | ||
37 | void Play(UUID soundAsset, double volume); | ||
38 | } | ||
39 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/ObjectAccessor.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/ObjectAccessor.cs new file mode 100644 index 0000000..140264b --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/ObjectAccessor.cs | |||
@@ -0,0 +1,185 @@ | |||
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; | ||
30 | using System.Collections.Generic; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Framework.Scenes; | ||
34 | using IEnumerable=System.Collections.IEnumerable; | ||
35 | |||
36 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
37 | { | ||
38 | |||
39 | internal class IObjEnum : System.MarshalByRefObject, IEnumerator<IObject> | ||
40 | { | ||
41 | private readonly Scene m_scene; | ||
42 | private readonly IEnumerator<EntityBase> m_sogEnum; | ||
43 | private readonly ISecurityCredential m_security; | ||
44 | private readonly List<EntityBase> m_entities; | ||
45 | |||
46 | public IObjEnum(Scene scene, ISecurityCredential security) | ||
47 | { | ||
48 | m_scene = scene; | ||
49 | m_security = security; | ||
50 | m_entities = new List<EntityBase>(m_scene.Entities.GetEntities()); | ||
51 | m_sogEnum = m_entities.GetEnumerator(); | ||
52 | } | ||
53 | |||
54 | public void Dispose() | ||
55 | { | ||
56 | m_sogEnum.Dispose(); | ||
57 | } | ||
58 | |||
59 | public bool MoveNext() | ||
60 | { | ||
61 | return m_sogEnum.MoveNext(); | ||
62 | } | ||
63 | |||
64 | public void Reset() | ||
65 | { | ||
66 | m_sogEnum.Reset(); | ||
67 | } | ||
68 | |||
69 | public IObject Current | ||
70 | { | ||
71 | get | ||
72 | { | ||
73 | return new SOPObject(m_scene, m_sogEnum.Current.LocalId, m_security); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | object IEnumerator.Current | ||
78 | { | ||
79 | get { return Current; } | ||
80 | } | ||
81 | } | ||
82 | |||
83 | public class ObjectAccessor : System.MarshalByRefObject, IObjectAccessor | ||
84 | { | ||
85 | private readonly Scene m_scene; | ||
86 | private readonly ISecurityCredential m_security; | ||
87 | |||
88 | public ObjectAccessor(Scene scene, ISecurityCredential security) | ||
89 | { | ||
90 | m_scene = scene; | ||
91 | m_security = security; | ||
92 | } | ||
93 | |||
94 | public IObject this[int index] | ||
95 | { | ||
96 | get | ||
97 | { | ||
98 | return new SOPObject(m_scene, m_scene.Entities[(uint)index].LocalId, m_security); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | public IObject this[uint index] | ||
103 | { | ||
104 | get | ||
105 | { | ||
106 | return new SOPObject(m_scene, m_scene.Entities[index].LocalId, m_security); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | public IObject this[UUID index] | ||
111 | { | ||
112 | get | ||
113 | { | ||
114 | return new SOPObject(m_scene, m_scene.Entities[index].LocalId, m_security); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | public IObject Create(Vector3 position) | ||
119 | { | ||
120 | return Create(position, Quaternion.Identity); | ||
121 | } | ||
122 | |||
123 | public IObject Create(Vector3 position, Quaternion rotation) | ||
124 | { | ||
125 | |||
126 | SceneObjectGroup sog = m_scene.AddNewPrim(m_security.owner.GlobalID, | ||
127 | UUID.Zero, | ||
128 | position, | ||
129 | rotation, | ||
130 | PrimitiveBaseShape.CreateBox()); | ||
131 | |||
132 | IObject ret = new SOPObject(m_scene, sog.LocalId, m_security); | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | public IEnumerator<IObject> GetEnumerator() | ||
138 | { | ||
139 | return new IObjEnum(m_scene, m_security); | ||
140 | } | ||
141 | |||
142 | IEnumerator IEnumerable.GetEnumerator() | ||
143 | { | ||
144 | return GetEnumerator(); | ||
145 | } | ||
146 | |||
147 | public void Add(IObject item) | ||
148 | { | ||
149 | throw new NotSupportedException("Collection is read-only. This is an API TODO FIX, creation of objects is presently impossible."); | ||
150 | } | ||
151 | |||
152 | public void Clear() | ||
153 | { | ||
154 | throw new NotSupportedException("Collection is read-only. TODO FIX."); | ||
155 | } | ||
156 | |||
157 | public bool Contains(IObject item) | ||
158 | { | ||
159 | return m_scene.Entities.ContainsKey(item.LocalID); | ||
160 | } | ||
161 | |||
162 | public void CopyTo(IObject[] array, int arrayIndex) | ||
163 | { | ||
164 | for (int i = arrayIndex; i < Count + arrayIndex; i++) | ||
165 | { | ||
166 | array[i] = this[i - arrayIndex]; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | public bool Remove(IObject item) | ||
171 | { | ||
172 | throw new NotSupportedException("Collection is read-only. TODO FIX."); | ||
173 | } | ||
174 | |||
175 | public int Count | ||
176 | { | ||
177 | get { return m_scene.Entities.Count; } | ||
178 | } | ||
179 | |||
180 | public bool IsReadOnly | ||
181 | { | ||
182 | get { return true; } | ||
183 | } | ||
184 | } | ||
185 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SEUser.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SEUser.cs new file mode 100644 index 0000000..e2bdf5e --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SEUser.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.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
34 | { | ||
35 | class SEUser : System.MarshalByRefObject, ISocialEntity | ||
36 | { | ||
37 | private readonly UUID m_uuid; | ||
38 | private readonly string m_name; | ||
39 | |||
40 | public SEUser(UUID uuid, string name) | ||
41 | { | ||
42 | m_uuid = uuid; | ||
43 | m_name = name; | ||
44 | } | ||
45 | |||
46 | public UUID GlobalID | ||
47 | { | ||
48 | get { return m_uuid; } | ||
49 | } | ||
50 | |||
51 | public string Name | ||
52 | { | ||
53 | get { return m_name; } | ||
54 | } | ||
55 | |||
56 | public bool IsUser | ||
57 | { | ||
58 | get { return true; } | ||
59 | } | ||
60 | } | ||
61 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs new file mode 100644 index 0000000..5ed1514 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs | |||
@@ -0,0 +1,833 @@ | |||
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.Security; | ||
31 | using OpenMetaverse; | ||
32 | using OpenMetaverse.Packets; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Region.Framework.Interfaces; | ||
35 | using OpenSim.Region.Framework.Scenes; | ||
36 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.Object; | ||
37 | using OpenSim.Region.Physics.Manager; | ||
38 | using PrimType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.PrimType; | ||
39 | using SculptType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.SculptType; | ||
40 | |||
41 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
42 | { | ||
43 | class SOPObject : MarshalByRefObject, IObject, IObjectPhysics, IObjectShape, IObjectSound | ||
44 | { | ||
45 | private readonly Scene m_rootScene; | ||
46 | private readonly uint m_localID; | ||
47 | private readonly ISecurityCredential m_security; | ||
48 | |||
49 | [Obsolete("Replace with 'credential' constructor [security]")] | ||
50 | public SOPObject(Scene rootScene, uint localID) | ||
51 | { | ||
52 | m_rootScene = rootScene; | ||
53 | m_localID = localID; | ||
54 | } | ||
55 | |||
56 | public SOPObject(Scene rootScene, uint localID, ISecurityCredential credential) | ||
57 | { | ||
58 | m_rootScene = rootScene; | ||
59 | m_localID = localID; | ||
60 | m_security = credential; | ||
61 | } | ||
62 | |||
63 | /// <summary> | ||
64 | /// This needs to run very, very quickly. | ||
65 | /// It is utilized in nearly every property and method. | ||
66 | /// </summary> | ||
67 | /// <returns></returns> | ||
68 | private SceneObjectPart GetSOP() | ||
69 | { | ||
70 | return m_rootScene.GetSceneObjectPart(m_localID); | ||
71 | } | ||
72 | |||
73 | private bool CanEdit() | ||
74 | { | ||
75 | if (!m_security.CanEditObject(this)) | ||
76 | { | ||
77 | throw new SecurityException("Insufficient Permission to edit object with UUID [" + GetSOP().UUID + "]"); | ||
78 | } | ||
79 | return true; | ||
80 | } | ||
81 | |||
82 | #region OnTouch | ||
83 | |||
84 | private event OnTouchDelegate _OnTouch; | ||
85 | private bool _OnTouchActive = false; | ||
86 | |||
87 | public event OnTouchDelegate OnTouch | ||
88 | { | ||
89 | add | ||
90 | { | ||
91 | if (CanEdit()) | ||
92 | { | ||
93 | if (!_OnTouchActive) | ||
94 | { | ||
95 | GetSOP().Flags |= PrimFlags.Touch; | ||
96 | _OnTouchActive = true; | ||
97 | m_rootScene.EventManager.OnObjectGrab += EventManager_OnObjectGrab; | ||
98 | } | ||
99 | |||
100 | _OnTouch += value; | ||
101 | } | ||
102 | } | ||
103 | remove | ||
104 | { | ||
105 | _OnTouch -= value; | ||
106 | |||
107 | if (_OnTouch == null) | ||
108 | { | ||
109 | GetSOP().Flags &= ~PrimFlags.Touch; | ||
110 | _OnTouchActive = false; | ||
111 | m_rootScene.EventManager.OnObjectGrab -= EventManager_OnObjectGrab; | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | void EventManager_OnObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) | ||
117 | { | ||
118 | if (_OnTouchActive && m_localID == localID) | ||
119 | { | ||
120 | TouchEventArgs e = new TouchEventArgs(); | ||
121 | e.Avatar = new SPAvatar(m_rootScene, remoteClient.AgentId, m_security); | ||
122 | e.TouchBiNormal = surfaceArgs.Binormal; | ||
123 | e.TouchMaterialIndex = surfaceArgs.FaceIndex; | ||
124 | e.TouchNormal = surfaceArgs.Normal; | ||
125 | e.TouchPosition = surfaceArgs.Position; | ||
126 | e.TouchST = new Vector2(surfaceArgs.STCoord.X, surfaceArgs.STCoord.Y); | ||
127 | e.TouchUV = new Vector2(surfaceArgs.UVCoord.X, surfaceArgs.UVCoord.Y); | ||
128 | |||
129 | IObject sender = this; | ||
130 | |||
131 | if (_OnTouch != null) | ||
132 | _OnTouch(sender, e); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | #endregion | ||
137 | |||
138 | public bool Exists | ||
139 | { | ||
140 | get { return GetSOP() != null; } | ||
141 | } | ||
142 | |||
143 | public uint LocalID | ||
144 | { | ||
145 | get { return m_localID; } | ||
146 | } | ||
147 | |||
148 | public UUID GlobalID | ||
149 | { | ||
150 | get { return GetSOP().UUID; } | ||
151 | } | ||
152 | |||
153 | public string Name | ||
154 | { | ||
155 | get { return GetSOP().Name; } | ||
156 | set | ||
157 | { | ||
158 | if (CanEdit()) | ||
159 | GetSOP().Name = value; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | public string Description | ||
164 | { | ||
165 | get { return GetSOP().Description; } | ||
166 | set | ||
167 | { | ||
168 | if (CanEdit()) | ||
169 | GetSOP().Description = value; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | public UUID OwnerId | ||
174 | { | ||
175 | get { return GetSOP().OwnerID;} | ||
176 | } | ||
177 | |||
178 | public UUID CreatorId | ||
179 | { | ||
180 | get { return GetSOP().CreatorID;} | ||
181 | } | ||
182 | |||
183 | public IObject[] Children | ||
184 | { | ||
185 | get | ||
186 | { | ||
187 | SceneObjectPart my = GetSOP(); | ||
188 | IObject[] rets = null; | ||
189 | |||
190 | int total = my.ParentGroup.PrimCount; | ||
191 | |||
192 | rets = new IObject[total]; | ||
193 | |||
194 | int i = 0; | ||
195 | |||
196 | foreach (SceneObjectPart part in my.ParentGroup.Parts) | ||
197 | { | ||
198 | rets[i++] = new SOPObject(m_rootScene, part.LocalId, m_security); | ||
199 | } | ||
200 | |||
201 | return rets; | ||
202 | } | ||
203 | } | ||
204 | |||
205 | public IObject Root | ||
206 | { | ||
207 | get { return new SOPObject(m_rootScene, GetSOP().ParentGroup.RootPart.LocalId, m_security); } | ||
208 | } | ||
209 | |||
210 | public IObjectMaterial[] Materials | ||
211 | { | ||
212 | get | ||
213 | { | ||
214 | SceneObjectPart sop = GetSOP(); | ||
215 | IObjectMaterial[] rets = new IObjectMaterial[getNumberOfSides(sop)]; | ||
216 | |||
217 | for (int i = 0; i < rets.Length; i++) | ||
218 | { | ||
219 | rets[i] = new SOPObjectMaterial(i, sop); | ||
220 | } | ||
221 | |||
222 | return rets; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | public Vector3 Scale | ||
227 | { | ||
228 | get { return GetSOP().Scale; } | ||
229 | set | ||
230 | { | ||
231 | if (CanEdit()) | ||
232 | GetSOP().Scale = value; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | public Quaternion WorldRotation | ||
237 | { | ||
238 | get { throw new System.NotImplementedException(); } | ||
239 | set { throw new System.NotImplementedException(); } | ||
240 | } | ||
241 | |||
242 | public Quaternion OffsetRotation | ||
243 | { | ||
244 | get { throw new System.NotImplementedException(); } | ||
245 | set { throw new System.NotImplementedException(); } | ||
246 | } | ||
247 | |||
248 | public Vector3 WorldPosition | ||
249 | { | ||
250 | get { return GetSOP().AbsolutePosition; } | ||
251 | set | ||
252 | { | ||
253 | if (CanEdit()) | ||
254 | { | ||
255 | SceneObjectPart pos = GetSOP(); | ||
256 | pos.UpdateOffSet(value - pos.AbsolutePosition); | ||
257 | } | ||
258 | } | ||
259 | } | ||
260 | |||
261 | public Vector3 OffsetPosition | ||
262 | { | ||
263 | get { return GetSOP().OffsetPosition; } | ||
264 | set | ||
265 | { | ||
266 | if (CanEdit()) | ||
267 | { | ||
268 | GetSOP().OffsetPosition = value; | ||
269 | } | ||
270 | } | ||
271 | } | ||
272 | |||
273 | public Vector3 SitTarget | ||
274 | { | ||
275 | get { return GetSOP().SitTargetPosition; } | ||
276 | set | ||
277 | { | ||
278 | if (CanEdit()) | ||
279 | { | ||
280 | GetSOP().SitTargetPosition = value; | ||
281 | } | ||
282 | } | ||
283 | } | ||
284 | |||
285 | public string SitTargetText | ||
286 | { | ||
287 | get { return GetSOP().SitName; } | ||
288 | set | ||
289 | { | ||
290 | if (CanEdit()) | ||
291 | { | ||
292 | GetSOP().SitName = value; | ||
293 | } | ||
294 | } | ||
295 | } | ||
296 | |||
297 | public string TouchText | ||
298 | { | ||
299 | get { return GetSOP().TouchName; } | ||
300 | set | ||
301 | { | ||
302 | if (CanEdit()) | ||
303 | { | ||
304 | GetSOP().TouchName = value; | ||
305 | } | ||
306 | } | ||
307 | } | ||
308 | |||
309 | public string Text | ||
310 | { | ||
311 | get { return GetSOP().Text; } | ||
312 | set | ||
313 | { | ||
314 | if (CanEdit()) | ||
315 | { | ||
316 | GetSOP().SetText(value,new Vector3(1.0f,1.0f,1.0f),1.0f); | ||
317 | } | ||
318 | } | ||
319 | } | ||
320 | |||
321 | public bool IsRotationLockedX | ||
322 | { | ||
323 | get { throw new System.NotImplementedException(); } | ||
324 | set { throw new System.NotImplementedException(); } | ||
325 | } | ||
326 | |||
327 | public bool IsRotationLockedY | ||
328 | { | ||
329 | get { throw new System.NotImplementedException(); } | ||
330 | set { throw new System.NotImplementedException(); } | ||
331 | } | ||
332 | |||
333 | public bool IsRotationLockedZ | ||
334 | { | ||
335 | get { throw new System.NotImplementedException(); } | ||
336 | set { throw new System.NotImplementedException(); } | ||
337 | } | ||
338 | |||
339 | public bool IsSandboxed | ||
340 | { | ||
341 | get { throw new System.NotImplementedException(); } | ||
342 | set { throw new System.NotImplementedException(); } | ||
343 | } | ||
344 | |||
345 | public bool IsImmotile | ||
346 | { | ||
347 | get { throw new System.NotImplementedException(); } | ||
348 | set { throw new System.NotImplementedException(); } | ||
349 | } | ||
350 | |||
351 | public bool IsAlwaysReturned | ||
352 | { | ||
353 | get { throw new System.NotImplementedException(); } | ||
354 | set { throw new System.NotImplementedException(); } | ||
355 | } | ||
356 | |||
357 | public bool IsTemporary | ||
358 | { | ||
359 | get { throw new System.NotImplementedException(); } | ||
360 | set { throw new System.NotImplementedException(); } | ||
361 | } | ||
362 | |||
363 | public bool IsFlexible | ||
364 | { | ||
365 | get { throw new System.NotImplementedException(); } | ||
366 | set { throw new System.NotImplementedException(); } | ||
367 | } | ||
368 | |||
369 | public PhysicsMaterial PhysicsMaterial | ||
370 | { | ||
371 | get { throw new System.NotImplementedException(); } | ||
372 | set { throw new System.NotImplementedException(); } | ||
373 | } | ||
374 | |||
375 | public IObjectPhysics Physics | ||
376 | { | ||
377 | get { return this; } | ||
378 | } | ||
379 | |||
380 | public IObjectShape Shape | ||
381 | { | ||
382 | get { return this; } | ||
383 | } | ||
384 | |||
385 | public IObjectInventory Inventory | ||
386 | { | ||
387 | get { return new SOPObjectInventory(m_rootScene, GetSOP().TaskInventory); } | ||
388 | } | ||
389 | |||
390 | #region Public Functions | ||
391 | |||
392 | public void Say(string msg) | ||
393 | { | ||
394 | if (!CanEdit()) | ||
395 | return; | ||
396 | |||
397 | SceneObjectPart sop = GetSOP(); | ||
398 | m_rootScene.SimChat(msg, ChatTypeEnum.Say, sop.AbsolutePosition, sop.Name, sop.UUID, false); | ||
399 | } | ||
400 | |||
401 | public void Say(string msg,int channel) | ||
402 | { | ||
403 | if (!CanEdit()) | ||
404 | return; | ||
405 | |||
406 | SceneObjectPart sop = GetSOP(); | ||
407 | m_rootScene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,channel, sop.AbsolutePosition, sop.Name, sop.UUID, false); | ||
408 | } | ||
409 | |||
410 | public void Dialog(UUID avatar, string message, string[] buttons, int chat_channel) | ||
411 | { | ||
412 | if (!CanEdit()) | ||
413 | return; | ||
414 | |||
415 | IDialogModule dm = m_rootScene.RequestModuleInterface<IDialogModule>(); | ||
416 | |||
417 | if (dm == null) | ||
418 | return; | ||
419 | |||
420 | if (buttons.Length < 1) | ||
421 | { | ||
422 | Say("ERROR: No less than 1 button can be shown",2147483647); | ||
423 | return; | ||
424 | } | ||
425 | if (buttons.Length > 12) | ||
426 | { | ||
427 | Say("ERROR: No more than 12 buttons can be shown",2147483647); | ||
428 | return; | ||
429 | } | ||
430 | |||
431 | foreach (string button in buttons) | ||
432 | { | ||
433 | if (button == String.Empty) | ||
434 | { | ||
435 | Say("ERROR: button label cannot be blank",2147483647); | ||
436 | return; | ||
437 | } | ||
438 | if (button.Length > 24) | ||
439 | { | ||
440 | Say("ERROR: button label cannot be longer than 24 characters",2147483647); | ||
441 | return; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | dm.SendDialogToUser( | ||
446 | avatar, GetSOP().Name, GetSOP().UUID, GetSOP().OwnerID, | ||
447 | message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buttons); | ||
448 | |||
449 | } | ||
450 | |||
451 | #endregion | ||
452 | |||
453 | |||
454 | #region Supporting Functions | ||
455 | |||
456 | // Helper functions to understand if object has cut, hollow, dimple, and other affecting number of faces | ||
457 | private static void hasCutHollowDimpleProfileCut(int primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow, | ||
458 | out bool hasDimple, out bool hasProfileCut) | ||
459 | { | ||
460 | if (primType == (int)PrimType.Box | ||
461 | || | ||
462 | primType == (int)PrimType.Cylinder | ||
463 | || | ||
464 | primType == (int)PrimType.Prism) | ||
465 | |||
466 | hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); | ||
467 | else | ||
468 | hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0); | ||
469 | |||
470 | hasHollow = shape.ProfileHollow > 0; | ||
471 | hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms | ||
472 | hasProfileCut = hasDimple; // is it the same thing? | ||
473 | |||
474 | } | ||
475 | |||
476 | private static int getScriptPrimType(PrimitiveBaseShape primShape) | ||
477 | { | ||
478 | if (primShape.SculptEntry) | ||
479 | return (int) PrimType.Sculpt; | ||
480 | if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Square) | ||
481 | { | ||
482 | if (primShape.PathCurve == (byte) Extrusion.Straight) | ||
483 | return (int) PrimType.Box; | ||
484 | if (primShape.PathCurve == (byte) Extrusion.Curve1) | ||
485 | return (int) PrimType.Tube; | ||
486 | } | ||
487 | else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Circle) | ||
488 | { | ||
489 | if (primShape.PathCurve == (byte) Extrusion.Straight) | ||
490 | return (int) PrimType.Cylinder; | ||
491 | if (primShape.PathCurve == (byte) Extrusion.Curve1) | ||
492 | return (int) PrimType.Torus; | ||
493 | } | ||
494 | else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.HalfCircle) | ||
495 | { | ||
496 | if (primShape.PathCurve == (byte) Extrusion.Curve1 || primShape.PathCurve == (byte) Extrusion.Curve2) | ||
497 | return (int) PrimType.Sphere; | ||
498 | } | ||
499 | else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.EquilateralTriangle) | ||
500 | { | ||
501 | if (primShape.PathCurve == (byte) Extrusion.Straight) | ||
502 | return (int) PrimType.Prism; | ||
503 | if (primShape.PathCurve == (byte) Extrusion.Curve1) | ||
504 | return (int) PrimType.Ring; | ||
505 | } | ||
506 | return (int) PrimType.NotPrimitive; | ||
507 | } | ||
508 | |||
509 | private static int getNumberOfSides(SceneObjectPart part) | ||
510 | { | ||
511 | int ret; | ||
512 | bool hasCut; | ||
513 | bool hasHollow; | ||
514 | bool hasDimple; | ||
515 | bool hasProfileCut; | ||
516 | |||
517 | int primType = getScriptPrimType(part.Shape); | ||
518 | hasCutHollowDimpleProfileCut(primType, part.Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut); | ||
519 | |||
520 | switch (primType) | ||
521 | { | ||
522 | default: | ||
523 | case (int) PrimType.Box: | ||
524 | ret = 6; | ||
525 | if (hasCut) ret += 2; | ||
526 | if (hasHollow) ret += 1; | ||
527 | break; | ||
528 | case (int) PrimType.Cylinder: | ||
529 | ret = 3; | ||
530 | if (hasCut) ret += 2; | ||
531 | if (hasHollow) ret += 1; | ||
532 | break; | ||
533 | case (int) PrimType.Prism: | ||
534 | ret = 5; | ||
535 | if (hasCut) ret += 2; | ||
536 | if (hasHollow) ret += 1; | ||
537 | break; | ||
538 | case (int) PrimType.Sphere: | ||
539 | ret = 1; | ||
540 | if (hasCut) ret += 2; | ||
541 | if (hasDimple) ret += 2; | ||
542 | if (hasHollow) | ||
543 | ret += 1; // GOTCHA: LSL shows 2 additional sides here. | ||
544 | // This has been fixed, but may cause porting issues. | ||
545 | break; | ||
546 | case (int) PrimType.Torus: | ||
547 | ret = 1; | ||
548 | if (hasCut) ret += 2; | ||
549 | if (hasProfileCut) ret += 2; | ||
550 | if (hasHollow) ret += 1; | ||
551 | break; | ||
552 | case (int) PrimType.Tube: | ||
553 | ret = 4; | ||
554 | if (hasCut) ret += 2; | ||
555 | if (hasProfileCut) ret += 2; | ||
556 | if (hasHollow) ret += 1; | ||
557 | break; | ||
558 | case (int) PrimType.Ring: | ||
559 | ret = 3; | ||
560 | if (hasCut) ret += 2; | ||
561 | if (hasProfileCut) ret += 2; | ||
562 | if (hasHollow) ret += 1; | ||
563 | break; | ||
564 | case (int) PrimType.Sculpt: | ||
565 | ret = 1; | ||
566 | break; | ||
567 | } | ||
568 | return ret; | ||
569 | } | ||
570 | |||
571 | |||
572 | #endregion | ||
573 | |||
574 | #region IObjectPhysics | ||
575 | |||
576 | public bool Enabled | ||
577 | { | ||
578 | get { throw new System.NotImplementedException(); } | ||
579 | set { throw new System.NotImplementedException(); } | ||
580 | } | ||
581 | |||
582 | public bool Phantom | ||
583 | { | ||
584 | get { throw new System.NotImplementedException(); } | ||
585 | set { throw new System.NotImplementedException(); } | ||
586 | } | ||
587 | |||
588 | public bool PhantomCollisions | ||
589 | { | ||
590 | get { throw new System.NotImplementedException(); } | ||
591 | set { throw new System.NotImplementedException(); } | ||
592 | } | ||
593 | |||
594 | public double Density | ||
595 | { | ||
596 | get { return (GetSOP().PhysActor.Mass/Scale.X*Scale.Y/Scale.Z); } | ||
597 | set { throw new NotImplementedException(); } | ||
598 | } | ||
599 | |||
600 | public double Mass | ||
601 | { | ||
602 | get { return GetSOP().PhysActor.Mass; } | ||
603 | set { throw new NotImplementedException(); } | ||
604 | } | ||
605 | |||
606 | public double Buoyancy | ||
607 | { | ||
608 | get { return GetSOP().PhysActor.Buoyancy; } | ||
609 | set { GetSOP().PhysActor.Buoyancy = (float)value; } | ||
610 | } | ||
611 | |||
612 | public Vector3 GeometricCenter | ||
613 | { | ||
614 | get | ||
615 | { | ||
616 | Vector3 tmp = GetSOP().PhysActor.GeometricCenter; | ||
617 | return tmp; | ||
618 | } | ||
619 | } | ||
620 | |||
621 | public Vector3 CenterOfMass | ||
622 | { | ||
623 | get | ||
624 | { | ||
625 | Vector3 tmp = GetSOP().PhysActor.CenterOfMass; | ||
626 | return tmp; | ||
627 | } | ||
628 | } | ||
629 | |||
630 | public Vector3 RotationalVelocity | ||
631 | { | ||
632 | get | ||
633 | { | ||
634 | Vector3 tmp = GetSOP().PhysActor.RotationalVelocity; | ||
635 | return tmp; | ||
636 | } | ||
637 | set | ||
638 | { | ||
639 | if (!CanEdit()) | ||
640 | return; | ||
641 | |||
642 | GetSOP().PhysActor.RotationalVelocity = value; | ||
643 | } | ||
644 | } | ||
645 | |||
646 | public Vector3 Velocity | ||
647 | { | ||
648 | get | ||
649 | { | ||
650 | Vector3 tmp = GetSOP().PhysActor.Velocity; | ||
651 | return tmp; | ||
652 | } | ||
653 | set | ||
654 | { | ||
655 | if (!CanEdit()) | ||
656 | return; | ||
657 | |||
658 | GetSOP().PhysActor.Velocity = value; | ||
659 | } | ||
660 | } | ||
661 | |||
662 | public Vector3 Torque | ||
663 | { | ||
664 | get | ||
665 | { | ||
666 | Vector3 tmp = GetSOP().PhysActor.Torque; | ||
667 | return tmp; | ||
668 | } | ||
669 | set | ||
670 | { | ||
671 | if (!CanEdit()) | ||
672 | return; | ||
673 | |||
674 | GetSOP().PhysActor.Torque = value; | ||
675 | } | ||
676 | } | ||
677 | |||
678 | public Vector3 Acceleration | ||
679 | { | ||
680 | get | ||
681 | { | ||
682 | Vector3 tmp = GetSOP().PhysActor.Acceleration; | ||
683 | return tmp; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | public Vector3 Force | ||
688 | { | ||
689 | get | ||
690 | { | ||
691 | Vector3 tmp = GetSOP().PhysActor.Force; | ||
692 | return tmp; | ||
693 | } | ||
694 | set | ||
695 | { | ||
696 | if (!CanEdit()) | ||
697 | return; | ||
698 | |||
699 | GetSOP().PhysActor.Force = value; | ||
700 | } | ||
701 | } | ||
702 | |||
703 | public bool FloatOnWater | ||
704 | { | ||
705 | set | ||
706 | { | ||
707 | if (!CanEdit()) | ||
708 | return; | ||
709 | GetSOP().PhysActor.FloatOnWater = value; | ||
710 | } | ||
711 | } | ||
712 | |||
713 | public void AddForce(Vector3 force, bool pushforce) | ||
714 | { | ||
715 | if (!CanEdit()) | ||
716 | return; | ||
717 | |||
718 | GetSOP().PhysActor.AddForce(force, pushforce); | ||
719 | } | ||
720 | |||
721 | public void AddAngularForce(Vector3 force, bool pushforce) | ||
722 | { | ||
723 | if (!CanEdit()) | ||
724 | return; | ||
725 | |||
726 | GetSOP().PhysActor.AddAngularForce(force, pushforce); | ||
727 | } | ||
728 | |||
729 | public void SetMomentum(Vector3 momentum) | ||
730 | { | ||
731 | if (!CanEdit()) | ||
732 | return; | ||
733 | |||
734 | GetSOP().PhysActor.SetMomentum(momentum); | ||
735 | } | ||
736 | |||
737 | #endregion | ||
738 | |||
739 | #region Implementation of IObjectShape | ||
740 | |||
741 | private UUID m_sculptMap = UUID.Zero; | ||
742 | |||
743 | public UUID SculptMap | ||
744 | { | ||
745 | get { return m_sculptMap; } | ||
746 | set | ||
747 | { | ||
748 | if (!CanEdit()) | ||
749 | return; | ||
750 | |||
751 | m_sculptMap = value; | ||
752 | SetPrimitiveSculpted(SculptMap, (byte) SculptType); | ||
753 | } | ||
754 | } | ||
755 | |||
756 | private SculptType m_sculptType = Object.SculptType.Default; | ||
757 | |||
758 | public SculptType SculptType | ||
759 | { | ||
760 | get { return m_sculptType; } | ||
761 | set | ||
762 | { | ||
763 | if (!CanEdit()) | ||
764 | return; | ||
765 | |||
766 | m_sculptType = value; | ||
767 | SetPrimitiveSculpted(SculptMap, (byte) SculptType); | ||
768 | } | ||
769 | } | ||
770 | |||
771 | public HoleShape HoleType | ||
772 | { | ||
773 | get { throw new System.NotImplementedException(); } | ||
774 | set { throw new System.NotImplementedException(); } | ||
775 | } | ||
776 | |||
777 | public double HoleSize | ||
778 | { | ||
779 | get { throw new System.NotImplementedException(); } | ||
780 | set { throw new System.NotImplementedException(); } | ||
781 | } | ||
782 | |||
783 | public PrimType PrimType | ||
784 | { | ||
785 | get { return (PrimType)getScriptPrimType(GetSOP().Shape); } | ||
786 | set { throw new System.NotImplementedException(); } | ||
787 | } | ||
788 | |||
789 | private void SetPrimitiveSculpted(UUID map, byte type) | ||
790 | { | ||
791 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); | ||
792 | |||
793 | SceneObjectPart part = GetSOP(); | ||
794 | |||
795 | UUID sculptId = map; | ||
796 | |||
797 | shapeBlock.ObjectLocalID = part.LocalId; | ||
798 | shapeBlock.PathScaleX = 100; | ||
799 | shapeBlock.PathScaleY = 150; | ||
800 | |||
801 | // retain pathcurve | ||
802 | shapeBlock.PathCurve = part.Shape.PathCurve; | ||
803 | |||
804 | part.Shape.SetSculptProperties((byte)type, sculptId); | ||
805 | part.Shape.SculptEntry = true; | ||
806 | part.UpdateShape(shapeBlock); | ||
807 | } | ||
808 | |||
809 | |||
810 | #endregion | ||
811 | |||
812 | |||
813 | #region Implementation of IObjectSound | ||
814 | |||
815 | public IObjectSound Sound | ||
816 | { | ||
817 | get { return this; } | ||
818 | } | ||
819 | |||
820 | public void Play(UUID asset, double volume) | ||
821 | { | ||
822 | if (!CanEdit()) | ||
823 | return; | ||
824 | ISoundModule module = m_rootScene.RequestModuleInterface<ISoundModule>(); | ||
825 | if (module != null) | ||
826 | { | ||
827 | module.SendSound(GetSOP().UUID, asset, volume, true, 0, 0, false, false); | ||
828 | } | ||
829 | } | ||
830 | |||
831 | #endregion | ||
832 | } | ||
833 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectInventory.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectInventory.cs new file mode 100644 index 0000000..d20f4a4 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectInventory.cs | |||
@@ -0,0 +1,215 @@ | |||
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; | ||
30 | using System.Collections.Generic; | ||
31 | |||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Framework.Scenes; | ||
34 | using OpenMetaverse; | ||
35 | |||
36 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.Object | ||
37 | { | ||
38 | public class SOPObjectInventory : IObjectInventory | ||
39 | { | ||
40 | TaskInventoryDictionary m_privateInventory; /// OpenSim's task inventory | ||
41 | Dictionary<UUID, IInventoryItem> m_publicInventory; /// MRM's inventory | ||
42 | Scene m_rootScene; | ||
43 | |||
44 | public SOPObjectInventory(Scene rootScene, TaskInventoryDictionary taskInventory) | ||
45 | { | ||
46 | m_rootScene = rootScene; | ||
47 | m_privateInventory = taskInventory; | ||
48 | m_publicInventory = new Dictionary<UUID, IInventoryItem>(); | ||
49 | } | ||
50 | |||
51 | /// <summary> | ||
52 | /// Fully populate the public dictionary with the contents of the private dictionary | ||
53 | /// </summary> | ||
54 | /// <description> | ||
55 | /// This will only convert those items which hasn't already been converted. ensuring that | ||
56 | /// no items are converted twice, and that any references already in use are maintained. | ||
57 | /// </description> | ||
58 | private void SynchronizeDictionaries() | ||
59 | { | ||
60 | foreach (TaskInventoryItem privateItem in m_privateInventory.Values) | ||
61 | if (!m_publicInventory.ContainsKey(privateItem.ItemID)) | ||
62 | m_publicInventory.Add(privateItem.ItemID, new InventoryItem(m_rootScene, privateItem)); | ||
63 | } | ||
64 | |||
65 | #region IDictionary<UUID, IInventoryItem> implementation | ||
66 | public void Add (UUID key, IInventoryItem value) | ||
67 | { | ||
68 | m_publicInventory.Add(key, value); | ||
69 | m_privateInventory.Add(key, InventoryItem.FromInterface(value).ToTaskInventoryItem()); | ||
70 | } | ||
71 | |||
72 | public bool ContainsKey (UUID key) | ||
73 | { | ||
74 | return m_privateInventory.ContainsKey(key); | ||
75 | } | ||
76 | |||
77 | public bool Remove (UUID key) | ||
78 | { | ||
79 | m_publicInventory.Remove(key); | ||
80 | return m_privateInventory.Remove(key); | ||
81 | } | ||
82 | |||
83 | public bool TryGetValue (UUID key, out IInventoryItem value) | ||
84 | { | ||
85 | value = null; | ||
86 | |||
87 | bool result = false; | ||
88 | if (!m_publicInventory.TryGetValue(key, out value)) | ||
89 | { | ||
90 | // wasn't found in the public inventory | ||
91 | TaskInventoryItem privateItem; | ||
92 | |||
93 | result = m_privateInventory.TryGetValue(key, out privateItem); | ||
94 | if (result) | ||
95 | { | ||
96 | value = new InventoryItem(m_rootScene, privateItem); | ||
97 | m_publicInventory.Add(key, value); // add item, so we don't convert again | ||
98 | } | ||
99 | } else | ||
100 | return true; | ||
101 | |||
102 | return result; | ||
103 | } | ||
104 | |||
105 | public ICollection<UUID> Keys { | ||
106 | get { | ||
107 | return m_privateInventory.Keys; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | public ICollection<IInventoryItem> Values { | ||
112 | get { | ||
113 | SynchronizeDictionaries(); | ||
114 | return m_publicInventory.Values; | ||
115 | } | ||
116 | } | ||
117 | #endregion | ||
118 | |||
119 | #region IEnumerable<KeyValuePair<UUID, IInventoryItem>> implementation | ||
120 | public IEnumerator<KeyValuePair<UUID, IInventoryItem>> GetEnumerator () | ||
121 | { | ||
122 | SynchronizeDictionaries(); | ||
123 | return m_publicInventory.GetEnumerator(); | ||
124 | } | ||
125 | |||
126 | #endregion | ||
127 | |||
128 | #region IEnumerable implementation | ||
129 | IEnumerator IEnumerable.GetEnumerator () | ||
130 | { | ||
131 | SynchronizeDictionaries(); | ||
132 | return m_publicInventory.GetEnumerator(); | ||
133 | } | ||
134 | |||
135 | #endregion | ||
136 | |||
137 | #region ICollection<KeyValuePair<UUID, IInventoryItem>> implementation | ||
138 | public void Add (KeyValuePair<UUID, IInventoryItem> item) | ||
139 | { | ||
140 | Add(item.Key, item.Value); | ||
141 | } | ||
142 | |||
143 | public void Clear () | ||
144 | { | ||
145 | m_publicInventory.Clear(); | ||
146 | m_privateInventory.Clear(); | ||
147 | } | ||
148 | |||
149 | public bool Contains (KeyValuePair<UUID, IInventoryItem> item) | ||
150 | { | ||
151 | return m_privateInventory.ContainsKey(item.Key); | ||
152 | } | ||
153 | |||
154 | public void CopyTo (KeyValuePair<UUID, IInventoryItem>[] array, int arrayIndex) | ||
155 | { | ||
156 | throw new NotImplementedException(); | ||
157 | } | ||
158 | |||
159 | public bool Remove (KeyValuePair<UUID, IInventoryItem> item) | ||
160 | { | ||
161 | return Remove(item.Key); | ||
162 | } | ||
163 | |||
164 | public int Count { | ||
165 | get { | ||
166 | return m_privateInventory.Count; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | public bool IsReadOnly { | ||
171 | get { | ||
172 | return false; | ||
173 | } | ||
174 | } | ||
175 | #endregion | ||
176 | |||
177 | #region Explicit implementations | ||
178 | IInventoryItem System.Collections.Generic.IDictionary<UUID, IInventoryItem>.this[UUID key] | ||
179 | { | ||
180 | get { | ||
181 | IInventoryItem result; | ||
182 | if (TryGetValue(key, out result)) | ||
183 | return result; | ||
184 | else | ||
185 | throw new KeyNotFoundException("[MRM] The requrested item ID could not be found"); | ||
186 | } | ||
187 | set { | ||
188 | m_publicInventory[key] = value; | ||
189 | m_privateInventory[key] = InventoryItem.FromInterface(value).ToTaskInventoryItem(); | ||
190 | } | ||
191 | } | ||
192 | |||
193 | void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<UUID, IInventoryItem>>.CopyTo(System.Collections.Generic.KeyValuePair<UUID,IInventoryItem>[] array, int offset) | ||
194 | { | ||
195 | throw new NotImplementedException(); | ||
196 | } | ||
197 | #endregion | ||
198 | |||
199 | public IInventoryItem this[string name] | ||
200 | { | ||
201 | get { | ||
202 | foreach (TaskInventoryItem i in m_privateInventory.Values) | ||
203 | if (i.Name == name) | ||
204 | { | ||
205 | if (!m_publicInventory.ContainsKey(i.ItemID)) | ||
206 | m_publicInventory.Add(i.ItemID, new InventoryItem(m_rootScene, i)); | ||
207 | |||
208 | return m_publicInventory[i.ItemID]; | ||
209 | } | ||
210 | throw new KeyNotFoundException(); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | } | ||
215 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectMaterial.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectMaterial.cs new file mode 100644 index 0000000..cea738c --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectMaterial.cs | |||
@@ -0,0 +1,136 @@ | |||
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.Drawing; | ||
29 | using OpenMetaverse; | ||
30 | using OpenSim.Region.Framework.Scenes; | ||
31 | |||
32 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
33 | { | ||
34 | class SOPObjectMaterial : System.MarshalByRefObject, IObjectMaterial | ||
35 | { | ||
36 | private readonly int m_face; | ||
37 | private readonly SceneObjectPart m_parent; | ||
38 | |||
39 | public SOPObjectMaterial(int m_face, SceneObjectPart m_parent) | ||
40 | { | ||
41 | this.m_face = m_face; | ||
42 | this.m_parent = m_parent; | ||
43 | } | ||
44 | |||
45 | public Color Color | ||
46 | { | ||
47 | get | ||
48 | { | ||
49 | Color4 res = GetTexface().RGBA; | ||
50 | return Color.FromArgb((int) (res.A*255), (int) (res.R*255), (int) (res.G*255), (int) (res.B*255)); | ||
51 | } | ||
52 | set | ||
53 | { | ||
54 | Primitive.TextureEntry tex = m_parent.Shape.Textures; | ||
55 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)m_face); | ||
56 | texface.RGBA = new Color4(value.R,value.G,value.B,value.A); | ||
57 | tex.FaceTextures[m_face] = texface; | ||
58 | m_parent.UpdateTextureEntry(tex.GetBytes()); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | public UUID Texture | ||
63 | { | ||
64 | get | ||
65 | { | ||
66 | Primitive.TextureEntryFace texface = GetTexface(); | ||
67 | return texface.TextureID; | ||
68 | } | ||
69 | set | ||
70 | { | ||
71 | Primitive.TextureEntry tex = m_parent.Shape.Textures; | ||
72 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)m_face); | ||
73 | texface.TextureID = value; | ||
74 | tex.FaceTextures[m_face] = texface; | ||
75 | m_parent.UpdateTextureEntry(tex.GetBytes()); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | private Primitive.TextureEntryFace GetTexface() | ||
80 | { | ||
81 | Primitive.TextureEntry tex = m_parent.Shape.Textures; | ||
82 | return tex.GetFace((uint)m_face); | ||
83 | } | ||
84 | |||
85 | public TextureMapping Mapping | ||
86 | { | ||
87 | get { throw new System.NotImplementedException(); } | ||
88 | set { throw new System.NotImplementedException(); } | ||
89 | } | ||
90 | |||
91 | public bool Bright | ||
92 | { | ||
93 | get { return GetTexface().Fullbright; } | ||
94 | set | ||
95 | { | ||
96 | Primitive.TextureEntry tex = m_parent.Shape.Textures; | ||
97 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)m_face); | ||
98 | texface.Fullbright = value; | ||
99 | tex.FaceTextures[m_face] = texface; | ||
100 | m_parent.UpdateTextureEntry(tex.GetBytes()); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | public double Bloom | ||
105 | { | ||
106 | get { return GetTexface().Glow; } | ||
107 | set | ||
108 | { | ||
109 | Primitive.TextureEntry tex = m_parent.Shape.Textures; | ||
110 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)m_face); | ||
111 | texface.Glow = (float) value; | ||
112 | tex.FaceTextures[m_face] = texface; | ||
113 | m_parent.UpdateTextureEntry(tex.GetBytes()); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | public bool Shiny | ||
118 | { | ||
119 | get { return GetTexface().Shiny != Shininess.None; } | ||
120 | set | ||
121 | { | ||
122 | Primitive.TextureEntry tex = m_parent.Shape.Textures; | ||
123 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)m_face); | ||
124 | texface.Shiny = value ? Shininess.High : Shininess.None; | ||
125 | tex.FaceTextures[m_face] = texface; | ||
126 | m_parent.UpdateTextureEntry(tex.GetBytes()); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | public bool BumpMap | ||
131 | { | ||
132 | get { return GetTexface().Bump == Bumpiness.None; } | ||
133 | set { throw new System.NotImplementedException(); } | ||
134 | } | ||
135 | } | ||
136 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs new file mode 100644 index 0000000..d192309 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs | |||
@@ -0,0 +1,105 @@ | |||
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.Collections; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Security; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Framework.Scenes; | ||
34 | using OpenSim.Region.Framework.Interfaces; | ||
35 | |||
36 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
37 | { | ||
38 | class SPAvatar : System.MarshalByRefObject, IAvatar | ||
39 | { | ||
40 | private readonly Scene m_rootScene; | ||
41 | private readonly UUID m_ID; | ||
42 | private readonly ISecurityCredential m_security; | ||
43 | //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
44 | |||
45 | public SPAvatar(Scene scene, UUID ID, ISecurityCredential security) | ||
46 | { | ||
47 | m_rootScene = scene; | ||
48 | m_security = security; | ||
49 | m_ID = ID; | ||
50 | } | ||
51 | |||
52 | private ScenePresence GetSP() | ||
53 | { | ||
54 | return m_rootScene.GetScenePresence(m_ID); | ||
55 | } | ||
56 | |||
57 | public string Name | ||
58 | { | ||
59 | get { return GetSP().Name; } | ||
60 | set { throw new SecurityException("Avatar Names are a read-only property."); } | ||
61 | } | ||
62 | |||
63 | public UUID GlobalID | ||
64 | { | ||
65 | get { return m_ID; } | ||
66 | } | ||
67 | |||
68 | public Vector3 WorldPosition | ||
69 | { | ||
70 | get { return GetSP().AbsolutePosition; } | ||
71 | set { GetSP().Teleport(value); } | ||
72 | } | ||
73 | |||
74 | public bool IsChildAgent | ||
75 | { | ||
76 | get { return GetSP().IsChildAgent; } | ||
77 | } | ||
78 | |||
79 | #region IAvatar implementation | ||
80 | public IAvatarAttachment[] Attachments | ||
81 | { | ||
82 | get { | ||
83 | List<IAvatarAttachment> attachments = new List<IAvatarAttachment>(); | ||
84 | |||
85 | List<AvatarAttachment> internalAttachments = GetSP().Appearance.GetAttachments(); | ||
86 | foreach (AvatarAttachment attach in internalAttachments) | ||
87 | { | ||
88 | attachments.Add(new SPAvatarAttachment(m_rootScene, this, attach.AttachPoint, | ||
89 | new UUID(attach.ItemID), | ||
90 | new UUID(attach.AssetID), m_security)); | ||
91 | } | ||
92 | |||
93 | return attachments.ToArray(); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | public void LoadUrl(IObject sender, string message, string url) | ||
98 | { | ||
99 | IDialogModule dm = m_rootScene.RequestModuleInterface<IDialogModule>(); | ||
100 | if (dm != null) | ||
101 | dm.SendUrlToUser(GetSP().UUID, sender.Name, sender.GlobalID, GetSP().UUID, false, message, url); | ||
102 | } | ||
103 | #endregion | ||
104 | } | ||
105 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatarAttachment.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatarAttachment.cs new file mode 100644 index 0000000..570459a --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatarAttachment.cs | |||
@@ -0,0 +1,65 @@ | |||
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 | |||
30 | using OpenMetaverse; | ||
31 | using OpenSim.Region.Framework.Scenes; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
34 | { | ||
35 | public class SPAvatarAttachment : IAvatarAttachment | ||
36 | { | ||
37 | private readonly Scene m_rootScene; | ||
38 | //private readonly IAvatar m_parent; | ||
39 | private readonly int m_location; | ||
40 | //private readonly UUID m_itemId; | ||
41 | private readonly UUID m_assetId; | ||
42 | |||
43 | private readonly ISecurityCredential m_security; | ||
44 | |||
45 | public SPAvatarAttachment(Scene rootScene, IAvatar self, int location, UUID itemId, UUID assetId, ISecurityCredential security) | ||
46 | { | ||
47 | m_rootScene = rootScene; | ||
48 | m_security = security; | ||
49 | //m_parent = self; | ||
50 | m_location = location; | ||
51 | //m_itemId = itemId; | ||
52 | m_assetId = assetId; | ||
53 | } | ||
54 | |||
55 | public int Location { get { return m_location; } } | ||
56 | |||
57 | public IObject Asset | ||
58 | { | ||
59 | get | ||
60 | { | ||
61 | return new SOPObject(m_rootScene, m_rootScene.GetSceneObjectPart(m_assetId).LocalId, m_security); | ||
62 | } | ||
63 | } | ||
64 | } | ||
65 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SecurityCredential.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SecurityCredential.cs new file mode 100644 index 0000000..bc7f6cb --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SecurityCredential.cs | |||
@@ -0,0 +1,62 @@ | |||
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.Text; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | |||
34 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
35 | { | ||
36 | class SecurityCredential : ISecurityCredential | ||
37 | { | ||
38 | private readonly ISocialEntity m_owner; | ||
39 | private readonly Scene m_scene; | ||
40 | |||
41 | public SecurityCredential(ISocialEntity m_owner, Scene m_scene) | ||
42 | { | ||
43 | this.m_owner = m_owner; | ||
44 | this.m_scene = m_scene; | ||
45 | } | ||
46 | |||
47 | public ISocialEntity owner | ||
48 | { | ||
49 | get { return m_owner; } | ||
50 | } | ||
51 | |||
52 | public bool CanEditObject(IObject target) | ||
53 | { | ||
54 | return m_scene.Permissions.CanEditObject(target.GlobalID, m_owner.GlobalID); | ||
55 | } | ||
56 | |||
57 | public bool CanEditTerrain(int x, int y) | ||
58 | { | ||
59 | return m_scene.Permissions.CanTerraformLand(m_owner.GlobalID, new Vector3(x, y, 0)); | ||
60 | } | ||
61 | } | ||
62 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/DrunkenTextAppreciationModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/DrunkenTextAppreciationModule.cs new file mode 100644 index 0000000..778bf7d --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/DrunkenTextAppreciationModule.cs | |||
@@ -0,0 +1,64 @@ | |||
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 OpenSim.Region.OptionalModules.Scripting.Minimodule; | ||
29 | |||
30 | namespace OpenSim | ||
31 | { | ||
32 | class DrunkenTextAppreciationModule : MRMBase | ||
33 | { | ||
34 | public override void Start() | ||
35 | { | ||
36 | World.OnChat += World_OnChat; | ||
37 | } | ||
38 | |||
39 | void World_OnChat(IWorld sender, ChatEventArgs e) | ||
40 | { | ||
41 | if (e.Sender is IAvatar) | ||
42 | { | ||
43 | if (!e.Text.Contains("hic!")) | ||
44 | { | ||
45 | e.Text = e.Text.Replace("s", "sh"); | ||
46 | e.Text = e.Text.Replace("S", "Sh"); | ||
47 | e.Text += " ...hic!"; | ||
48 | |||
49 | Host.Object.Say(e.Text); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | if (e.Sender is IObject) | ||
54 | { | ||
55 | // Ignore | ||
56 | } | ||
57 | } | ||
58 | |||
59 | public override void Stop() | ||
60 | { | ||
61 | |||
62 | } | ||
63 | } | ||
64 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/Microthreads/MicrothreadSample.txt b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/Microthreads/MicrothreadSample.txt new file mode 100644 index 0000000..d2c204a --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/Microthreads/MicrothreadSample.txt | |||
@@ -0,0 +1,40 @@ | |||
1 | //MRM:C# | ||
2 | using System.Collections; | ||
3 | using System.Collections.Generic; | ||
4 | using OpenSim.Region.OptionalModules.Scripting.Minimodule; | ||
5 | |||
6 | namespace OpenSim | ||
7 | { | ||
8 | class MiniModule : MRMBase | ||
9 | { | ||
10 | public microthreaded void MicroThreadFunction(string testparam) | ||
11 | { | ||
12 | Host.Object.Say("Hello " + testparam); | ||
13 | |||
14 | relax; // the 'relax' keyword gives up processing time. | ||
15 | // and should be inserted before, after or in | ||
16 | // any computationally "heavy" zones. | ||
17 | |||
18 | int c = 500; | ||
19 | while(c-- < 0) { | ||
20 | Host.Object.Say("C=" + c); | ||
21 | relax; // Putting 'relax' in microthreaded loops | ||
22 | // is an easy way to lower the CPU tax | ||
23 | // on your script. | ||
24 | } | ||
25 | |||
26 | } | ||
27 | |||
28 | public override void Start() | ||
29 | { | ||
30 | Host.Microthreads.Run( | ||
31 | MicroThreadFunction("World!") | ||
32 | ); | ||
33 | } | ||
34 | |||
35 | public override void Stop() | ||
36 | { | ||
37 | |||
38 | } | ||
39 | } | ||
40 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/TestModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/TestModule.cs new file mode 100644 index 0000000..13d0140 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Test/TestModule.cs | |||
@@ -0,0 +1,98 @@ | |||
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.Collections; | ||
29 | using System.Collections.Generic; | ||
30 | using OpenSim.Region.OptionalModules.Scripting.Minimodule; | ||
31 | |||
32 | namespace OpenSim | ||
33 | { | ||
34 | class MiniModule : MRMBase | ||
35 | { | ||
36 | // private microthreaded Function(params...) | ||
37 | private IEnumerable TestMicrothread(string param) | ||
38 | { | ||
39 | Host.Console.Info("Microthreaded " + param); | ||
40 | // relax; | ||
41 | yield return null; | ||
42 | Host.Console.Info("Microthreaded 2" + param); | ||
43 | yield return null; | ||
44 | int c = 100; | ||
45 | while (c-- < 0) | ||
46 | { | ||
47 | Host.Console.Info("Microthreaded Looped " + c + " " + param); | ||
48 | yield return null; | ||
49 | } | ||
50 | } | ||
51 | |||
52 | public void Microthread(IEnumerable thread) | ||
53 | { | ||
54 | |||
55 | } | ||
56 | |||
57 | public void RunMicrothread() | ||
58 | { | ||
59 | List<IEnumerator> threads = new List<IEnumerator>(); | ||
60 | threads.Add(TestMicrothread("A").GetEnumerator()); | ||
61 | threads.Add(TestMicrothread("B").GetEnumerator()); | ||
62 | threads.Add(TestMicrothread("C").GetEnumerator()); | ||
63 | |||
64 | Microthread(TestMicrothread("Ohai")); | ||
65 | |||
66 | int i = 0; | ||
67 | while (threads.Count > 0) | ||
68 | { | ||
69 | i++; | ||
70 | bool running = threads[i%threads.Count].MoveNext(); | ||
71 | |||
72 | if (!running) | ||
73 | threads.Remove(threads[i%threads.Count]); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | public override void Start() | ||
78 | { | ||
79 | // Say Hello | ||
80 | Host.Object.Say("Hello, Avatar!"); | ||
81 | |||
82 | // Register ourselves to listen | ||
83 | // for touch events. | ||
84 | Host.Object.OnTouch += OnTouched; | ||
85 | } | ||
86 | |||
87 | // This is our touch event handler | ||
88 | void OnTouched(IObject sender, TouchEventArgs e) | ||
89 | { | ||
90 | Host.Object.Say("Touched."); | ||
91 | } | ||
92 | |||
93 | public override void Stop() | ||
94 | { | ||
95 | |||
96 | } | ||
97 | } | ||
98 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/World.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/World.cs new file mode 100644 index 0000000..f2324d2 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/World.cs | |||
@@ -0,0 +1,250 @@ | |||
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.Collections.Generic; | ||
29 | using OpenMetaverse; | ||
30 | using OpenSim.Framework; | ||
31 | using OpenSim.Region.Framework.Interfaces; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | using OpenSim.Region.OptionalModules.Scripting.Minimodule.WorldX; | ||
34 | |||
35 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | ||
36 | { | ||
37 | public class World : System.MarshalByRefObject, IWorld, IWorldAudio | ||
38 | { | ||
39 | private readonly Scene m_internalScene; | ||
40 | private readonly ISecurityCredential m_security; | ||
41 | private readonly Heightmap m_heights; | ||
42 | |||
43 | private readonly ObjectAccessor m_objs; | ||
44 | |||
45 | public World(Scene internalScene, ISecurityCredential securityCredential) | ||
46 | { | ||
47 | m_security = securityCredential; | ||
48 | m_internalScene = internalScene; | ||
49 | m_heights = new Heightmap(m_internalScene); | ||
50 | m_objs = new ObjectAccessor(m_internalScene, securityCredential); | ||
51 | } | ||
52 | |||
53 | #region Events | ||
54 | |||
55 | #region OnNewUser | ||
56 | |||
57 | private event OnNewUserDelegate _OnNewUser; | ||
58 | private bool _OnNewUserActive; | ||
59 | |||
60 | public event OnNewUserDelegate OnNewUser | ||
61 | { | ||
62 | add | ||
63 | { | ||
64 | if (!_OnNewUserActive) | ||
65 | { | ||
66 | _OnNewUserActive = true; | ||
67 | m_internalScene.EventManager.OnNewPresence += EventManager_OnNewPresence; | ||
68 | } | ||
69 | |||
70 | _OnNewUser += value; | ||
71 | } | ||
72 | remove | ||
73 | { | ||
74 | _OnNewUser -= value; | ||
75 | |||
76 | if (_OnNewUser == null) | ||
77 | { | ||
78 | _OnNewUserActive = false; | ||
79 | m_internalScene.EventManager.OnNewPresence -= EventManager_OnNewPresence; | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | |||
84 | void EventManager_OnNewPresence(ScenePresence presence) | ||
85 | { | ||
86 | if (_OnNewUser != null) | ||
87 | { | ||
88 | NewUserEventArgs e = new NewUserEventArgs(); | ||
89 | e.Avatar = new SPAvatar(m_internalScene, presence.UUID, m_security); | ||
90 | _OnNewUser(this, e); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | #endregion | ||
95 | |||
96 | #region OnChat | ||
97 | private event OnChatDelegate _OnChat; | ||
98 | private bool _OnChatActive; | ||
99 | |||
100 | public IWorldAudio Audio | ||
101 | { | ||
102 | get { return this; } | ||
103 | } | ||
104 | |||
105 | public event OnChatDelegate OnChat | ||
106 | { | ||
107 | add | ||
108 | { | ||
109 | if (!_OnChatActive) | ||
110 | { | ||
111 | _OnChatActive = true; | ||
112 | m_internalScene.EventManager.OnChatFromClient += EventManager_OnChatFromClient; | ||
113 | m_internalScene.EventManager.OnChatFromWorld += EventManager_OnChatFromWorld; | ||
114 | } | ||
115 | |||
116 | _OnChat += value; | ||
117 | } | ||
118 | remove | ||
119 | { | ||
120 | _OnChat -= value; | ||
121 | |||
122 | if (_OnChat == null) | ||
123 | { | ||
124 | _OnChatActive = false; | ||
125 | m_internalScene.EventManager.OnChatFromClient -= EventManager_OnChatFromClient; | ||
126 | m_internalScene.EventManager.OnChatFromWorld -= EventManager_OnChatFromWorld; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | void EventManager_OnChatFromWorld(object sender, OSChatMessage chat) | ||
132 | { | ||
133 | if (_OnChat != null) | ||
134 | { | ||
135 | HandleChatPacket(chat); | ||
136 | return; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | private void HandleChatPacket(OSChatMessage chat) | ||
141 | { | ||
142 | if (string.IsNullOrEmpty(chat.Message)) | ||
143 | return; | ||
144 | |||
145 | // Object? | ||
146 | if (chat.Sender == null && chat.SenderObject != null) | ||
147 | { | ||
148 | ChatEventArgs e = new ChatEventArgs(); | ||
149 | e.Sender = new SOPObject(m_internalScene, ((SceneObjectPart) chat.SenderObject).LocalId, m_security); | ||
150 | e.Text = chat.Message; | ||
151 | e.Channel = chat.Channel; | ||
152 | |||
153 | _OnChat(this, e); | ||
154 | return; | ||
155 | } | ||
156 | // Avatar? | ||
157 | if (chat.Sender != null && chat.SenderObject == null) | ||
158 | { | ||
159 | ChatEventArgs e = new ChatEventArgs(); | ||
160 | e.Sender = new SPAvatar(m_internalScene, chat.SenderUUID, m_security); | ||
161 | e.Text = chat.Message; | ||
162 | e.Channel = chat.Channel; | ||
163 | |||
164 | _OnChat(this, e); | ||
165 | return; | ||
166 | } | ||
167 | // Skip if other | ||
168 | } | ||
169 | |||
170 | void EventManager_OnChatFromClient(object sender, OSChatMessage chat) | ||
171 | { | ||
172 | if (_OnChat != null) | ||
173 | { | ||
174 | HandleChatPacket(chat); | ||
175 | return; | ||
176 | } | ||
177 | } | ||
178 | #endregion | ||
179 | |||
180 | #endregion | ||
181 | |||
182 | public IObjectAccessor Objects | ||
183 | { | ||
184 | get { return m_objs; } | ||
185 | } | ||
186 | |||
187 | public IParcel[] Parcels | ||
188 | { | ||
189 | get | ||
190 | { | ||
191 | List<ILandObject> m_los = m_internalScene.LandChannel.AllParcels(); | ||
192 | List<IParcel> m_parcels = new List<IParcel>(m_los.Count); | ||
193 | |||
194 | foreach (ILandObject landObject in m_los) | ||
195 | { | ||
196 | m_parcels.Add(new LOParcel(m_internalScene, landObject.LandData.LocalID)); | ||
197 | } | ||
198 | |||
199 | return m_parcels.ToArray(); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | |||
204 | public IAvatar[] Avatars | ||
205 | { | ||
206 | get | ||
207 | { | ||
208 | EntityBase[] ents = m_internalScene.Entities.GetAllByType<ScenePresence>(); | ||
209 | IAvatar[] rets = new IAvatar[ents.Length]; | ||
210 | |||
211 | for (int i = 0; i < ents.Length; i++) | ||
212 | { | ||
213 | EntityBase ent = ents[i]; | ||
214 | rets[i] = new SPAvatar(m_internalScene, ent.UUID, m_security); | ||
215 | } | ||
216 | |||
217 | return rets; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | public IHeightmap Terrain | ||
222 | { | ||
223 | get { return m_heights; } | ||
224 | } | ||
225 | |||
226 | #region Implementation of IWorldAudio | ||
227 | |||
228 | public void PlaySound(UUID audio, Vector3 position, double volume) | ||
229 | { | ||
230 | ISoundModule soundModule = m_internalScene.RequestModuleInterface<ISoundModule>(); | ||
231 | if (soundModule != null) | ||
232 | { | ||
233 | soundModule.TriggerSound(audio, UUID.Zero, UUID.Zero, UUID.Zero, volume, position, | ||
234 | m_internalScene.RegionInfo.RegionHandle, 0); | ||
235 | } | ||
236 | } | ||
237 | |||
238 | public void PlaySound(UUID audio, Vector3 position) | ||
239 | { | ||
240 | ISoundModule soundModule = m_internalScene.RequestModuleInterface<ISoundModule>(); | ||
241 | if (soundModule != null) | ||
242 | { | ||
243 | soundModule.TriggerSound(audio, UUID.Zero, UUID.Zero, UUID.Zero, 1.0, position, | ||
244 | m_internalScene.RegionInfo.RegionHandle, 0); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | #endregion | ||
249 | } | ||
250 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/WorldX/IWorldAudio.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/WorldX/IWorldAudio.cs new file mode 100644 index 0000000..712a676 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/WorldX/IWorldAudio.cs | |||
@@ -0,0 +1,40 @@ | |||
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.Text; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.OptionalModules.Scripting.Minimodule.WorldX | ||
34 | { | ||
35 | public interface IWorldAudio | ||
36 | { | ||
37 | void PlaySound(UUID audio, Vector3 position, double volume); | ||
38 | void PlaySound(UUID audio, Vector3 position); | ||
39 | } | ||
40 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/ObjectModules/IObjectModule.cs b/OpenSim/Region/OptionalModules/Scripting/ObjectModules/IObjectModule.cs new file mode 100644 index 0000000..9d554ac --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/ObjectModules/IObjectModule.cs | |||
@@ -0,0 +1,42 @@ | |||
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 OpenSim.Region.Framework.Scenes; | ||
29 | |||
30 | namespace OpenSim.Region.OptionalModules.Scripting.ObjectModules | ||
31 | { | ||
32 | interface IObjectModule | ||
33 | { | ||
34 | void Add(EntityBase entity, Scene scene); | ||
35 | void Start(); | ||
36 | void Stop(); | ||
37 | void Tick(); | ||
38 | |||
39 | string ClassName { get; } | ||
40 | bool IsShared { get; } | ||
41 | } | ||
42 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs new file mode 100644 index 0000000..870c0bb --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs | |||
@@ -0,0 +1,313 @@ | |||
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.Reflection; | ||
31 | using System.Net; | ||
32 | using System.IO; | ||
33 | using System.Text; | ||
34 | using log4net; | ||
35 | using Mono.Addins; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenMetaverse.StructuredData; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Region.Framework.Interfaces; | ||
41 | using OpenSim.Region.Framework.Scenes; | ||
42 | using OpenSim.Services.Interfaces; | ||
43 | |||
44 | namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | ||
45 | { | ||
46 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionReadyModule")] | ||
47 | public class RegionReadyModule : IRegionReadyModule, INonSharedRegionModule | ||
48 | { | ||
49 | private static readonly ILog m_log = | ||
50 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
51 | |||
52 | private IConfig m_config = null; | ||
53 | private bool m_firstEmptyCompileQueue; | ||
54 | private bool m_oarFileLoading; | ||
55 | private bool m_lastOarLoadedOk; | ||
56 | private int m_channelNotify = -1000; | ||
57 | private bool m_enabled = false; | ||
58 | private bool m_disable_logins; | ||
59 | private string m_uri = string.Empty; | ||
60 | |||
61 | Scene m_scene; | ||
62 | |||
63 | #region INonSharedRegionModule interface | ||
64 | |||
65 | public Type ReplaceableInterface | ||
66 | { | ||
67 | get { return null; } | ||
68 | } | ||
69 | |||
70 | public void Initialise(IConfigSource config) | ||
71 | { | ||
72 | m_config = config.Configs["RegionReady"]; | ||
73 | if (m_config != null) | ||
74 | { | ||
75 | m_enabled = m_config.GetBoolean("enabled", false); | ||
76 | |||
77 | if (m_enabled) | ||
78 | { | ||
79 | m_channelNotify = m_config.GetInt("channel_notify", m_channelNotify); | ||
80 | m_disable_logins = m_config.GetBoolean("login_disable", false); | ||
81 | m_uri = m_config.GetString("alert_uri",string.Empty); | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | public void AddRegion(Scene scene) | ||
87 | { | ||
88 | if (!m_enabled) | ||
89 | return; | ||
90 | |||
91 | m_scene = scene; | ||
92 | |||
93 | m_scene.RegisterModuleInterface<IRegionReadyModule>(this); | ||
94 | |||
95 | m_firstEmptyCompileQueue = true; | ||
96 | m_oarFileLoading = false; | ||
97 | m_lastOarLoadedOk = true; | ||
98 | |||
99 | m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded; | ||
100 | |||
101 | m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName); | ||
102 | |||
103 | if (m_disable_logins) | ||
104 | { | ||
105 | m_scene.LoginLock = true; | ||
106 | m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue; | ||
107 | |||
108 | // This should always show up to the user but should not trigger warn/errors as these messages are | ||
109 | // expected and are not simulator problems. Ideally, there would be a status level in log4net but | ||
110 | // failing that, we will print out to console instead. | ||
111 | MainConsole.Instance.OutputFormat("Region {0} - LOGINS DISABLED DURING INITIALIZATION.", m_scene.Name); | ||
112 | |||
113 | if (m_uri != string.Empty) | ||
114 | { | ||
115 | RRAlert("disabled"); | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | |||
120 | public void RemoveRegion(Scene scene) | ||
121 | { | ||
122 | if (!m_enabled) | ||
123 | return; | ||
124 | |||
125 | m_scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded; | ||
126 | |||
127 | if (m_disable_logins) | ||
128 | m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; | ||
129 | |||
130 | if (m_uri != string.Empty) | ||
131 | RRAlert("shutdown"); | ||
132 | |||
133 | m_scene = null; | ||
134 | } | ||
135 | |||
136 | public void Close() | ||
137 | { | ||
138 | } | ||
139 | |||
140 | public void RegionLoaded(Scene scene) | ||
141 | { | ||
142 | } | ||
143 | |||
144 | public string Name | ||
145 | { | ||
146 | get { return "RegionReadyModule"; } | ||
147 | } | ||
148 | |||
149 | #endregion | ||
150 | |||
151 | void OnEmptyScriptCompileQueue(int numScriptsFailed, string message) | ||
152 | { | ||
153 | m_log.DebugFormat("[RegionReady]: Script compile queue empty!"); | ||
154 | |||
155 | if (m_firstEmptyCompileQueue || m_oarFileLoading) | ||
156 | { | ||
157 | OSChatMessage c = new OSChatMessage(); | ||
158 | if (m_firstEmptyCompileQueue) | ||
159 | c.Message = "server_startup,"; | ||
160 | else | ||
161 | c.Message = "oar_file_load,"; | ||
162 | m_firstEmptyCompileQueue = false; | ||
163 | m_oarFileLoading = false; | ||
164 | |||
165 | m_scene.Backup(false); | ||
166 | |||
167 | c.From = "RegionReady"; | ||
168 | if (m_lastOarLoadedOk) | ||
169 | c.Message += "1,"; | ||
170 | else | ||
171 | c.Message += "0,"; | ||
172 | c.Channel = m_channelNotify; | ||
173 | c.Message += numScriptsFailed.ToString() + "," + message; | ||
174 | c.Type = ChatTypeEnum.Region; | ||
175 | if (m_scene != null) | ||
176 | c.Position = new Vector3((m_scene.RegionInfo.RegionSizeX * 0.5f), (m_scene.RegionInfo.RegionSizeY * 0.5f), 30); | ||
177 | else | ||
178 | c.Position = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30); | ||
179 | c.Sender = null; | ||
180 | c.SenderUUID = UUID.Zero; | ||
181 | c.Scene = m_scene; | ||
182 | |||
183 | m_log.DebugFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", | ||
184 | m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); | ||
185 | |||
186 | m_scene.EventManager.TriggerOnChatBroadcast(this, c); | ||
187 | |||
188 | TriggerRegionReady(m_scene); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | void OnOarFileLoaded(Guid requestId, List<UUID> loadedScenes, string message) | ||
193 | { | ||
194 | m_oarFileLoading = true; | ||
195 | |||
196 | if (message==String.Empty) | ||
197 | { | ||
198 | m_lastOarLoadedOk = true; | ||
199 | } | ||
200 | else | ||
201 | { | ||
202 | m_log.WarnFormat("[RegionReady]: Oar file load errors: {0}", message); | ||
203 | m_lastOarLoadedOk = false; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | /// <summary> | ||
208 | /// This will be triggered by Scene directly if it contains no scripts on startup. Otherwise it is triggered | ||
209 | /// when the script compile queue is empty after initial region startup. | ||
210 | /// </summary> | ||
211 | /// <param name='scene'></param> | ||
212 | public void TriggerRegionReady(IScene scene) | ||
213 | { | ||
214 | m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; | ||
215 | m_scene.LoginLock = false; | ||
216 | |||
217 | if (!m_scene.StartDisabled) | ||
218 | { | ||
219 | m_scene.LoginsEnabled = true; | ||
220 | |||
221 | // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", | ||
222 | // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); | ||
223 | |||
224 | // Putting this out to console to make it eye-catching for people who are running OpenSimulator | ||
225 | // without info log messages enabled. Making this a warning is arguably misleading since it isn't a | ||
226 | // warning, and monitor scripts looking for warn/error/fatal messages will received false positives. | ||
227 | // Arguably, log4net needs a status log level (like Apache). | ||
228 | MainConsole.Instance.OutputFormat("INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name); | ||
229 | } | ||
230 | |||
231 | m_scene.SceneGridService.InformNeighborsThatRegionisUp( | ||
232 | m_scene.RequestModuleInterface<INeighbourService>(), m_scene.RegionInfo); | ||
233 | |||
234 | if (m_uri != string.Empty) | ||
235 | { | ||
236 | RRAlert("enabled"); | ||
237 | } | ||
238 | |||
239 | m_scene.Ready = true; | ||
240 | } | ||
241 | |||
242 | public void OarLoadingAlert(string msg) | ||
243 | { | ||
244 | // Let's bypass this for now until some better feedback can be established | ||
245 | // | ||
246 | |||
247 | // if (msg == "load") | ||
248 | // { | ||
249 | // m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue; | ||
250 | // m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded; | ||
251 | // m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled; | ||
252 | // m_scene.EventManager.OnRezScript += OnRezScript; | ||
253 | // m_oarFileLoading = true; | ||
254 | // m_firstEmptyCompileQueue = true; | ||
255 | // | ||
256 | // m_scene.LoginsDisabled = true; | ||
257 | // m_scene.LoginLock = true; | ||
258 | // if ( m_uri != string.Empty ) | ||
259 | // { | ||
260 | // RRAlert("loading oar"); | ||
261 | // RRAlert("disabled"); | ||
262 | // } | ||
263 | // } | ||
264 | } | ||
265 | |||
266 | public void RRAlert(string status) | ||
267 | { | ||
268 | string request_method = "POST"; | ||
269 | string content_type = "application/json"; | ||
270 | OSDMap RRAlert = new OSDMap(); | ||
271 | |||
272 | RRAlert["alert"] = "region_ready"; | ||
273 | RRAlert["login"] = status; | ||
274 | RRAlert["region_name"] = m_scene.RegionInfo.RegionName; | ||
275 | RRAlert["region_id"] = m_scene.RegionInfo.RegionID; | ||
276 | |||
277 | string strBuffer = ""; | ||
278 | byte[] buffer = new byte[1]; | ||
279 | try | ||
280 | { | ||
281 | strBuffer = OSDParser.SerializeJsonString(RRAlert); | ||
282 | Encoding str = Util.UTF8; | ||
283 | buffer = str.GetBytes(strBuffer); | ||
284 | |||
285 | } | ||
286 | catch (Exception e) | ||
287 | { | ||
288 | m_log.WarnFormat("[RegionReady]: Exception thrown on alert: {0}", e.Message); | ||
289 | } | ||
290 | |||
291 | WebRequest request = WebRequest.Create(m_uri); | ||
292 | request.Method = request_method; | ||
293 | request.ContentType = content_type; | ||
294 | |||
295 | Stream os = null; | ||
296 | try | ||
297 | { | ||
298 | request.ContentLength = buffer.Length; | ||
299 | os = request.GetRequestStream(); | ||
300 | os.Write(buffer, 0, strBuffer.Length); | ||
301 | } | ||
302 | catch(Exception e) | ||
303 | { | ||
304 | m_log.WarnFormat("[RegionReady]: Exception thrown sending alert: {0}", e.Message); | ||
305 | } | ||
306 | finally | ||
307 | { | ||
308 | if (os != null) | ||
309 | os.Dispose(); | ||
310 | } | ||
311 | } | ||
312 | } | ||
313 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs new file mode 100644 index 0000000..709d389 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs | |||
@@ -0,0 +1,208 @@ | |||
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.Reflection; | ||
31 | |||
32 | using log4net; | ||
33 | using Nini.Config; | ||
34 | using OpenMetaverse; | ||
35 | using Mono.Addins; | ||
36 | |||
37 | using OpenSim.Framework; | ||
38 | using OpenSim.Framework.Communications; | ||
39 | using OpenSim.Framework.Servers; | ||
40 | using OpenSim.Framework.Servers.HttpServer; | ||
41 | using OpenSim.Framework.Client; | ||
42 | using OpenSim.Region.Framework.Interfaces; | ||
43 | using OpenSim.Region.Framework.Scenes; | ||
44 | |||
45 | namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule | ||
46 | { | ||
47 | public class XmlRpcInfo | ||
48 | { | ||
49 | public UUID item; | ||
50 | public UUID channel; | ||
51 | public string uri; | ||
52 | } | ||
53 | |||
54 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XmlRpcGridRouter")] | ||
55 | public class XmlRpcGridRouter : INonSharedRegionModule, IXmlRpcRouter | ||
56 | { | ||
57 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
58 | |||
59 | private Dictionary<UUID, UUID> m_Channels = | ||
60 | new Dictionary<UUID, UUID>(); | ||
61 | |||
62 | private bool m_Enabled = false; | ||
63 | private string m_ServerURI = String.Empty; | ||
64 | |||
65 | #region INonSharedRegionModule | ||
66 | |||
67 | public void Initialise(IConfigSource config) | ||
68 | { | ||
69 | IConfig startupConfig = config.Configs["XMLRPC"]; | ||
70 | if (startupConfig == null) | ||
71 | return; | ||
72 | |||
73 | if (startupConfig.GetString("XmlRpcRouterModule", | ||
74 | "XmlRpcRouterModule") == "XmlRpcGridRouterModule") | ||
75 | { | ||
76 | m_ServerURI = startupConfig.GetString("XmlRpcHubURI", String.Empty); | ||
77 | if (m_ServerURI == String.Empty) | ||
78 | { | ||
79 | m_log.Error("[XMLRPC GRID ROUTER] Module configured but no URI given. Disabling"); | ||
80 | return; | ||
81 | } | ||
82 | m_Enabled = true; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | public void AddRegion(Scene scene) | ||
87 | { | ||
88 | if (!m_Enabled) | ||
89 | return; | ||
90 | |||
91 | scene.RegisterModuleInterface<IXmlRpcRouter>(this); | ||
92 | |||
93 | IScriptModule scriptEngine = scene.RequestModuleInterface<IScriptModule>(); | ||
94 | if ( scriptEngine != null ) | ||
95 | { | ||
96 | scriptEngine.OnScriptRemoved += this.ScriptRemoved; | ||
97 | scriptEngine.OnObjectRemoved += this.ObjectRemoved; | ||
98 | |||
99 | } | ||
100 | } | ||
101 | |||
102 | public void RegionLoaded(Scene scene) | ||
103 | { | ||
104 | } | ||
105 | |||
106 | public void RemoveRegion(Scene scene) | ||
107 | { | ||
108 | if (!m_Enabled) | ||
109 | return; | ||
110 | |||
111 | scene.UnregisterModuleInterface<IXmlRpcRouter>(this); | ||
112 | } | ||
113 | |||
114 | public void Close() | ||
115 | { | ||
116 | } | ||
117 | |||
118 | public string Name | ||
119 | { | ||
120 | get { return "XmlRpcGridRouterModule"; } | ||
121 | } | ||
122 | |||
123 | public Type ReplaceableInterface | ||
124 | { | ||
125 | get { return null; } | ||
126 | } | ||
127 | |||
128 | #endregion | ||
129 | |||
130 | public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) | ||
131 | { | ||
132 | if (!m_Enabled) | ||
133 | return; | ||
134 | |||
135 | m_log.InfoFormat("[XMLRPC GRID ROUTER]: New receiver Obj: {0} Ch: {1} ID: {2} URI: {3}", | ||
136 | objectID.ToString(), channel.ToString(), itemID.ToString(), uri); | ||
137 | |||
138 | XmlRpcInfo info = new XmlRpcInfo(); | ||
139 | info.channel = channel; | ||
140 | info.uri = uri; | ||
141 | info.item = itemID; | ||
142 | |||
143 | bool success = SynchronousRestObjectRequester.MakeRequest<XmlRpcInfo, bool>( | ||
144 | "POST", m_ServerURI+"/RegisterChannel/", info); | ||
145 | |||
146 | if (!success) | ||
147 | { | ||
148 | m_log.Error("[XMLRPC GRID ROUTER] Error contacting server"); | ||
149 | } | ||
150 | |||
151 | m_Channels[itemID] = channel; | ||
152 | |||
153 | } | ||
154 | |||
155 | public void UnRegisterReceiver(string channelID, UUID itemID) | ||
156 | { | ||
157 | if (!m_Enabled) | ||
158 | return; | ||
159 | |||
160 | RemoveChannel(itemID); | ||
161 | |||
162 | } | ||
163 | |||
164 | public void ScriptRemoved(UUID itemID) | ||
165 | { | ||
166 | if (!m_Enabled) | ||
167 | return; | ||
168 | |||
169 | RemoveChannel(itemID); | ||
170 | |||
171 | } | ||
172 | |||
173 | public void ObjectRemoved(UUID objectID) | ||
174 | { | ||
175 | // m_log.InfoFormat("[XMLRPC GRID ROUTER]: Object Removed {0}",objectID.ToString()); | ||
176 | } | ||
177 | |||
178 | private bool RemoveChannel(UUID itemID) | ||
179 | { | ||
180 | if(!m_Channels.ContainsKey(itemID)) | ||
181 | { | ||
182 | m_log.InfoFormat("[XMLRPC GRID ROUTER]: Attempted to unregister non-existing Item: {0}", itemID.ToString()); | ||
183 | return false; | ||
184 | } | ||
185 | |||
186 | XmlRpcInfo info = new XmlRpcInfo(); | ||
187 | |||
188 | info.channel = m_Channels[itemID]; | ||
189 | info.item = itemID; | ||
190 | info.uri = "http://0.0.0.0:00"; | ||
191 | |||
192 | if (info != null) | ||
193 | { | ||
194 | bool success = SynchronousRestObjectRequester.MakeRequest<XmlRpcInfo, bool>( | ||
195 | "POST", m_ServerURI+"/RemoveChannel/", info); | ||
196 | |||
197 | if (!success) | ||
198 | { | ||
199 | m_log.Error("[XMLRPC GRID ROUTER] Error contacting server"); | ||
200 | } | ||
201 | |||
202 | m_Channels.Remove(itemID); | ||
203 | return true; | ||
204 | } | ||
205 | return false; | ||
206 | } | ||
207 | } | ||
208 | } | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs new file mode 100644 index 0000000..943675e --- /dev/null +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs | |||
@@ -0,0 +1,118 @@ | |||
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.Reflection; | ||
30 | |||
31 | using log4net; | ||
32 | using Nini.Config; | ||
33 | using OpenMetaverse; | ||
34 | using Mono.Addins; | ||
35 | |||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.Framework.Interfaces; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | |||
40 | |||
41 | namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule | ||
42 | { | ||
43 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XmlRpcRouter")] | ||
44 | public class XmlRpcRouter : INonSharedRegionModule, IXmlRpcRouter | ||
45 | { | ||
46 | //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | private bool m_Enabled; | ||
49 | |||
50 | #region INonSharedRegionModule | ||
51 | |||
52 | public void Initialise(IConfigSource config) | ||
53 | { | ||
54 | IConfig startupConfig = config.Configs["XMLRPC"]; | ||
55 | if (startupConfig == null) | ||
56 | return; | ||
57 | |||
58 | if (startupConfig.GetString("XmlRpcRouterModule", | ||
59 | "XmlRpcRouterModule") == "XmlRpcRouterModule") | ||
60 | m_Enabled = true; | ||
61 | } | ||
62 | |||
63 | public void AddRegion(Scene scene) | ||
64 | { | ||
65 | if (!m_Enabled) | ||
66 | return; | ||
67 | |||
68 | scene.RegisterModuleInterface<IXmlRpcRouter>(this); | ||
69 | } | ||
70 | |||
71 | public void RegionLoaded(Scene scene) | ||
72 | { | ||
73 | } | ||
74 | |||
75 | public void RemoveRegion(Scene scene) | ||
76 | { | ||
77 | if (!m_Enabled) | ||
78 | return; | ||
79 | |||
80 | scene.UnregisterModuleInterface<IXmlRpcRouter>(this); | ||
81 | } | ||
82 | |||
83 | public void Close() | ||
84 | { | ||
85 | } | ||
86 | |||
87 | public string Name | ||
88 | { | ||
89 | get { return "XmlRpcRouterModule"; } | ||
90 | } | ||
91 | |||
92 | public Type ReplaceableInterface | ||
93 | { | ||
94 | get { return null; } | ||
95 | } | ||
96 | |||
97 | #endregion | ||
98 | |||
99 | public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) | ||
100 | { | ||
101 | scriptEngine.PostScriptEvent(itemID, "xmlrpc_uri", new Object[] {uri}); | ||
102 | } | ||
103 | |||
104 | public void UnRegisterReceiver(string channelID, UUID itemID) | ||
105 | { | ||
106 | } | ||
107 | |||
108 | public void ScriptRemoved(UUID itemID) | ||
109 | { | ||
110 | // System.Console.WriteLine("TEST Script Removed!"); | ||
111 | } | ||
112 | |||
113 | public void ObjectRemoved(UUID objectID) | ||
114 | { | ||
115 | // System.Console.WriteLine("TEST Obj Removed!"); | ||
116 | } | ||
117 | } | ||
118 | } | ||