opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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 JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier)
324 {
325 UUID reqID = UUID.Random();
326 Util.FireAndForget(o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier));
327 return reqID;
328 }
329  
330 // -----------------------------------------------------------------
331 /// <summary>
332 ///
333 /// </summary>
334 // -----------------------------------------------------------------
335 [ScriptInvocation]
336 public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name)
337 {
338 UUID reqID = UUID.Random();
339 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); });
340 return reqID;
341 }
342  
343 // -----------------------------------------------------------------
344 /// <summary>
345 ///
346 /// </summary>
347 // -----------------------------------------------------------------
348 [ScriptInvocation]
349 public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist)
350 {
351 string ipath = ConvertList2Path(pathlist);
352 string opath;
353  
354 if (JsonStore.CanonicalPathExpression(ipath,out opath))
355 return opath;
356  
357 // This won't parse if passed to the other routines as opposed to
358 // returning an empty string which is a valid path and would overwrite
359 // the entire store
360 return "**INVALID**";
361 }
362  
363 // -----------------------------------------------------------------
364 /// <summary>
365 ///
366 /// </summary>
367 // -----------------------------------------------------------------
368 [ScriptInvocation]
369 public int JsonGetNodeType(UUID hostID, UUID scriptID, UUID storeID, string path)
370 {
371 return (int)m_store.GetNodeType(storeID,path);
372 }
373  
374 // -----------------------------------------------------------------
375 /// <summary>
376 ///
377 /// </summary>
378 // -----------------------------------------------------------------
379 [ScriptInvocation]
380 public int JsonGetValueType(UUID hostID, UUID scriptID, UUID storeID, string path)
381 {
382 return (int)m_store.GetValueType(storeID,path);
383 }
384  
385 // -----------------------------------------------------------------
386 /// <summary>
387 ///
388 /// </summary>
389 // -----------------------------------------------------------------
390 [ScriptInvocation]
391 public int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
392 {
393 return m_store.SetValue(storeID,path,value,false) ? 1 : 0;
394 }
395  
396 [ScriptInvocation]
397 public int JsonSetJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
398 {
399 return m_store.SetValue(storeID,path,value,true) ? 1 : 0;
400 }
401  
402 // -----------------------------------------------------------------
403 /// <summary>
404 ///
405 /// </summary>
406 // -----------------------------------------------------------------
407 [ScriptInvocation]
408 public int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path)
409 {
410 return m_store.RemoveValue(storeID,path) ? 1 : 0;
411 }
412  
413 // -----------------------------------------------------------------
414 /// <summary>
415 ///
416 /// </summary>
417 // -----------------------------------------------------------------
418 [ScriptInvocation]
419 public int JsonGetArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path)
420 {
421 return m_store.GetArrayLength(storeID,path);
422 }
423  
424 // -----------------------------------------------------------------
425 /// <summary>
426 ///
427 /// </summary>
428 // -----------------------------------------------------------------
429 [ScriptInvocation]
430 public string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path)
431 {
432 string value = String.Empty;
433 m_store.GetValue(storeID,path,false,out value);
434 return value;
435 }
436  
437 [ScriptInvocation]
438 public string JsonGetJson(UUID hostID, UUID scriptID, UUID storeID, string path)
439 {
440 string value = String.Empty;
441 m_store.GetValue(storeID,path,true, out value);
442 return value;
443 }
444  
445 // -----------------------------------------------------------------
446 /// <summary>
447 ///
448 /// </summary>
449 // -----------------------------------------------------------------
450 [ScriptInvocation]
451 public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path)
452 {
453 UUID reqID = UUID.Random();
454 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); });
455 return reqID;
456 }
457  
458 [ScriptInvocation]
459 public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
460 {
461 UUID reqID = UUID.Random();
462 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); });
463 return reqID;
464 }
465  
466 // -----------------------------------------------------------------
467 /// <summary>
468 ///
469 /// </summary>
470 // -----------------------------------------------------------------
471 [ScriptInvocation]
472 public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path)
473 {
474 UUID reqID = UUID.Random();
475 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); });
476 return reqID;
477 }
478  
479 [ScriptInvocation]
480 public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
481 {
482 UUID reqID = UUID.Random();
483 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); });
484 return reqID;
485 }
486  
487 #endregion
488  
489 // -----------------------------------------------------------------
490 /// <summary>
491 ///
492 /// </summary>
493 // -----------------------------------------------------------------
494 protected void GenerateRuntimeError(string msg)
495 {
496 m_log.InfoFormat("[JsonStore] runtime error: {0}",msg);
497 throw new Exception("JsonStore Runtime Error: " + msg);
498 }
499  
500 // -----------------------------------------------------------------
501 /// <summary>
502 ///
503 /// </summary>
504 // -----------------------------------------------------------------
505 protected void DispatchValue(UUID scriptID, UUID reqID, string value)
506 {
507 m_comms.DispatchReply(scriptID,1,value,reqID.ToString());
508 }
509  
510 // -----------------------------------------------------------------
511 /// <summary>
512 ///
513 /// </summary>
514 // -----------------------------------------------------------------
515 private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
516 {
517 try
518 {
519 m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
520 return;
521 }
522 catch (Exception e)
523 {
524 m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString());
525 }
526  
527 DispatchValue(scriptID,reqID,String.Empty);
528 }
529  
530  
531 // -----------------------------------------------------------------
532 /// <summary>
533 ///
534 /// </summary>
535 // -----------------------------------------------------------------
536 private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
537 {
538 try
539 {
540 m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
541 return;
542 }
543 catch (Exception e)
544 {
545 m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString());
546 }
547  
548 DispatchValue(scriptID,reqID,String.Empty);
549 }
550  
551 // -----------------------------------------------------------------
552 /// <summary>
553 ///
554 /// </summary>
555 // -----------------------------------------------------------------
556 private void DoJsonReadNotecard(
557 UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier)
558 {
559 UUID assetID;
560  
561 if (!UUID.TryParse(notecardIdentifier, out assetID))
562 {
563 SceneObjectPart part = m_scene.GetSceneObjectPart(hostID);
564 assetID = ScriptUtils.GetAssetIdFromItemName(part, notecardIdentifier, (int)AssetType.Notecard);
565 }
566  
567 AssetBase a = m_scene.AssetService.Get(assetID.ToString());
568 if (a == null)
569 GenerateRuntimeError(String.Format("Unable to find notecard asset {0}", assetID));
570  
571 if (a.Type != (sbyte)AssetType.Notecard)
572 GenerateRuntimeError(String.Format("Invalid notecard asset {0}", assetID));
573  
574 m_log.DebugFormat("[JsonStoreScripts]: read notecard in context {0}",storeID);
575  
576 try
577 {
578 string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data));
579 int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
580 m_comms.DispatchReply(scriptID, result, "", reqID.ToString());
581 return;
582 }
583 catch (Exception e)
584 {
585 m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message);
586 }
587  
588 GenerateRuntimeError(String.Format("Json parsing failed for {0}", assetID));
589 m_comms.DispatchReply(scriptID, 0, "", reqID.ToString());
590 }
591  
592 // -----------------------------------------------------------------
593 /// <summary>
594 ///
595 /// </summary>
596 // -----------------------------------------------------------------
597 private void DoJsonWriteNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string name)
598 {
599 string data;
600 if (! m_store.GetValue(storeID,path,true, out data))
601 {
602 m_comms.DispatchReply(scriptID,0,UUID.Zero.ToString(),reqID.ToString());
603 return;
604 }
605  
606 SceneObjectPart host = m_scene.GetSceneObjectPart(hostID);
607  
608 // Create new asset
609 UUID assetID = UUID.Random();
610 AssetBase asset = new AssetBase(assetID, name, (sbyte)AssetType.Notecard, host.OwnerID.ToString());
611 asset.Description = "Json store";
612  
613 int textLength = data.Length;
614 data = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length "
615 + textLength.ToString() + "\n" + data + "}\n";
616  
617 asset.Data = Util.UTF8.GetBytes(data);
618 m_scene.AssetService.Store(asset);
619  
620 // Create Task Entry
621 TaskInventoryItem taskItem = new TaskInventoryItem();
622  
623 taskItem.ResetIDs(host.UUID);
624 taskItem.ParentID = host.UUID;
625 taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch();
626 taskItem.Name = asset.Name;
627 taskItem.Description = asset.Description;
628 taskItem.Type = (int)AssetType.Notecard;
629 taskItem.InvType = (int)InventoryType.Notecard;
630 taskItem.OwnerID = host.OwnerID;
631 taskItem.CreatorID = host.OwnerID;
632 taskItem.BasePermissions = (uint)PermissionMask.All;
633 taskItem.CurrentPermissions = (uint)PermissionMask.All;
634 taskItem.EveryonePermissions = 0;
635 taskItem.NextPermissions = (uint)PermissionMask.All;
636 taskItem.GroupID = host.GroupID;
637 taskItem.GroupPermissions = 0;
638 taskItem.Flags = 0;
639 taskItem.PermsGranter = UUID.Zero;
640 taskItem.PermsMask = 0;
641 taskItem.AssetID = asset.FullID;
642  
643 host.Inventory.AddInventoryItem(taskItem, false);
644  
645 m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString());
646 }
647  
648 // -----------------------------------------------------------------
649 /// <summary>
650 /// Convert a list of values that are path components to a single string path
651 /// </summary>
652 // -----------------------------------------------------------------
653 protected static Regex m_ArrayPattern = new Regex("^([0-9]+|\\+)$");
654 private string ConvertList2Path(object[] pathlist)
655 {
656 string path = "";
657 for (int i = 0; i < pathlist.Length; i++)
658 {
659 string token = "";
660  
661 if (pathlist[i] is string)
662 {
663 token = pathlist[i].ToString();
664  
665 // Check to see if this is a bare number which would not be a valid
666 // identifier otherwise
667 if (m_ArrayPattern.IsMatch(token))
668 token = '[' + token + ']';
669 }
670 else if (pathlist[i] is int)
671 {
672 token = "[" + pathlist[i].ToString() + "]";
673 }
674 else
675 {
676 token = "." + pathlist[i].ToString() + ".";
677 }
678  
679 path += token + ".";
680 }
681  
682 return path;
683 }
684  
685 }
686 }