aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs48
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs38
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs500
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs430
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs490
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs2
-rw-r--r--bin/OpenSimDefaults.ini6
9 files changed, 1534 insertions, 2 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
new file mode 100644
index 0000000..baac6e8
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
@@ -0,0 +1,48 @@
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
28using System;
29using System.Reflection;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Framework.Interfaces
33{
34 public delegate void TakeValueCallback(string s);
35
36 public interface IJsonStoreModule
37 {
38 bool CreateStore(string value, out UUID result);
39 bool DestroyStore(UUID storeID);
40 bool TestPath(UUID storeID, string path, bool useJson);
41 bool SetValue(UUID storeID, string path, string value, bool useJson);
42 bool RemoveValue(UUID storeID, string path);
43 bool GetValue(UUID storeID, string path, bool useJson, out string value);
44
45 void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
46 void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
47 }
48}
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index cd4bd42..0a1b921 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -101,6 +101,9 @@ namespace OpenSim.Region.Framework.Scenes
101 /// </summary> 101 /// </summary>
102 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>(); 102 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>();
103 103
104 /// <summary>
105 /// Lock to prevent object group update, linking and delinking operations from running concurrently.
106 /// </summary>
104 private Object m_updateLock = new Object(); 107 private Object m_updateLock = new Object();
105 108
106 #endregion 109 #endregion
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 6f3a084..7bd6c11 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2584,6 +2584,10 @@ namespace OpenSim.Region.Framework.Scenes
2584 /// <summary> 2584 /// <summary>
2585 /// Link the prims in a given group to this group 2585 /// Link the prims in a given group to this group
2586 /// </summary> 2586 /// </summary>
2587 /// <remarks>
2588 /// Do not call this method directly - use Scene.LinkObjects() instead to avoid races between threads.
2589 /// FIXME: There are places where scripts call these methods directly without locking. This is a potential race condition.
2590 /// </remarks>
2587 /// <param name="objectGroup">The group of prims which should be linked to this group</param> 2591 /// <param name="objectGroup">The group of prims which should be linked to this group</param>
2588 public void LinkToGroup(SceneObjectGroup objectGroup) 2592 public void LinkToGroup(SceneObjectGroup objectGroup)
2589 { 2593 {
@@ -2714,6 +2718,11 @@ namespace OpenSim.Region.Framework.Scenes
2714 /// Delink the given prim from this group. The delinked prim is established as 2718 /// Delink the given prim from this group. The delinked prim is established as
2715 /// an independent SceneObjectGroup. 2719 /// an independent SceneObjectGroup.
2716 /// </summary> 2720 /// </summary>
2721 /// <remarks>
2722 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2723 /// condition. But currently there is no
2724 /// alternative method that does take a lonk to delink a single prim.
2725 /// </remarks>
2717 /// <param name="partID"></param> 2726 /// <param name="partID"></param>
2718 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> 2727 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
2719 public SceneObjectGroup DelinkFromGroup(uint partID) 2728 public SceneObjectGroup DelinkFromGroup(uint partID)
@@ -2725,6 +2734,11 @@ namespace OpenSim.Region.Framework.Scenes
2725 /// Delink the given prim from this group. The delinked prim is established as 2734 /// Delink the given prim from this group. The delinked prim is established as
2726 /// an independent SceneObjectGroup. 2735 /// an independent SceneObjectGroup.
2727 /// </summary> 2736 /// </summary>
2737 /// <remarks>
2738 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2739 /// condition. But currently there is no
2740 /// alternative method that does take a lonk to delink a single prim.
2741 /// </remarks>
2728 /// <param name="partID"></param> 2742 /// <param name="partID"></param>
2729 /// <param name="sendEvents"></param> 2743 /// <param name="sendEvents"></param>
2730 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> 2744 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
@@ -2750,6 +2764,11 @@ namespace OpenSim.Region.Framework.Scenes
2750 /// Delink the given prim from this group. The delinked prim is established as 2764 /// Delink the given prim from this group. The delinked prim is established as
2751 /// an independent SceneObjectGroup. 2765 /// an independent SceneObjectGroup.
2752 /// </summary> 2766 /// </summary>
2767 /// <remarks>
2768 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2769 /// condition. But currently there is no
2770 /// alternative method that does take a lonk to delink a single prim.
2771 /// </remarks>
2753 /// <param name="partID"></param> 2772 /// <param name="partID"></param>
2754 /// <param name="sendEvents"></param> 2773 /// <param name="sendEvents"></param>
2755 /// <returns>The object group of the newly delinked prim.</returns> 2774 /// <returns>The object group of the newly delinked prim.</returns>
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
index fffa3bd..9fea3c6 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
@@ -111,8 +111,44 @@ namespace OpenSim.Region.Framework.Scenes.Tests
111 Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition)); 111 Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition));
112 Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition)); 112 Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition));
113 Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition)); 113 Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition));
114 }
115
116 [Test]
117 public void TestGetChildPartPositionAfterObjectRotation()
118 {
119 TestHelpers.InMethod();
120
121 Vector3 rootPartPosition = new Vector3(10, 20, 30);
122 Vector3 childOffsetPosition = new Vector3(2, 3, 4);
123
124 SceneObjectGroup so
125 = SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10);
126 so.AbsolutePosition = rootPartPosition;
127 so.Parts[1].OffsetPosition = childOffsetPosition;
128
129 m_scene.AddNewSceneObject(so, false);
130
131 so.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 0, -90 * Utils.DEG_TO_RAD));
132
133 // Calculate child absolute position.
134 Vector3 rotatedChildOffsetPosition
135 = new Vector3(childOffsetPosition.Y, -childOffsetPosition.X, childOffsetPosition.Z);
136
137 Vector3 childPosition = new Vector3(rootPartPosition + rotatedChildOffsetPosition);
138
139 SceneObjectPart childPart = so.Parts[1];
114 140
115 // TODO: Write test for child part position after rotation. 141 // FIXME: Should be childPosition after rotation?
142 Assert.That(childPart.AbsolutePosition, Is.EqualTo(rootPartPosition + childOffsetPosition));
143
144 Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition));
145 Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition));
146
147 // Relative to root part as (0, 0, 0)
148 Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition));
149
150 // Relative to root part as (0, 0, 0)
151 Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition));
116 } 152 }
117 } 153 }
118} \ No newline at end of file 154} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
new file mode 100644
index 0000000..34894ba
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
@@ -0,0 +1,500 @@
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 */
27using Mono.Addins;
28
29using System;
30using System.Reflection;
31using System.Threading;
32using System.Text;
33using System.Net;
34using System.Net.Sockets;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42using System.Collections.Generic;
43using System.Text.RegularExpressions;
44
45namespace 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 private OSD m_ValueStore;
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
72 // -----------------------------------------------------------------
73 /// <summary>
74 ///
75 /// </summary>
76 // -----------------------------------------------------------------
77 public JsonStore() : this("") {}
78
79 public JsonStore(string value)
80 {
81 m_TakeStore = new List<TakeValueCallbackClass>();
82 m_ReadStore = new List<TakeValueCallbackClass>();
83
84 if (String.IsNullOrEmpty(value))
85 m_ValueStore = new OSDMap();
86 else
87 m_ValueStore = OSDParser.DeserializeJson(value);
88 }
89
90 // -----------------------------------------------------------------
91 /// <summary>
92 ///
93 /// </summary>
94 // -----------------------------------------------------------------
95 public bool TestPath(string expr, bool useJson)
96 {
97 Stack<string> path = ParsePathExpression(expr);
98 OSD result = ProcessPathExpression(m_ValueStore,path);
99
100 if (result == null)
101 return false;
102
103 if (useJson || result.Type == OSDType.String)
104 return true;
105
106 return false;
107 }
108
109 // -----------------------------------------------------------------
110 /// <summary>
111 ///
112 /// </summary>
113 // -----------------------------------------------------------------
114 public bool GetValue(string expr, out string value, bool useJson)
115 {
116 Stack<string> path = ParsePathExpression(expr);
117 OSD result = ProcessPathExpression(m_ValueStore,path);
118 return ConvertOutputValue(result,out value,useJson);
119 }
120
121
122 // -----------------------------------------------------------------
123 /// <summary>
124 ///
125 /// </summary>
126 // -----------------------------------------------------------------
127 public bool RemoveValue(string expr)
128 {
129 return SetValueFromExpression(expr,null);
130 }
131
132 // -----------------------------------------------------------------
133 /// <summary>
134 ///
135 /// </summary>
136 // -----------------------------------------------------------------
137 public bool SetValue(string expr, string value, bool useJson)
138 {
139 OSD ovalue = useJson ? OSDParser.DeserializeJson(value) : new OSDString(value);
140 return SetValueFromExpression(expr,ovalue);
141 }
142
143 // -----------------------------------------------------------------
144 /// <summary>
145 ///
146 /// </summary>
147 // -----------------------------------------------------------------
148 public bool TakeValue(string expr, bool useJson, TakeValueCallback cback)
149 {
150 Stack<string> path = ParsePathExpression(expr);
151 string pexpr = PathExpressionToKey(path);
152
153 OSD result = ProcessPathExpression(m_ValueStore,path);
154 if (result == null)
155 {
156 m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
157 return false;
158 }
159
160 string value = String.Empty;
161 if (! ConvertOutputValue(result,out value,useJson))
162 {
163 // the structure does not match the request so i guess we'll wait
164 m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
165 return false;
166 }
167
168 SetValueFromExpression(expr,null);
169 cback(value);
170
171 return true;
172 }
173
174 // -----------------------------------------------------------------
175 /// <summary>
176 ///
177 /// </summary>
178 // -----------------------------------------------------------------
179 public bool ReadValue(string expr, bool useJson, TakeValueCallback cback)
180 {
181 Stack<string> path = ParsePathExpression(expr);
182 string pexpr = PathExpressionToKey(path);
183
184 OSD result = ProcessPathExpression(m_ValueStore,path);
185 if (result == null)
186 {
187 m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
188 return false;
189 }
190
191 string value = String.Empty;
192 if (! ConvertOutputValue(result,out value,useJson))
193 {
194 // the structure does not match the request so i guess we'll wait
195 m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
196 return false;
197 }
198
199 cback(value);
200
201 return true;
202 }
203
204 // -----------------------------------------------------------------
205 /// <summary>
206 ///
207 /// </summary>
208 // -----------------------------------------------------------------
209 protected bool SetValueFromExpression(string expr, OSD ovalue)
210 {
211 Stack<string> path = ParsePathExpression(expr);
212 if (path.Count == 0)
213 {
214 m_ValueStore = ovalue;
215 return true;
216 }
217
218 string pkey = path.Pop();
219 string pexpr = PathExpressionToKey(path);
220 if (pexpr != "")
221 pexpr += ".";
222
223 OSD result = ProcessPathExpression(m_ValueStore,path);
224 if (result == null)
225 return false;
226
227 Regex aPattern = new Regex("\\[([0-9]+|\\+)\\]");
228 MatchCollection amatches = aPattern.Matches(pkey,0);
229
230 if (amatches.Count > 0)
231 {
232 if (result.Type != OSDType.Array)
233 return false;
234
235 OSDArray amap = result as OSDArray;
236
237 Match match = amatches[0];
238 GroupCollection groups = match.Groups;
239 string akey = groups[1].Value;
240
241 if (akey == "+")
242 {
243 string npkey = String.Format("[{0}]",amap.Count);
244
245 amap.Add(ovalue);
246 InvokeNextCallback(pexpr + npkey);
247 return true;
248 }
249
250 int aval = Convert.ToInt32(akey);
251 if (0 <= aval && aval < amap.Count)
252 {
253 if (ovalue == null)
254 amap.RemoveAt(aval);
255 else
256 {
257 amap[aval] = ovalue;
258 InvokeNextCallback(pexpr + pkey);
259 }
260 return true;
261 }
262
263 return false;
264 }
265
266 Regex hPattern = new Regex("{([^}]+)}");
267 MatchCollection hmatches = hPattern.Matches(pkey,0);
268
269 if (hmatches.Count > 0)
270 {
271 Match match = hmatches[0];
272 GroupCollection groups = match.Groups;
273 string hkey = groups[1].Value;
274
275 if (result is OSDMap)
276 {
277 OSDMap hmap = result as OSDMap;
278 if (ovalue != null)
279 {
280 hmap[hkey] = ovalue;
281 InvokeNextCallback(pexpr + pkey);
282 }
283 else if (hmap.ContainsKey(hkey))
284 hmap.Remove(hkey);
285
286 return true;
287 }
288
289 return false;
290 }
291
292 // Shouldn't get here if the path was checked correctly
293 m_log.WarnFormat("[JsonStore] invalid path expression");
294 return false;
295 }
296
297 // -----------------------------------------------------------------
298 /// <summary>
299 ///
300 /// </summary>
301 // -----------------------------------------------------------------
302 protected bool InvokeNextCallback(string pexpr)
303 {
304 // Process all of the reads that match the expression first
305 List<TakeValueCallbackClass> reads =
306 m_ReadStore.FindAll(delegate(TakeValueCallbackClass tb) { return pexpr.StartsWith(tb.Path); });
307
308 foreach (TakeValueCallbackClass readcb in reads)
309 {
310 m_ReadStore.Remove(readcb);
311 ReadValue(readcb.Path,readcb.UseJson,readcb.Callback);
312 }
313
314 // Process one take next
315 TakeValueCallbackClass takecb =
316 m_TakeStore.Find(delegate(TakeValueCallbackClass tb) { return pexpr.StartsWith(tb.Path); });
317
318 if (takecb != null)
319 {
320 m_TakeStore.Remove(takecb);
321 TakeValue(takecb.Path,takecb.UseJson,takecb.Callback);
322
323 return true;
324 }
325
326 return false;
327 }
328
329 // -----------------------------------------------------------------
330 /// <summary>
331 /// Parse the path expression and put the components into a stack. We
332 /// use a stack because we process the path in inverse order later
333 /// </summary>
334 // -----------------------------------------------------------------
335 protected static Stack<string> ParsePathExpression(string path)
336 {
337 Stack<string> m_path = new Stack<string>();
338
339 // add front and rear separators
340 path = "." + path + ".";
341
342 // add separators for quoted paths
343 Regex pass1 = new Regex("{[^}]+}");
344 path = pass1.Replace(path,".$0.",-1,0);
345
346 // add separators for array references
347 Regex pass2 = new Regex("(\\[[0-9]+\\]|\\[\\+\\])");
348 path = pass2.Replace(path,".$0.",-1,0);
349
350 // add quotes to bare identifier
351 Regex pass3 = new Regex("\\.([a-zA-Z]+)");
352 path = pass3.Replace(path,".{$1}",-1,0);
353
354 // remove extra separators
355 Regex pass4 = new Regex("\\.+");
356 path = pass4.Replace(path,".",-1,0);
357
358 Regex validate = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$");
359 if (validate.IsMatch(path))
360 {
361 Regex parser = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)");
362 MatchCollection matches = parser.Matches(path,0);
363 foreach (Match match in matches)
364 m_path.Push(match.Groups[1].Value);
365 }
366
367 return m_path;
368 }
369
370 // -----------------------------------------------------------------
371 /// <summary>
372 ///
373 /// </summary>
374 /// <param>path is a stack where the top level of the path is at the bottom of the stack</param>
375 // -----------------------------------------------------------------
376 protected static OSD ProcessPathExpression(OSD map, Stack<string> path)
377 {
378 if (path.Count == 0)
379 return map;
380
381 string pkey = path.Pop();
382
383 OSD rmap = ProcessPathExpression(map,path);
384 if (rmap == null)
385 return null;
386
387 // ---------- Check for an array index ----------
388 Regex aPattern = new Regex("\\[([0-9]+)\\]");
389 MatchCollection amatches = aPattern.Matches(pkey,0);
390
391 if (amatches.Count > 0)
392 {
393 if (rmap.Type != OSDType.Array)
394 {
395 m_log.WarnFormat("[JsonStore] wrong type for key {2}, expecting {0}, got {1}",OSDType.Array,rmap.Type,pkey);
396 return null;
397 }
398
399 OSDArray amap = rmap as OSDArray;
400
401 Match match = amatches[0];
402 GroupCollection groups = match.Groups;
403 string akey = groups[1].Value;
404 int aval = Convert.ToInt32(akey);
405
406 if (aval < amap.Count)
407 return (OSD) amap[aval];
408
409 return null;
410 }
411
412 // ---------- Check for a hash index ----------
413 Regex hPattern = new Regex("{([^}]+)}");
414 MatchCollection hmatches = hPattern.Matches(pkey,0);
415
416 if (hmatches.Count > 0)
417 {
418 if (rmap.Type != OSDType.Map)
419 {
420 m_log.WarnFormat("[JsonStore] wrong type for key {2}, expecting {0}, got {1}",OSDType.Map,rmap.Type,pkey);
421 return null;
422 }
423
424 OSDMap hmap = rmap as OSDMap;
425
426 Match match = hmatches[0];
427 GroupCollection groups = match.Groups;
428 string hkey = groups[1].Value;
429
430 if (hmap.ContainsKey(hkey))
431 return (OSD) hmap[hkey];
432
433 return null;
434 }
435
436 // Shouldn't get here if the path was checked correctly
437 m_log.WarnFormat("[JsonStore] Path type (unknown) does not match the structure");
438 return null;
439 }
440
441 // -----------------------------------------------------------------
442 /// <summary>
443 ///
444 /// </summary>
445 // -----------------------------------------------------------------
446 protected static bool ConvertOutputValue(OSD result, out string value, bool useJson)
447 {
448 value = String.Empty;
449
450 // If we couldn't process the path
451 if (result == null)
452 return false;
453
454 if (useJson)
455 {
456 // The path pointed to an intermediate hash structure
457 if (result.Type == OSDType.Map)
458 {
459 value = OSDParser.SerializeJsonString(result as OSDMap);
460 return true;
461 }
462
463 // The path pointed to an intermediate hash structure
464 if (result.Type == OSDType.Array)
465 {
466 value = OSDParser.SerializeJsonString(result as OSDArray);
467 return true;
468 }
469
470 value = "'" + result.AsString() + "'";
471 return true;
472 }
473
474 if (result.Type == OSDType.String)
475 {
476 value = result.AsString();
477 return true;
478 }
479
480 return false;
481 }
482
483 // -----------------------------------------------------------------
484 /// <summary>
485 ///
486 /// </summary>
487 // -----------------------------------------------------------------
488 protected static string PathExpressionToKey(Stack<string> path)
489 {
490 if (path.Count == 0)
491 return "";
492
493 string pkey = "";
494 foreach (string k in path)
495 pkey = (pkey == "") ? k : (k + "." + pkey);
496
497 return pkey;
498 }
499 }
500}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
new file mode 100644
index 0000000..311531c
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -0,0 +1,430 @@
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 */
27using Mono.Addins;
28
29using System;
30using System.Reflection;
31using System.Threading;
32using System.Text;
33using System.Net;
34using System.Net.Sockets;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42using System.Collections.Generic;
43using System.Text.RegularExpressions;
44
45
46namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
47{
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreModule")]
49
50 public class JsonStoreModule : INonSharedRegionModule, IJsonStoreModule
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private IConfig m_config = null;
56 private bool m_enabled = false;
57 private Scene m_scene = null;
58
59 private Dictionary<UUID,JsonStore> m_JsonValueStore;
60 private UUID m_sharedStore;
61
62#region IRegionModule Members
63
64 // -----------------------------------------------------------------
65 /// <summary>
66 /// Name of this shared module is it's class name
67 /// </summary>
68 // -----------------------------------------------------------------
69 public string Name
70 {
71 get { return this.GetType().Name; }
72 }
73
74 // -----------------------------------------------------------------
75 /// <summary>
76 /// Initialise this shared module
77 /// </summary>
78 /// <param name="scene">this region is getting initialised</param>
79 /// <param name="source">nini config, we are not using this</param>
80 // -----------------------------------------------------------------
81 public void Initialise(IConfigSource config)
82 {
83 try
84 {
85 if ((m_config = config.Configs["JsonStore"]) == null)
86 {
87 // There is no configuration, the module is disabled
88 // m_log.InfoFormat("[JsonStore] no configuration info");
89 return;
90 }
91
92 m_enabled = m_config.GetBoolean("Enabled", m_enabled);
93 }
94 catch (Exception e)
95 {
96 m_log.ErrorFormat("[JsonStore] initialization error: {0}",e.Message);
97 return;
98 }
99
100 if (m_enabled)
101 m_log.DebugFormat("[JsonStore] module is enabled");
102 }
103
104 // -----------------------------------------------------------------
105 /// <summary>
106 /// everything is loaded, perform post load configuration
107 /// </summary>
108 // -----------------------------------------------------------------
109 public void PostInitialise()
110 {
111 }
112
113 // -----------------------------------------------------------------
114 /// <summary>
115 /// Nothing to do on close
116 /// </summary>
117 // -----------------------------------------------------------------
118 public void Close()
119 {
120 }
121
122 // -----------------------------------------------------------------
123 /// <summary>
124 /// </summary>
125 // -----------------------------------------------------------------
126 public void AddRegion(Scene scene)
127 {
128 if (m_enabled)
129 {
130 m_scene = scene;
131 m_scene.RegisterModuleInterface<IJsonStoreModule>(this);
132
133 m_sharedStore = UUID.Zero;
134 m_JsonValueStore = new Dictionary<UUID,JsonStore>();
135 m_JsonValueStore.Add(m_sharedStore,new JsonStore(""));
136 }
137 }
138
139 // -----------------------------------------------------------------
140 /// <summary>
141 /// </summary>
142 // -----------------------------------------------------------------
143 public void RemoveRegion(Scene scene)
144 {
145 // need to remove all references to the scene in the subscription
146 // list to enable full garbage collection of the scene object
147 }
148
149 // -----------------------------------------------------------------
150 /// <summary>
151 /// Called when all modules have been added for a region. This is
152 /// where we hook up events
153 /// </summary>
154 // -----------------------------------------------------------------
155 public void RegionLoaded(Scene scene)
156 {
157 if (m_enabled) {}
158 }
159
160 /// -----------------------------------------------------------------
161 /// <summary>
162 /// </summary>
163 // -----------------------------------------------------------------
164 public Type ReplaceableInterface
165 {
166 get { return null; }
167 }
168
169#endregion
170
171#region ScriptInvocationInteface
172
173 // -----------------------------------------------------------------
174 /// <summary>
175 ///
176 /// </summary>
177 // -----------------------------------------------------------------
178 public bool CreateStore(string value, out UUID result)
179 {
180 result = UUID.Zero;
181
182 if (! m_enabled) return false;
183
184 UUID uuid = UUID.Random();
185 JsonStore map = null;
186
187 try
188 {
189 map = new JsonStore(value);
190 }
191 catch (Exception e)
192 {
193 m_log.InfoFormat("[JsonStore] Unable to initialize store from {0}; {1}",value,e.Message);
194 return false;
195 }
196
197 lock (m_JsonValueStore)
198 m_JsonValueStore.Add(uuid,map);
199
200 result = uuid;
201 return true;
202 }
203
204 // -----------------------------------------------------------------
205 /// <summary>
206 ///
207 /// </summary>
208 // -----------------------------------------------------------------
209 public bool DestroyStore(UUID storeID)
210 {
211 if (! m_enabled) return false;
212
213 lock (m_JsonValueStore)
214 m_JsonValueStore.Remove(storeID);
215
216 return true;
217 }
218
219 // -----------------------------------------------------------------
220 /// <summary>
221 ///
222 /// </summary>
223 // -----------------------------------------------------------------
224 public bool TestPath(UUID storeID, string path, bool useJson)
225 {
226 if (! m_enabled) return false;
227
228 JsonStore map = null;
229 lock (m_JsonValueStore)
230 {
231 if (! m_JsonValueStore.TryGetValue(storeID,out map))
232 {
233 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
234 return true;
235 }
236 }
237
238 try
239 {
240 lock (map)
241 return map.TestPath(path,useJson);
242 }
243 catch (Exception e)
244 {
245 m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message);
246 }
247
248 return false;
249 }
250
251 // -----------------------------------------------------------------
252 /// <summary>
253 ///
254 /// </summary>
255 // -----------------------------------------------------------------
256 public bool SetValue(UUID storeID, string path, string value, bool useJson)
257 {
258 if (! m_enabled) return false;
259
260 JsonStore map = null;
261 lock (m_JsonValueStore)
262 {
263 if (! m_JsonValueStore.TryGetValue(storeID,out map))
264 {
265 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
266 return false;
267 }
268 }
269
270 try
271 {
272 lock (map)
273 if (map.SetValue(path,value,useJson))
274 return true;
275 }
276 catch (Exception e)
277 {
278 m_log.InfoFormat("[JsonStore] Unable to assign {0} to {1} in {2}; {3}",value,path,storeID,e.Message);
279 }
280
281 return false;
282 }
283
284 // -----------------------------------------------------------------
285 /// <summary>
286 ///
287 /// </summary>
288 // -----------------------------------------------------------------
289 public bool RemoveValue(UUID storeID, string path)
290 {
291 if (! m_enabled) return false;
292
293 JsonStore map = null;
294 lock (m_JsonValueStore)
295 {
296 if (! m_JsonValueStore.TryGetValue(storeID,out map))
297 {
298 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
299 return false;
300 }
301 }
302
303 try
304 {
305 lock (map)
306 if (map.RemoveValue(path))
307 return true;
308 }
309 catch (Exception e)
310 {
311 m_log.InfoFormat("[JsonStore] Unable to remove {0} in {1}; {2}",path,storeID,e.Message);
312 }
313
314 return false;
315 }
316
317 // -----------------------------------------------------------------
318 /// <summary>
319 ///
320 /// </summary>
321 // -----------------------------------------------------------------
322 public bool GetValue(UUID storeID, string path, bool useJson, out string value)
323 {
324 value = String.Empty;
325
326 if (! m_enabled) return false;
327
328 JsonStore map = null;
329 lock (m_JsonValueStore)
330 {
331 if (! m_JsonValueStore.TryGetValue(storeID,out map))
332 return false;
333 }
334
335 try
336 {
337 lock (map)
338 {
339 return map.GetValue(path, out value, useJson);
340 }
341 }
342 catch (Exception e)
343 {
344 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.Message);
345 }
346
347 return false;
348 }
349
350 // -----------------------------------------------------------------
351 /// <summary>
352 ///
353 /// </summary>
354 // -----------------------------------------------------------------
355 public void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
356 {
357 if (! m_enabled)
358 {
359 cback(String.Empty);
360 return;
361 }
362
363 JsonStore map = null;
364 lock (m_JsonValueStore)
365 {
366 if (! m_JsonValueStore.TryGetValue(storeID,out map))
367 {
368 cback(String.Empty);
369 return;
370 }
371 }
372
373 try
374 {
375 lock (map)
376 {
377 map.TakeValue(path, useJson, cback);
378 return;
379 }
380 }
381 catch (Exception e)
382 {
383 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString());
384 }
385
386 cback(String.Empty);
387 }
388
389 // -----------------------------------------------------------------
390 /// <summary>
391 ///
392 /// </summary>
393 // -----------------------------------------------------------------
394 public void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
395 {
396 if (! m_enabled)
397 {
398 cback(String.Empty);
399 return;
400 }
401
402 JsonStore map = null;
403 lock (m_JsonValueStore)
404 {
405 if (! m_JsonValueStore.TryGetValue(storeID,out map))
406 {
407 cback(String.Empty);
408 return;
409 }
410 }
411
412 try
413 {
414 lock (map)
415 {
416 map.ReadValue(path, useJson, cback);
417 return;
418 }
419 }
420 catch (Exception e)
421 {
422 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString());
423 }
424
425 cback(String.Empty);
426 }
427
428#endregion
429 }
430}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
new file mode 100644
index 0000000..eda2aef
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -0,0 +1,490 @@
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 */
27using Mono.Addins;
28
29using System;
30using System.Reflection;
31using System.Threading;
32using System.Text;
33using System.Net;
34using System.Net.Sockets;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42using System.Collections.Generic;
43using System.Text.RegularExpressions;
44
45namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
46{
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreScriptModule")]
48
49 public class JsonStoreScriptModule : 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 private Scene m_scene = null;
57
58 private IScriptModuleComms m_comms;
59 private IJsonStoreModule m_store;
60
61#region IRegionModule Members
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("[JsonStoreScripts] 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.ErrorFormat("[JsonStoreScripts] initialization error: {0}",e.Message);
96 return;
97 }
98
99 if (m_enabled)
100 m_log.DebugFormat("[JsonStoreScripts] 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 }
128
129 // -----------------------------------------------------------------
130 /// <summary>
131 /// </summary>
132 // -----------------------------------------------------------------
133 public void RemoveRegion(Scene scene)
134 {
135 // need to remove all references to the scene in the subscription
136 // list to enable full garbage collection of the scene object
137 }
138
139 // -----------------------------------------------------------------
140 /// <summary>
141 /// Called when all modules have been added for a region. This is
142 /// where we hook up events
143 /// </summary>
144 // -----------------------------------------------------------------
145 public void RegionLoaded(Scene scene)
146 {
147 if (m_enabled)
148 {
149 m_scene = scene;
150 m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>();
151 if (m_comms == null)
152 {
153 m_log.ErrorFormat("[JsonStoreScripts] ScriptModuleComms interface not defined");
154 m_enabled = false;
155 return;
156 }
157
158 m_store = m_scene.RequestModuleInterface<IJsonStoreModule>();
159 if (m_store == null)
160 {
161 m_log.ErrorFormat("[JsonStoreScripts] JsonModule interface not defined");
162 m_enabled = false;
163 return;
164 }
165
166 m_comms.RegisterScriptInvocation(this,"JsonCreateStore");
167 m_comms.RegisterScriptInvocation(this,"JsonDestroyStore");
168
169 m_comms.RegisterScriptInvocation(this,"JsonReadNotecard");
170 m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard");
171
172 m_comms.RegisterScriptInvocation(this,"JsonTestPath");
173 m_comms.RegisterScriptInvocation(this,"JsonTestPathJson");
174
175 m_comms.RegisterScriptInvocation(this,"JsonGetValue");
176 m_comms.RegisterScriptInvocation(this,"JsonGetValueJson");
177
178 m_comms.RegisterScriptInvocation(this,"JsonTakeValue");
179 m_comms.RegisterScriptInvocation(this,"JsonTakeValueJson");
180
181 m_comms.RegisterScriptInvocation(this,"JsonReadValue");
182 m_comms.RegisterScriptInvocation(this,"JsonReadValueJson");
183
184 m_comms.RegisterScriptInvocation(this,"JsonSetValue");
185 m_comms.RegisterScriptInvocation(this,"JsonSetValueJson");
186
187 m_comms.RegisterScriptInvocation(this,"JsonRemoveValue");
188 }
189 }
190
191 /// -----------------------------------------------------------------
192 /// <summary>
193 /// </summary>
194 // -----------------------------------------------------------------
195 public Type ReplaceableInterface
196 {
197 get { return null; }
198 }
199
200#endregion
201
202#region ScriptInvocationInteface
203 // -----------------------------------------------------------------
204 /// <summary>
205 ///
206 /// </summary>
207 // -----------------------------------------------------------------
208 protected void GenerateRuntimeError(string msg)
209 {
210 throw new Exception("JsonStore Runtime Error: " + msg);
211 }
212
213 // -----------------------------------------------------------------
214 /// <summary>
215 ///
216 /// </summary>
217 // -----------------------------------------------------------------
218 protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value)
219 {
220 UUID uuid = UUID.Zero;
221 if (! m_store.CreateStore(value, out uuid))
222 GenerateRuntimeError("Failed to create Json store");
223
224 return uuid;
225 }
226
227 // -----------------------------------------------------------------
228 /// <summary>
229 ///
230 /// </summary>
231 // -----------------------------------------------------------------
232 protected int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID)
233 {
234 return m_store.DestroyStore(storeID) ? 1 : 0;
235 }
236
237 // -----------------------------------------------------------------
238 /// <summary>
239 ///
240 /// </summary>
241 // -----------------------------------------------------------------
242 protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID)
243 {
244 UUID reqID = UUID.Random();
245 Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); });
246 return reqID;
247 }
248
249 // -----------------------------------------------------------------
250 /// <summary>
251 ///
252 /// </summary>
253 // -----------------------------------------------------------------
254 protected UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name)
255 {
256 UUID reqID = UUID.Random();
257 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); });
258 return reqID;
259 }
260
261 // -----------------------------------------------------------------
262 /// <summary>
263 ///
264 /// </summary>
265 // -----------------------------------------------------------------
266 protected int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path)
267 {
268 return m_store.TestPath(storeID,path,false) ? 1 : 0;
269 }
270
271 protected int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path)
272 {
273 return m_store.TestPath(storeID,path,true) ? 1 : 0;
274 }
275
276 // -----------------------------------------------------------------
277 /// <summary>
278 ///
279 /// </summary>
280 // -----------------------------------------------------------------
281 protected int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
282 {
283 return m_store.SetValue(storeID,path,value,false) ? 1 : 0;
284 }
285
286 protected int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
287 {
288 return m_store.SetValue(storeID,path,value,true) ? 1 : 0;
289 }
290
291 // -----------------------------------------------------------------
292 /// <summary>
293 ///
294 /// </summary>
295 // -----------------------------------------------------------------
296 protected int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path)
297 {
298 return m_store.RemoveValue(storeID,path) ? 1 : 0;
299 }
300
301 // -----------------------------------------------------------------
302 /// <summary>
303 ///
304 /// </summary>
305 // -----------------------------------------------------------------
306 protected string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path)
307 {
308 string value = String.Empty;
309 m_store.GetValue(storeID,path,false,out value);
310 return value;
311 }
312
313 protected string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
314 {
315 string value = String.Empty;
316 m_store.GetValue(storeID,path,true, out value);
317 return value;
318 }
319
320 // -----------------------------------------------------------------
321 /// <summary>
322 ///
323 /// </summary>
324 // -----------------------------------------------------------------
325 protected UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path)
326 {
327 UUID reqID = UUID.Random();
328 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); });
329 return reqID;
330 }
331
332 protected UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
333 {
334 UUID reqID = UUID.Random();
335 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); });
336 return reqID;
337 }
338
339 private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
340 {
341 try
342 {
343 m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
344 return;
345 }
346 catch (Exception e)
347 {
348 m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString());
349 }
350
351 DispatchValue(scriptID,reqID,String.Empty);
352 }
353
354
355 // -----------------------------------------------------------------
356 /// <summary>
357 ///
358 /// </summary>
359 // -----------------------------------------------------------------
360 protected UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path)
361 {
362 UUID reqID = UUID.Random();
363 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); });
364 return reqID;
365 }
366
367 protected UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
368 {
369 UUID reqID = UUID.Random();
370 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); });
371 return reqID;
372 }
373
374 private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
375 {
376 try
377 {
378 m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
379 return;
380 }
381 catch (Exception e)
382 {
383 m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString());
384 }
385
386 DispatchValue(scriptID,reqID,String.Empty);
387 }
388
389#endregion
390
391 // -----------------------------------------------------------------
392 /// <summary>
393 ///
394 /// </summary>
395 // -----------------------------------------------------------------
396 protected void DispatchValue(UUID scriptID, UUID reqID, string value)
397 {
398 m_comms.DispatchReply(scriptID,1,value,reqID.ToString());
399 }
400
401 // -----------------------------------------------------------------
402 /// <summary>
403 ///
404 /// </summary>
405 // -----------------------------------------------------------------
406 private void DoJsonReadNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID)
407 {
408 AssetBase a = m_scene.AssetService.Get(assetID.ToString());
409 if (a == null)
410 GenerateRuntimeError(String.Format("Unable to find notecard asset {0}",assetID));
411
412 if (a.Type != (sbyte)AssetType.Notecard)
413 GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID));
414
415 m_log.DebugFormat("[JsonStoreScripts] read notecard in context {0}",storeID);
416
417 try
418 {
419 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
420 string jsondata = SLUtil.ParseNotecardToString(enc.GetString(a.Data));
421 int result = m_store.SetValue(storeID,path,jsondata,true) ? 1 : 0;
422 m_comms.DispatchReply(scriptID,result,"",reqID.ToString());
423 return;
424 }
425 catch (Exception e)
426 {
427 m_log.WarnFormat("[JsonStoreScripts] Json parsing failed; {0}",e.Message);
428 }
429
430 GenerateRuntimeError(String.Format("Json parsing failed for {0}",assetID.ToString()));
431 m_comms.DispatchReply(scriptID,0,"",reqID.ToString());
432 }
433
434 // -----------------------------------------------------------------
435 /// <summary>
436 ///
437 /// </summary>
438 // -----------------------------------------------------------------
439 private void DoJsonWriteNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string name)
440 {
441 string data;
442 if (! m_store.GetValue(storeID,path,true, out data))
443 {
444 m_comms.DispatchReply(scriptID,0,UUID.Zero.ToString(),reqID.ToString());
445 return;
446 }
447
448 SceneObjectPart host = m_scene.GetSceneObjectPart(hostID);
449
450 // Create new asset
451 UUID assetID = UUID.Random();
452 AssetBase asset = new AssetBase(assetID, name, (sbyte)AssetType.Notecard, host.OwnerID.ToString());
453 asset.Description = "Json store";
454
455 int textLength = data.Length;
456 data = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length "
457 + textLength.ToString() + "\n" + data + "}\n";
458
459 asset.Data = Util.UTF8.GetBytes(data);
460 m_scene.AssetService.Store(asset);
461
462 // Create Task Entry
463 TaskInventoryItem taskItem = new TaskInventoryItem();
464
465 taskItem.ResetIDs(host.UUID);
466 taskItem.ParentID = host.UUID;
467 taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch();
468 taskItem.Name = asset.Name;
469 taskItem.Description = asset.Description;
470 taskItem.Type = (int)AssetType.Notecard;
471 taskItem.InvType = (int)InventoryType.Notecard;
472 taskItem.OwnerID = host.OwnerID;
473 taskItem.CreatorID = host.OwnerID;
474 taskItem.BasePermissions = (uint)PermissionMask.All;
475 taskItem.CurrentPermissions = (uint)PermissionMask.All;
476 taskItem.EveryonePermissions = 0;
477 taskItem.NextPermissions = (uint)PermissionMask.All;
478 taskItem.GroupID = host.GroupID;
479 taskItem.GroupPermissions = 0;
480 taskItem.Flags = 0;
481 taskItem.PermsGranter = UUID.Zero;
482 taskItem.PermsMask = 0;
483 taskItem.AssetID = asset.FullID;
484
485 host.Inventory.AddInventoryItem(taskItem, false);
486
487 m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString());
488 }
489 }
490}
diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index cab30de..74a85e2 100644
--- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -38,7 +38,7 @@ using OpenMetaverse;
38using System.Linq; 38using System.Linq;
39using System.Linq.Expressions; 39using System.Linq.Expressions;
40 40
41namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms 41namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
42{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
44 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms 44 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index babd0ec..65ec445 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -1561,6 +1561,12 @@
1561 RefreshTime = 3600 1561 RefreshTime = 3600
1562 1562
1563;; 1563;;
1564;; JsonStore module provides structured store for scripts
1565;;
1566[JsonStore]
1567Enabled = False
1568
1569;;
1564;; These are defaults that are overwritten below in [Architecture]. 1570;; These are defaults that are overwritten below in [Architecture].
1565;; These defaults allow OpenSim to work out of the box with 1571;; These defaults allow OpenSim to work out of the box with
1566;; zero configuration 1572;; zero configuration