From 134f86e8d5c414409631b25b8c6f0ee45fbd8631 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Thu, 3 Nov 2016 21:44:39 +1000 Subject: Initial update to OpenSim 0.8.2.1 source code. --- .../Scripting/JsonStore/JsonStore.cs | 391 +++++++-- .../Scripting/JsonStore/JsonStoreCommands.cs | 195 +++++ .../Scripting/JsonStore/JsonStoreModule.cs | 200 ++++- .../Scripting/JsonStore/JsonStoreScriptModule.cs | 482 +++++++++-- .../JsonStore/Tests/JsonStoreScriptModuleTests.cs | 900 +++++++++++++++++++++ .../Scripting/Minimodule/MRMModule.cs | 2 + .../Scripting/Minimodule/SOPObject.cs | 2 +- .../RegionReadyModule/RegionReadyModule.cs | 19 +- .../XmlRpcRouterModule/XmlRpcGridRouterModule.cs | 1 - 9 files changed, 2013 insertions(+), 179 deletions(-) create mode 100644 OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreCommands.cs create mode 100644 OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs (limited to 'OpenSim/Region/OptionalModules/Scripting') diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 34894ba..c38bb3e 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private OSD m_ValueStore; + protected virtual OSD ValueStore { get; set; } protected class TakeValueCallbackClass { @@ -68,42 +68,141 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore protected List m_TakeStore; protected List m_ReadStore; + // add separators for quoted paths and array references + protected static Regex m_ParsePassOne = new Regex("({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])"); + // add quotes to bare identifiers which are limited to alphabetic characters + protected static Regex m_ParsePassThree = new Regex("(? + /// This is a simple estimator for the size of the stored data, it + /// is not precise, but should be close enough to implement reasonable + /// limits on the storage space used + /// + // ----------------------------------------------------------------- + public int StringSpace { get; set; } + // ----------------------------------------------------------------- /// /// /// // ----------------------------------------------------------------- - public JsonStore() : this("") {} + public static bool CanonicalPathExpression(string ipath, out string opath) + { + Stack path; + if (! ParsePathExpression(ipath,out path)) + { + opath = ""; + return false; + } + + opath = PathExpressionToKey(path); + return true; + } - public JsonStore(string value) + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public JsonStore() { + StringSpace = 0; m_TakeStore = new List(); m_ReadStore = new List(); - + } + + public JsonStore(string value) : this() + { + // This is going to throw an exception if the value is not + // a valid JSON chunk. Calling routines should catch the + // exception and handle it appropriately if (String.IsNullOrEmpty(value)) - m_ValueStore = new OSDMap(); + ValueStore = new OSDMap(); else - m_ValueStore = OSDParser.DeserializeJson(value); + ValueStore = OSDParser.DeserializeJson(value); } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public JsonStoreNodeType GetNodeType(string expr) + { + Stack path; + if (! ParsePathExpression(expr,out path)) + return JsonStoreNodeType.Undefined; + + OSD result = ProcessPathExpression(ValueStore,path); + if (result == null) + return JsonStoreNodeType.Undefined; + + if (result is OSDMap) + return JsonStoreNodeType.Object; + + if (result is OSDArray) + return JsonStoreNodeType.Array; + + if (OSDBaseType(result.Type)) + return JsonStoreNodeType.Value; + + return JsonStoreNodeType.Undefined; + } + // ----------------------------------------------------------------- /// /// /// // ----------------------------------------------------------------- - public bool TestPath(string expr, bool useJson) + public JsonStoreValueType GetValueType(string expr) { - Stack path = ParsePathExpression(expr); - OSD result = ProcessPathExpression(m_ValueStore,path); + Stack path; + if (! ParsePathExpression(expr,out path)) + return JsonStoreValueType.Undefined; + + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) - return false; + return JsonStoreValueType.Undefined; - if (useJson || result.Type == OSDType.String) - return true; + if (result is OSDMap) + return JsonStoreValueType.Undefined; - return false; + if (result is OSDArray) + return JsonStoreValueType.Undefined; + + if (result is OSDBoolean) + return JsonStoreValueType.Boolean; + + if (result is OSDInteger) + return JsonStoreValueType.Integer; + + if (result is OSDReal) + return JsonStoreValueType.Float; + + if (result is OSDString) + return JsonStoreValueType.String; + + return JsonStoreValueType.Undefined; } // ----------------------------------------------------------------- @@ -111,10 +210,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + public int ArrayLength(string expr) + { + Stack path; + if (! ParsePathExpression(expr,out path)) + return -1; + + OSD result = ProcessPathExpression(ValueStore,path); + if (result != null && result.Type == OSDType.Array) + { + OSDArray arr = result as OSDArray; + return arr.Count; + } + + return -1; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public bool GetValue(string expr, out string value, bool useJson) { - Stack path = ParsePathExpression(expr); - OSD result = ProcessPathExpression(m_ValueStore,path); + Stack path; + if (! ParsePathExpression(expr,out path)) + { + value = ""; + return false; + } + + OSD result = ProcessPathExpression(ValueStore,path); return ConvertOutputValue(result,out value,useJson); } @@ -136,7 +262,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool SetValue(string expr, string value, bool useJson) { - OSD ovalue = useJson ? OSDParser.DeserializeJson(value) : new OSDString(value); + OSD ovalue; + + // One note of caution... if you use an empty string in the + // structure it will be assumed to be a default value and will + // not be seialized in the json + + if (useJson) + { + // There doesn't appear to be a good way to determine if the + // value is valid Json other than to let the parser crash + try + { + ovalue = OSDParser.DeserializeJson(value); + } + catch (Exception) + { + if (value.StartsWith("'") && value.EndsWith("'")) + { + ovalue = new OSDString(value.Substring(1,value.Length - 2)); + } + else + { + return false; + } + } + } + else + { + ovalue = new OSDString(value); + } + return SetValueFromExpression(expr,ovalue); } @@ -147,10 +303,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool TakeValue(string expr, bool useJson, TakeValueCallback cback) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + string pexpr = PathExpressionToKey(path); - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) { m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); @@ -178,10 +337,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool ReadValue(string expr, bool useJson, TakeValueCallback cback) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + string pexpr = PathExpressionToKey(path); - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) { m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); @@ -208,25 +370,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- protected bool SetValueFromExpression(string expr, OSD ovalue) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + if (path.Count == 0) { - m_ValueStore = ovalue; + ValueStore = ovalue; + StringSpace = 0; return true; } + // pkey will be the final element in the path, we pull it out here to make sure + // that the assignment works correctly string pkey = path.Pop(); string pexpr = PathExpressionToKey(path); if (pexpr != "") pexpr += "."; - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) return false; - Regex aPattern = new Regex("\\[([0-9]+|\\+)\\]"); - MatchCollection amatches = aPattern.Matches(pkey,0); - + // Check pkey, the last element in the path, for and extract array references + MatchCollection amatches = m_ArrayPattern.Matches(pkey,0); if (amatches.Count > 0) { if (result.Type != OSDType.Array) @@ -242,8 +409,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore { string npkey = String.Format("[{0}]",amap.Count); - amap.Add(ovalue); - InvokeNextCallback(pexpr + npkey); + if (ovalue != null) + { + StringSpace += ComputeSizeOf(ovalue); + + amap.Add(ovalue); + InvokeNextCallback(pexpr + npkey); + } return true; } @@ -251,9 +423,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (0 <= aval && aval < amap.Count) { if (ovalue == null) + { + StringSpace -= ComputeSizeOf(amap[aval]); amap.RemoveAt(aval); + } else { + StringSpace -= ComputeSizeOf(amap[aval]); + StringSpace += ComputeSizeOf(ovalue); amap[aval] = ovalue; InvokeNextCallback(pexpr + pkey); } @@ -263,9 +440,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return false; } - Regex hPattern = new Regex("{([^}]+)}"); - MatchCollection hmatches = hPattern.Matches(pkey,0); - + // Check for and extract hash references + MatchCollection hmatches = m_HashPattern.Matches(pkey,0); if (hmatches.Count > 0) { Match match = hmatches[0]; @@ -274,16 +450,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (result is OSDMap) { + // this is the assignment case OSDMap hmap = result as OSDMap; if (ovalue != null) { + StringSpace -= ComputeSizeOf(hmap[hkey]); + StringSpace += ComputeSizeOf(ovalue); + hmap[hkey] = ovalue; InvokeNextCallback(pexpr + pkey); + return true; } - else if (hmap.ContainsKey(hkey)) + + // this is the remove case + if (hmap.ContainsKey(hkey)) + { + StringSpace -= ComputeSizeOf(hmap[hkey]); hmap.Remove(hkey); - - return true; + return true; + } + + return false; } return false; @@ -332,39 +519,33 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// use a stack because we process the path in inverse order later /// // ----------------------------------------------------------------- - protected static Stack ParsePathExpression(string path) + protected static bool ParsePathExpression(string expr, out Stack path) { - Stack m_path = new Stack(); + path = new Stack(); // add front and rear separators - path = "." + path + "."; + expr = "." + expr + "."; - // add separators for quoted paths - Regex pass1 = new Regex("{[^}]+}"); - path = pass1.Replace(path,".$0.",-1,0); - - // add separators for array references - Regex pass2 = new Regex("(\\[[0-9]+\\]|\\[\\+\\])"); - path = pass2.Replace(path,".$0.",-1,0); + // add separators for quoted exprs and array references + expr = m_ParsePassOne.Replace(expr,".$1.",-1,0); // add quotes to bare identifier - Regex pass3 = new Regex("\\.([a-zA-Z]+)"); - path = pass3.Replace(path,".{$1}",-1,0); + expr = m_ParsePassThree.Replace(expr,".{$1}",-1,0); // remove extra separators - Regex pass4 = new Regex("\\.+"); - path = pass4.Replace(path,".",-1,0); + expr = m_ParsePassFour.Replace(expr,".",-1,0); - Regex validate = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$"); - if (validate.IsMatch(path)) + // validate the results (catches extra quote characters for example) + if (m_ValidatePath.IsMatch(expr)) { - Regex parser = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)"); - MatchCollection matches = parser.Matches(path,0); + MatchCollection matches = m_PathComponent.Matches(expr,0); foreach (Match match in matches) - m_path.Push(match.Groups[1].Value); + path.Push(match.Groups[1].Value); + + return true; } - return m_path; + return false; } // ----------------------------------------------------------------- @@ -385,9 +566,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return null; // ---------- Check for an array index ---------- - Regex aPattern = new Regex("\\[([0-9]+)\\]"); - MatchCollection amatches = aPattern.Matches(pkey,0); - + MatchCollection amatches = m_SimpleArrayPattern.Matches(pkey,0); + if (amatches.Count > 0) { if (rmap.Type != OSDType.Array) @@ -410,9 +590,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } // ---------- Check for a hash index ---------- - Regex hPattern = new Regex("{([^}]+)}"); - MatchCollection hmatches = hPattern.Matches(pkey,0); - + MatchCollection hmatches = m_HashPattern.Matches(pkey,0); + if (hmatches.Count > 0) { if (rmap.Type != OSDType.Map) @@ -456,14 +635,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // The path pointed to an intermediate hash structure if (result.Type == OSDType.Map) { - value = OSDParser.SerializeJsonString(result as OSDMap); + value = OSDParser.SerializeJsonString(result as OSDMap,true); return true; } // The path pointed to an intermediate hash structure if (result.Type == OSDType.Array) { - value = OSDParser.SerializeJsonString(result as OSDArray); + value = OSDParser.SerializeJsonString(result as OSDArray,true); return true; } @@ -471,7 +650,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return true; } - if (result.Type == OSDType.String) + if (OSDBaseType(result.Type)) { value = result.AsString(); return true; @@ -496,5 +675,91 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return pkey; } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected static bool OSDBaseType(OSDType type) + { + // Should be the list of base types for which AsString() returns + // something useful + if (type == OSDType.Boolean) + return true; + if (type == OSDType.Integer) + return true; + if (type == OSDType.Real) + return true; + if (type == OSDType.String) + return true; + if (type == OSDType.UUID) + return true; + if (type == OSDType.Date) + return true; + if (type == OSDType.URI) + return true; + + return false; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected static int ComputeSizeOf(OSD value) + { + string sval; + + if (ConvertOutputValue(value,out sval,true)) + return sval.Length; + + return 0; + } + } + + // ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- + public class JsonObjectStore : JsonStore + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + private UUID m_objectID; + + protected override OSD ValueStore + { + get + { + SceneObjectPart sop = m_scene.GetSceneObjectPart(m_objectID); + if (sop == null) + { + // This is bad + return null; + } + + return sop.DynAttrs.TopLevelMap; + } + + // cannot set the top level + set + { + m_log.InfoFormat("[JsonStore] cannot set top level value in object store"); + } + } + + public JsonObjectStore(Scene scene, UUID oid) : base() + { + m_scene = scene; + m_objectID = oid; + + // the size limit is imposed on whatever is already in the store + StringSpace = ComputeSizeOf(ValueStore); + } } + } 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 @@ +/* + * Copyright (c) Contributors + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using Mono.Addins; + +using System; +using System.Reflection; +using System.Threading; +using System.Text; +using System.Net; +using System.Net.Sockets; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace OpenSim.Region.OptionalModules.Scripting.JsonStore +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreCommandsModule")] + + public class JsonStoreCommandsModule : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IConfig m_config = null; + private bool m_enabled = false; + + private Scene m_scene = null; + //private IJsonStoreModule m_store; + private JsonStoreModule m_store; + +#region Region Module interface + + // ----------------------------------------------------------------- + /// + /// Name of this shared module is it's class name + /// + // ----------------------------------------------------------------- + public string Name + { + get { return this.GetType().Name; } + } + + // ----------------------------------------------------------------- + /// + /// Initialise this shared module + /// + /// this region is getting initialised + /// nini config, we are not using this + // ----------------------------------------------------------------- + public void Initialise(IConfigSource config) + { + try + { + if ((m_config = config.Configs["JsonStore"]) == null) + { + // There is no configuration, the module is disabled + // m_log.InfoFormat("[JsonStore] no configuration info"); + return; + } + + m_enabled = m_config.GetBoolean("Enabled", m_enabled); + } + catch (Exception e) + { + m_log.Error("[JsonStore]: initialization error: {0}", e); + return; + } + + if (m_enabled) + m_log.DebugFormat("[JsonStore]: module is enabled"); + } + + // ----------------------------------------------------------------- + /// + /// everything is loaded, perform post load configuration + /// + // ----------------------------------------------------------------- + public void PostInitialise() + { + } + + // ----------------------------------------------------------------- + /// + /// Nothing to do on close + /// + // ----------------------------------------------------------------- + public void Close() + { + } + + // ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- + public void AddRegion(Scene scene) + { + if (m_enabled) + { + m_scene = scene; + + } + } + + // ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- + public void RemoveRegion(Scene scene) + { + // need to remove all references to the scene in the subscription + // list to enable full garbage collection of the scene object + } + + // ----------------------------------------------------------------- + /// + /// Called when all modules have been added for a region. This is + /// where we hook up events + /// + // ----------------------------------------------------------------- + public void RegionLoaded(Scene scene) + { + if (m_enabled) + { + m_scene = scene; + + m_store = (JsonStoreModule) m_scene.RequestModuleInterface(); + if (m_store == null) + { + m_log.ErrorFormat("[JsonStoreCommands]: JsonModule interface not defined"); + m_enabled = false; + return; + } + + scene.AddCommand("JsonStore", this, "jsonstore stats", "jsonstore stats", + "Display statistics about the state of the JsonStore module", "", + CmdStats); + } + } + + /// ----------------------------------------------------------------- + /// + /// + // ----------------------------------------------------------------- + public Type ReplaceableInterface + { + get { return null; } + } + +#endregion + +#region Commands + + private void CmdStats(string module, string[] cmd) + { + if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null) + return; + + JsonStoreStats stats = m_store.GetStoreStats(); + MainConsole.Instance.OutputFormat("{0}\t{1}",m_scene.RegionInfo.RegionName,stats.StoreCount); + } + +#endregion + + } +} diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs index e68764a..26044f0 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs @@ -42,7 +42,6 @@ using OpenSim.Region.Framework.Scenes; using System.Collections.Generic; using System.Text.RegularExpressions; - namespace OpenSim.Region.OptionalModules.Scripting.JsonStore { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreModule")] @@ -54,9 +53,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore private IConfig m_config = null; private bool m_enabled = false; + private bool m_enableObjectStore = false; + private int m_maxStringSpace = Int32.MaxValue; + private Scene m_scene = null; private Dictionary m_JsonValueStore; + private UUID m_sharedStore; #region Region Module interface @@ -90,15 +93,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } m_enabled = m_config.GetBoolean("Enabled", m_enabled); + m_enableObjectStore = m_config.GetBoolean("EnableObjectStore", m_enableObjectStore); + m_maxStringSpace = m_config.GetInt("MaxStringSpace", m_maxStringSpace); + if (m_maxStringSpace == 0) + m_maxStringSpace = Int32.MaxValue; } catch (Exception e) { - m_log.ErrorFormat("[JsonStore] initialization error: {0}",e.Message); + m_log.Error("[JsonStore]: initialization error: {0}", e); return; } if (m_enabled) - m_log.DebugFormat("[JsonStore] module is enabled"); + m_log.DebugFormat("[JsonStore]: module is enabled"); } // ----------------------------------------------------------------- @@ -133,6 +140,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_sharedStore = UUID.Zero; m_JsonValueStore = new Dictionary(); m_JsonValueStore.Add(m_sharedStore,new JsonStore("")); + + scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene; } } @@ -142,6 +151,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public void RemoveRegion(Scene scene) { + scene.EventManager.OnObjectBeingRemovedFromScene -= EventManagerOnObjectBeingRemovedFromScene; + // need to remove all references to the scene in the subscription // list to enable full garbage collection of the scene object } @@ -154,7 +165,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public void RegionLoaded(Scene scene) { - if (m_enabled) {} + if (m_enabled) + { + } } /// ----------------------------------------------------------------- @@ -168,8 +181,68 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore #endregion +#region SceneEvents + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public void EventManagerOnObjectBeingRemovedFromScene(SceneObjectGroup obj) + { + obj.ForEachPart(delegate(SceneObjectPart sop) { DestroyStore(sop.UUID); } ); + } + +#endregion + #region ScriptInvocationInteface + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public JsonStoreStats GetStoreStats() + { + JsonStoreStats stats; + + lock (m_JsonValueStore) + { + stats.StoreCount = m_JsonValueStore.Count; + } + + return stats; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public bool AttachObjectStore(UUID objectID) + { + if (! m_enabled) return false; + if (! m_enableObjectStore) return false; + + SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID); + if (sop == null) + { + m_log.ErrorFormat("[JsonStore] unable to attach to unknown object; {0}", objectID); + return false; + } + + lock (m_JsonValueStore) + { + if (m_JsonValueStore.ContainsKey(objectID)) + return true; + + JsonStore map = new JsonObjectStore(m_scene,objectID); + m_JsonValueStore.Add(objectID,map); + } + + return true; + } + // ----------------------------------------------------------------- /// /// @@ -189,9 +262,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore { map = new JsonStore(value); } - catch (Exception e) + catch (Exception) { - m_log.InfoFormat("[JsonStore] Unable to initialize store from {0}; {1}",value,e.Message); + m_log.ErrorFormat("[JsonStore]: Unable to initialize store from {0}", value); return false; } @@ -211,9 +284,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (! m_enabled) return false; lock (m_JsonValueStore) - m_JsonValueStore.Remove(storeID); - - return true; + return m_JsonValueStore.Remove(storeID); } // ----------------------------------------------------------------- @@ -221,31 +292,76 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public bool TestPath(UUID storeID, string path, bool useJson) + public bool TestStore(UUID storeID) { if (! m_enabled) return false; + lock (m_JsonValueStore) + return m_JsonValueStore.ContainsKey(storeID); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public JsonStoreNodeType GetNodeType(UUID storeID, string path) + { + if (! m_enabled) return JsonStoreNodeType.Undefined; + JsonStore map = null; lock (m_JsonValueStore) { if (! m_JsonValueStore.TryGetValue(storeID,out map)) { m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); - return false; + return JsonStoreNodeType.Undefined; } } try { lock (map) - return map.TestPath(path,useJson); + return map.GetNodeType(path); } catch (Exception e) { - m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message); + m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e); } - return false; + return JsonStoreNodeType.Undefined; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + public JsonStoreValueType GetValueType(UUID storeID, string path) + { + if (! m_enabled) return JsonStoreValueType.Undefined; + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + { + m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); + return JsonStoreValueType.Undefined; + } + } + + try + { + lock (map) + return map.GetValueType(path); + } + catch (Exception e) + { + m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e); + } + + return JsonStoreValueType.Undefined; } // ----------------------------------------------------------------- @@ -270,12 +386,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore try { lock (map) - if (map.SetValue(path,value,useJson)) - return true; + { + if (map.StringSpace > m_maxStringSpace) + { + m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit", + storeID,map.StringSpace,m_maxStringSpace); + return false; + } + + return map.SetValue(path,value,useJson); + } } catch (Exception e) { - m_log.InfoFormat("[JsonStore] Unable to assign {0} to {1} in {2}; {3}",value,path,storeID,e.Message); + m_log.Error(string.Format("[JsonStore]: Unable to assign {0} to {1} in {2}", value, path, storeID), e); } return false; @@ -303,12 +427,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore try { lock (map) - if (map.RemoveValue(path)) - return true; + return map.RemoveValue(path); } catch (Exception e) { - m_log.InfoFormat("[JsonStore] Unable to remove {0} in {1}; {2}",path,storeID,e.Message); + m_log.Error(string.Format("[JsonStore]: Unable to remove {0} in {1}", path, storeID), e); } return false; @@ -319,6 +442,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- + public int GetArrayLength(UUID storeID, string path) + { + if (! m_enabled) return -1; + + JsonStore map = null; + lock (m_JsonValueStore) + { + if (! m_JsonValueStore.TryGetValue(storeID,out map)) + return -1; + } + + try + { + lock (map) + { + return map.ArrayLength(path); + } + } + catch (Exception e) + { + m_log.Error("[JsonStore]: unable to retrieve value", e); + } + + return -1; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- public bool GetValue(UUID storeID, string path, bool useJson, out string value) { value = String.Empty; @@ -341,7 +495,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.Message); + m_log.Error("[JsonStore]: unable to retrieve value", e); } return false; @@ -380,7 +534,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); + m_log.Error("[JsonStore] unable to retrieve value", e); } cback(String.Empty); @@ -419,7 +573,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString()); + m_log.Error("[JsonStore]: unable to retrieve value", e); } cback(String.Empty); diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 0c175ca..edf51a2 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -39,8 +39,10 @@ using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Scripting; using System.Collections.Generic; using System.Text.RegularExpressions; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.OptionalModules.Scripting.JsonStore { @@ -57,7 +59,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore private IScriptModuleComms m_comms; private IJsonStoreModule m_store; - + + private Dictionary> m_scriptStores = new Dictionary>(); + #region Region Module interface // ----------------------------------------------------------------- @@ -92,12 +96,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore } catch (Exception e) { - m_log.ErrorFormat("[JsonStoreScripts] initialization error: {0}",e.Message); + m_log.ErrorFormat("[JsonStoreScripts]: initialization error: {0}", e.Message); return; } if (m_enabled) - m_log.DebugFormat("[JsonStoreScripts] module is enabled"); + m_log.DebugFormat("[JsonStoreScripts]: module is enabled"); } // ----------------------------------------------------------------- @@ -124,6 +128,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public void AddRegion(Scene scene) { + scene.EventManager.OnScriptReset += HandleScriptReset; + scene.EventManager.OnRemoveScript += HandleScriptReset; } // ----------------------------------------------------------------- @@ -132,12 +138,34 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public void RemoveRegion(Scene scene) { + scene.EventManager.OnScriptReset -= HandleScriptReset; + scene.EventManager.OnRemoveScript -= HandleScriptReset; + // need to remove all references to the scene in the subscription // list to enable full garbage collection of the scene object } // ----------------------------------------------------------------- /// + /// + // ----------------------------------------------------------------- + private void HandleScriptReset(uint localID, UUID itemID) + { + HashSet stores; + + lock (m_scriptStores) + { + if (! m_scriptStores.TryGetValue(itemID, out stores)) + return; + m_scriptStores.Remove(itemID); + } + + foreach (UUID id in stores) + m_store.DestroyStore(id); + } + + // ----------------------------------------------------------------- + /// /// Called when all modules have been added for a region. This is /// where we hook up events /// @@ -150,7 +178,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_comms = m_scene.RequestModuleInterface(); if (m_comms == null) { - m_log.ErrorFormat("[JsonStoreScripts] ScriptModuleComms interface not defined"); + m_log.ErrorFormat("[JsonStoreScripts]: ScriptModuleComms interface not defined"); m_enabled = false; return; } @@ -158,40 +186,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_store = m_scene.RequestModuleInterface(); if (m_store == null) { - m_log.ErrorFormat("[JsonStoreScripts] JsonModule interface not defined"); + m_log.ErrorFormat("[JsonStoreScripts]: JsonModule interface not defined"); m_enabled = false; return; } - + try { - m_comms.RegisterScriptInvocation(this,"JsonCreateStore"); - m_comms.RegisterScriptInvocation(this,"JsonDestroyStore"); - - m_comms.RegisterScriptInvocation(this,"JsonReadNotecard"); - m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard"); - - m_comms.RegisterScriptInvocation(this,"JsonTestPath"); - m_comms.RegisterScriptInvocation(this,"JsonTestPathJson"); - - m_comms.RegisterScriptInvocation(this,"JsonGetValue"); - m_comms.RegisterScriptInvocation(this,"JsonGetValueJson"); - - m_comms.RegisterScriptInvocation(this,"JsonTakeValue"); - m_comms.RegisterScriptInvocation(this,"JsonTakeValueJson"); - - m_comms.RegisterScriptInvocation(this,"JsonReadValue"); - m_comms.RegisterScriptInvocation(this,"JsonReadValueJson"); - - m_comms.RegisterScriptInvocation(this,"JsonSetValue"); - m_comms.RegisterScriptInvocation(this,"JsonSetValueJson"); - - m_comms.RegisterScriptInvocation(this,"JsonRemoveValue"); + m_comms.RegisterScriptInvocations(this); + m_comms.RegisterConstants(this); } catch (Exception e) { // See http://opensimulator.org/mantis/view.php?id=5971 for more information - m_log.WarnFormat("[JsonStroreScripts] script method registration failed; {0}",e.Message); + m_log.WarnFormat("[JsonStoreScripts]: script method registration failed; {0}", e.Message); m_enabled = false; } } @@ -208,28 +216,73 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore #endregion +#region ScriptConstantsInterface + + [ScriptConstant] + public static readonly int JSON_NODETYPE_UNDEF = (int)JsonStoreNodeType.Undefined; + + [ScriptConstant] + public static readonly int JSON_NODETYPE_OBJECT = (int)JsonStoreNodeType.Object; + + [ScriptConstant] + public static readonly int JSON_NODETYPE_ARRAY = (int)JsonStoreNodeType.Array; + + [ScriptConstant] + public static readonly int JSON_NODETYPE_VALUE = (int)JsonStoreNodeType.Value; + + [ScriptConstant] + public static readonly int JSON_VALUETYPE_UNDEF = (int)JsonStoreValueType.Undefined; + + [ScriptConstant] + public static readonly int JSON_VALUETYPE_BOOLEAN = (int)JsonStoreValueType.Boolean; + + [ScriptConstant] + public static readonly int JSON_VALUETYPE_INTEGER = (int)JsonStoreValueType.Integer; + + [ScriptConstant] + public static readonly int JSON_VALUETYPE_FLOAT = (int)JsonStoreValueType.Float; + + [ScriptConstant] + public static readonly int JSON_VALUETYPE_STRING = (int)JsonStoreValueType.String; + + +#endregion + #region ScriptInvocationInteface // ----------------------------------------------------------------- /// /// /// // ----------------------------------------------------------------- - protected void GenerateRuntimeError(string msg) + [ScriptInvocation] + public UUID JsonAttachObjectStore(UUID hostID, UUID scriptID) { - throw new Exception("JsonStore Runtime Error: " + msg); + UUID uuid = UUID.Zero; + if (! m_store.AttachObjectStore(hostID)) + GenerateRuntimeError("Failed to create Json store"); + + return hostID; } - + // ----------------------------------------------------------------- /// /// /// // ----------------------------------------------------------------- - protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) + [ScriptInvocation] + public UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) { UUID uuid = UUID.Zero; if (! m_store.CreateStore(value, ref uuid)) GenerateRuntimeError("Failed to create Json store"); + lock (m_scriptStores) + { + if (! m_scriptStores.ContainsKey(scriptID)) + m_scriptStores[scriptID] = new HashSet(); + + m_scriptStores[scriptID].Add(uuid); + } return uuid; } @@ -238,8 +291,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) + [ScriptInvocation] + public int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID) { + lock(m_scriptStores) + { + if (m_scriptStores.ContainsKey(scriptID)) + m_scriptStores[scriptID].Remove(storeID); + } + return m_store.DestroyStore(storeID) ? 1 : 0; } @@ -248,10 +308,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) + [ScriptInvocation] + public int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID) + { + return m_store.TestStore(storeID) ? 1 : 0; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + [ScriptInvocation] + public UUID JsonRezAtRoot(UUID hostID, UUID scriptID, string item, Vector3 pos, Vector3 vel, Quaternion rot, string param) + { + UUID reqID = UUID.Random(); + Util.FireAndForget( + o => DoJsonRezObject(hostID, scriptID, reqID, item, pos, vel, rot, param), null, "JsonStoreScriptModule.DoJsonRezObject"); + return reqID; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + [ScriptInvocation] + public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) { UUID reqID = UUID.Random(); - Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); }); + Util.FireAndForget( + o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier), null, "JsonStoreScriptModule.JsonReadNotecard"); return reqID; } @@ -260,10 +347,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) + [ScriptInvocation] + public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) { UUID reqID = UUID.Random(); - Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); }); + Util.FireAndForget( + o => DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name), null, "JsonStoreScriptModule.DoJsonWriteNotecard"); return reqID; } @@ -272,14 +361,41 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist) + { + string ipath = ConvertList2Path(pathlist); + string opath; + + if (JsonStore.CanonicalPathExpression(ipath,out opath)) + return opath; + + // This won't parse if passed to the other routines as opposed to + // returning an empty string which is a valid path and would overwrite + // the entire store + return "**INVALID**"; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + [ScriptInvocation] + public int JsonGetNodeType(UUID hostID, UUID scriptID, UUID storeID, string path) { - return m_store.TestPath(storeID,path,false) ? 1 : 0; + return (int)m_store.GetNodeType(storeID,path); } - protected int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path) + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + [ScriptInvocation] + public int JsonGetValueType(UUID hostID, UUID scriptID, UUID storeID, string path) { - return m_store.TestPath(storeID,path,true) ? 1 : 0; + return (int)m_store.GetValueType(storeID,path); } // ----------------------------------------------------------------- @@ -287,12 +403,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) + [ScriptInvocation] + public int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value) { return m_store.SetValue(storeID,path,value,false) ? 1 : 0; } - protected int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) + [ScriptInvocation] + public int JsonSetJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value) { return m_store.SetValue(storeID,path,value,true) ? 1 : 0; } @@ -302,7 +420,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path) { return m_store.RemoveValue(storeID,path) ? 1 : 0; } @@ -312,14 +431,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public int JsonGetArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path) + { + return m_store.GetArrayLength(storeID,path); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + [ScriptInvocation] + public string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path) { string value = String.Empty; m_store.GetValue(storeID,path,false,out value); return value; } - protected string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public string JsonGetJson(UUID hostID, UUID scriptID, UUID storeID, string path) { string value = String.Empty; m_store.GetValue(storeID,path,true, out value); @@ -331,80 +463,109 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - protected UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) { UUID reqID = UUID.Random(); - Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); }); + Util.FireAndForget( + o => DoJsonTakeValue(scriptID,reqID,storeID,path,false), null, "JsonStoreScriptModule.DoJsonTakeValue"); return reqID; } - protected UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) { UUID reqID = UUID.Random(); - Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); }); + Util.FireAndForget( + o => DoJsonTakeValue(scriptID,reqID,storeID,path,true), null, "JsonStoreScriptModule.DoJsonTakeValueJson"); return reqID; } - private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) - { - try - { - m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); - return; - } - catch (Exception e) - { - m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); - } - - DispatchValue(scriptID,reqID,String.Empty); - } - - // ----------------------------------------------------------------- /// /// /// // ----------------------------------------------------------------- - protected UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) { UUID reqID = UUID.Random(); - Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); }); + Util.FireAndForget( + o => DoJsonReadValue(scriptID,reqID,storeID,path,false), null, "JsonStoreScriptModule.DoJsonReadValue"); return reqID; } - protected UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) + [ScriptInvocation] + public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) { UUID reqID = UUID.Random(); - Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); }); + Util.FireAndForget( + o => DoJsonReadValue(scriptID,reqID,storeID,path,true), null, "JsonStoreScriptModule.DoJsonReadValueJson"); return reqID; } - private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) +#endregion + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected void GenerateRuntimeError(string msg) + { + m_log.InfoFormat("[JsonStore] runtime error: {0}",msg); + throw new Exception("JsonStore Runtime Error: " + msg); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + protected void DispatchValue(UUID scriptID, UUID reqID, string value) + { + m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) { try { - m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); + m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); return; } catch (Exception e) { - m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString()); + m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString()); } DispatchValue(scriptID,reqID,String.Empty); } -#endregion // ----------------------------------------------------------------- /// /// /// // ----------------------------------------------------------------- - protected void DispatchValue(UUID scriptID, UUID reqID, string value) + private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson) { - m_comms.DispatchReply(scriptID,1,value,reqID.ToString()); + try + { + m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); }); + return; + } + catch (Exception e) + { + m_log.InfoFormat("[JsonStoreScripts]: unable to retrieve value; {0}",e.ToString()); + } + + DispatchValue(scriptID,reqID,String.Empty); } // ----------------------------------------------------------------- @@ -412,31 +573,44 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - private void DoJsonReadNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID) + private void DoJsonReadNotecard( + UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) { + UUID assetID; + + if (!UUID.TryParse(notecardIdentifier, out assetID)) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(hostID); + assetID = ScriptUtils.GetAssetIdFromItemName(part, notecardIdentifier, (int)AssetType.Notecard); + } + AssetBase a = m_scene.AssetService.Get(assetID.ToString()); if (a == null) - GenerateRuntimeError(String.Format("Unable to find notecard asset {0}",assetID)); + GenerateRuntimeError(String.Format("Unable to find notecard asset {0}", assetID)); if (a.Type != (sbyte)AssetType.Notecard) - GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID)); + GenerateRuntimeError(String.Format("Invalid notecard asset {0}", assetID)); - m_log.DebugFormat("[JsonStoreScripts] read notecard in context {0}",storeID); + m_log.DebugFormat("[JsonStoreScripts]: read notecard in context {0}",storeID); try { - string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data)); + string jsondata = SLUtil.ParseNotecardToString(a.Data); int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0; - m_comms.DispatchReply(scriptID,result, "", reqID.ToString()); + m_comms.DispatchReply(scriptID, result, "", reqID.ToString()); return; } + catch(SLUtil.NotANotecardFormatException e) + { + m_log.WarnFormat("[JsonStoreScripts]: Notecard parsing failed; assetId {0} at line number {1}", assetID.ToString(), e.lineNumber); + } catch (Exception e) { - m_log.WarnFormat("[JsonStoreScripts] Json parsing failed; {0}",e.Message); + m_log.WarnFormat("[JsonStoreScripts]: Json parsing failed; {0}", e.Message); } - GenerateRuntimeError(String.Format("Json parsing failed for {0}",assetID.ToString())); - m_comms.DispatchReply(scriptID,0,"",reqID.ToString()); + GenerateRuntimeError(String.Format("Json parsing failed for {0}", assetID)); + m_comms.DispatchReply(scriptID, 0, "", reqID.ToString()); } // ----------------------------------------------------------------- @@ -494,5 +668,141 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); } + + // ----------------------------------------------------------------- + /// + /// Convert a list of values that are path components to a single string path + /// + // ----------------------------------------------------------------- + protected static Regex m_ArrayPattern = new Regex("^([0-9]+|\\+)$"); + private string ConvertList2Path(object[] pathlist) + { + string path = ""; + for (int i = 0; i < pathlist.Length; i++) + { + string token = ""; + + if (pathlist[i] is string) + { + token = pathlist[i].ToString(); + + // Check to see if this is a bare number which would not be a valid + // identifier otherwise + if (m_ArrayPattern.IsMatch(token)) + token = '[' + token + ']'; + } + else if (pathlist[i] is int) + { + token = "[" + pathlist[i].ToString() + "]"; + } + else + { + token = "." + pathlist[i].ToString() + "."; + } + + path += token + "."; + } + + return path; + } + + // ----------------------------------------------------------------- + /// + /// + /// + // ----------------------------------------------------------------- + private void DoJsonRezObject(UUID hostID, UUID scriptID, UUID reqID, string name, Vector3 pos, Vector3 vel, Quaternion rot, string param) + { + if (Double.IsNaN(rot.X) || Double.IsNaN(rot.Y) || Double.IsNaN(rot.Z) || Double.IsNaN(rot.W)) + { + GenerateRuntimeError("Invalid rez rotation"); + return; + } + + SceneObjectGroup host = m_scene.GetSceneObjectGroup(hostID); + if (host == null) + { + GenerateRuntimeError(String.Format("Unable to find rezzing host '{0}'",hostID)); + return; + } + + // hpos = host.RootPart.GetWorldPosition() + // float dist = (float)llVecDist(hpos, pos); + // if (dist > m_ScriptDistanceFactor * 10.0f) + // return; + + TaskInventoryItem item = host.RootPart.Inventory.GetInventoryItem(name); + if (item == null) + { + GenerateRuntimeError(String.Format("Unable to find object to rez '{0}'",name)); + return; + } + + if (item.InvType != (int)InventoryType.Object) + { + GenerateRuntimeError("Can't create requested object; object is missing from database"); + return; + } + + List objlist; + List veclist; + + bool success = host.RootPart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist); + if (! success) + { + GenerateRuntimeError("Failed to create object"); + return; + } + + int totalPrims = 0; + foreach (SceneObjectGroup group in objlist) + totalPrims += group.PrimCount; + + if (! m_scene.Permissions.CanRezObject(totalPrims, item.OwnerID, pos)) + { + GenerateRuntimeError("Not allowed to create the object"); + return; + } + + if (! m_scene.Permissions.BypassPermissions()) + { + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + host.RootPart.Inventory.RemoveInventoryItem(item.ItemID); + } + + for (int i = 0; i < objlist.Count; i++) + { + SceneObjectGroup group = objlist[i]; + Vector3 curpos = pos + veclist[i]; + + if (group.IsAttachment == false && group.RootPart.Shape.State != 0) + { + group.RootPart.AttachedPos = group.AbsolutePosition; + group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; + } + + group.FromPartID = host.RootPart.UUID; + m_scene.AddNewSceneObject(group, true, curpos, rot, vel); + + UUID storeID = group.UUID; + if (! m_store.CreateStore(param, ref storeID)) + { + GenerateRuntimeError("Unable to create jsonstore for new object"); + continue; + } + + // We can only call this after adding the scene object, since the scene object references the scene + // to find out if scripts should be activated at all. + group.RootPart.SetDieAtEdge(true); + group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3); + group.ResumeScripts(); + + group.ScheduleGroupForFullUpdate(); + + // send the reply back to the host object, use the integer param to indicate the number + // of remaining objects + m_comms.DispatchReply(scriptID, objlist.Count-i-1, group.RootPart.UUID.ToString(), reqID.ToString()); + } + } } } 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 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using log4net; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Scripting.ScriptModuleComms; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; + +namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests +{ + /// + /// Tests for inventory functions in LSL + /// + [TestFixture] + public class JsonStoreScriptModuleTests : OpenSimTestCase + { + private Scene m_scene; + private MockScriptEngine m_engine; + private ScriptModuleCommsModule m_smcm; + private JsonStoreScriptModule m_jssm; + + [TestFixtureSetUp] + public void FixtureInit() + { + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; + } + + [TestFixtureTearDown] + public void TearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression + // tests really shouldn't). + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + + [SetUp] + public override void SetUp() + { + base.SetUp(); + + IConfigSource configSource = new IniConfigSource(); + IConfig jsonStoreConfig = configSource.AddConfig("JsonStore"); + jsonStoreConfig.Set("Enabled", "true"); + + m_engine = new MockScriptEngine(); + m_smcm = new ScriptModuleCommsModule(); + JsonStoreModule jsm = new JsonStoreModule(); + m_jssm = new JsonStoreScriptModule(); + + m_scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, m_jssm); + + try + { + m_smcm.RegisterScriptInvocation(this, "DummyTestMethod"); + } + catch (ArgumentException) + { + Assert.Ignore("Ignoring test since running on .NET 3.5 or earlier."); + } + + // XXX: Unfortunately, ICommsModule currently has no way of deregistering methods. + } + + private object InvokeOp(string name, params object[] args) + { + return InvokeOpOnHost(name, UUID.Zero, args); + } + + private object InvokeOpOnHost(string name, UUID hostId, params object[] args) + { + return m_smcm.InvokeOperation(hostId, UUID.Zero, name, args); + } + + [Test] + public void TestJsonCreateStore() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + // Test blank store + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); + } + + // Test single element store + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); + } + + // Test with an integer value + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 42.15 }"); + Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); + Assert.That(value, Is.EqualTo("42.15")); + } + + // Test with an array as the root node + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "[ 'one', 'two', 'three' ]"); + Assert.That(storeId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "[1]"); + Assert.That(value, Is.EqualTo("two")); + } + } + + [Test] + public void TestJsonDestroyStore() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + int dsrv = (int)InvokeOp("JsonDestroyStore", storeId); + + Assert.That(dsrv, Is.EqualTo(1)); + + int tprv = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); + Assert.That(tprv, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); + } + + [Test] + public void TestJsonDestroyStoreNotExists() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + + int dsrv = (int)InvokeOp("JsonDestroyStore", fakeStoreId); + + Assert.That(dsrv, Is.EqualTo(0)); + } + + [Test] + public void TestJsonGetValue() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); + + { + string value = (string)InvokeOp("JsonGetValue", storeId, "Hello.World"); + Assert.That(value, Is.EqualTo("Two")); + } + + // Test get of path section instead of leaf + { + string value = (string)InvokeOp("JsonGetValue", storeId, "Hello"); + Assert.That(value, Is.EqualTo("")); + } + + // Test get of non-existing value + { + string fakeValueGet = (string)InvokeOp("JsonGetValue", storeId, "foo"); + Assert.That(fakeValueGet, Is.EqualTo("")); + } + + // Test get from non-existing store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + string fakeStoreValueGet = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueGet, Is.EqualTo("")); + } + } + + [Test] + public void TestJsonGetJson() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); + + { + string value = (string)InvokeOp("JsonGetJson", storeId, "Hello.World"); + Assert.That(value, Is.EqualTo("'Two'")); + } + + // Test get of path section instead of leaf + { + string value = (string)InvokeOp("JsonGetJson", storeId, "Hello"); + Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}")); + } + + // Test get of non-existing value + { + string fakeValueGet = (string)InvokeOp("JsonGetJson", storeId, "foo"); + Assert.That(fakeValueGet, Is.EqualTo("")); + } + + // Test get from non-existing store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + string fakeStoreValueGet = (string)InvokeOp("JsonGetJson", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueGet, Is.EqualTo("")); + } + } + +// [Test] +// public void TestJsonTakeValue() +// { +// TestHelpers.InMethod(); +//// TestHelpers.EnableLogging(); +// +// UUID storeId +// = (UUID)m_smcm.InvokeOperation( +// UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" }); +// +// string value +// = (string)m_smcm.InvokeOperation( +// UUID.Zero, UUID.Zero, "JsonTakeValue", new object[] { storeId, "Hello" }); +// +// Assert.That(value, Is.EqualTo("World")); +// +// string value2 +// = (string)m_smcm.InvokeOperation( +// UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" }); +// +// Assert.That(value, Is.Null); +// } + + [Test] + public void TestJsonRemoveValue() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + // Test remove of node in object pointing to a string + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + + int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); + Assert.That(returnValue, Is.EqualTo(1)); + + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); + + string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello"); + Assert.That(returnValue2, Is.EqualTo("")); + } + + // Test remove of node in object pointing to another object + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Wally' } }"); + + int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); + Assert.That(returnValue, Is.EqualTo(1)); + + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); + + string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello"); + Assert.That(returnValue2, Is.EqualTo("")); + } + + // Test remove of node in an array + { + UUID storeId + = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : [ 'value1', 'value2' ] }"); + + int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]"); + Assert.That(returnValue, Is.EqualTo(1)); + + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[0]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); + + result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[1]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); + + string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]"); + Assert.That(stringReturnValue, Is.EqualTo("value2")); + + stringReturnValue = (string)InvokeOp("JsonGetJson", storeId, "Hello[1]"); + Assert.That(stringReturnValue, Is.EqualTo("")); + } + + // Test remove of non-existing value + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); + + int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Cheese"); + Assert.That(fakeValueRemove, Is.EqualTo(0)); + } + + { + // Test get from non-existing store + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello"); + Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); + } + } + +// [Test] +// public void TestJsonTestPath() +// { +// TestHelpers.InMethod(); +//// TestHelpers.EnableLogging(); +// +// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); +// +// { +// int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World"); +// Assert.That(result, Is.EqualTo(1)); +// } +// +// // Test for path which does not resolve to a value. +// { +// int result = (int)InvokeOp("JsonTestPath", storeId, "Hello"); +// Assert.That(result, Is.EqualTo(0)); +// } +// +// { +// int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo"); +// Assert.That(result2, Is.EqualTo(0)); +// } +// +// // Test with fake store +// { +// UUID fakeStoreId = TestHelpers.ParseTail(0x500); +// int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello"); +// Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); +// } +// } + +// [Test] +// public void TestJsonTestPathJson() +// { +// TestHelpers.InMethod(); +//// TestHelpers.EnableLogging(); +// +// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); +// +// { +// int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World"); +// Assert.That(result, Is.EqualTo(1)); +// } +// +// // Test for path which does not resolve to a value. +// { +// int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello"); +// Assert.That(result, Is.EqualTo(1)); +// } +// +// { +// int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo"); +// Assert.That(result2, Is.EqualTo(0)); +// } +// +// // Test with fake store +// { +// UUID fakeStoreId = TestHelpers.ParseTail(0x500); +// int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello"); +// Assert.That(fakeStoreValueRemove, Is.EqualTo(0)); +// } +// } + + [Test] + public void TestJsonGetArrayLength() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); + + { + int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello.World"); + Assert.That(result, Is.EqualTo(2)); + } + + // Test path which is not an array + { + int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello"); + Assert.That(result, Is.EqualTo(-1)); + } + + // Test fake path + { + int result = (int)InvokeOp("JsonGetArrayLength", storeId, "foo"); + Assert.That(result, Is.EqualTo(-1)); + } + + // Test fake store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int result = (int)InvokeOp("JsonGetArrayLength", fakeStoreId, "Hello.World"); + Assert.That(result, Is.EqualTo(-1)); + } + } + + [Test] + public void TestJsonGetNodeType() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); + + { + int result = (int)InvokeOp("JsonGetNodeType", storeId, "."); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT)); + } + + { + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT)); + } + + { + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_ARRAY)); + } + + { + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[0]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); + } + + { + int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[1]"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE)); + } + + // Test for non-existent path + { + int result = (int)InvokeOp("JsonGetNodeType", storeId, "foo"); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); + } + + // Test for non-existent store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int result = (int)InvokeOp("JsonGetNodeType", fakeStoreId, "."); + Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF)); + } + } + + [Test] + public void TestJsonList2Path() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + // Invoking these methods directly since I just couldn't get comms module invocation to work for some reason + // - some confusion with the methods that take a params object[] invocation. + { + string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo" }); + Assert.That(result, Is.EqualTo("{foo}")); + } + + { + string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", "bar" }); + Assert.That(result, Is.EqualTo("{foo}.{bar}")); + } + + { + string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", 1, "bar" }); + Assert.That(result, Is.EqualTo("{foo}.[1].{bar}")); + } + } + + [Test] + public void TestJsonSetValue() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); + Assert.That(value, Is.EqualTo("Times")); + } + + // Test setting a key containing periods with delineation + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}"); + Assert.That(value, Is.EqualTo("Times")); + } + + // *** Test [] *** + + // Test setting a key containing unbalanced ] without delineation. Expecting failure + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun]Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun]Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting a key containing unbalanced [ without delineation. Expecting failure + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting a key containing unbalanced [] without delineation. Expecting failure + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[]Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[]Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting a key containing unbalanced ] with delineation + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun]Circus}", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun]Circus}"); + Assert.That(value, Is.EqualTo("Times")); + } + + // Test setting a key containing unbalanced [ with delineation + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[Circus}", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[Circus}"); + Assert.That(value, Is.EqualTo("Times")); + } + + // Test setting a key containing empty balanced [] with delineation + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[]Circus}", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}"); + Assert.That(value, Is.EqualTo("Times")); + } + +// // Commented out as this currently unexpectedly fails. +// // Test setting a key containing brackets around an integer with delineation +// { +// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); +// +// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[0]Circus}", "Times"); +// Assert.That(result, Is.EqualTo(1)); +// +// string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[0]Circus}"); +// Assert.That(value, Is.EqualTo("Times")); +// } + + // *** Test {} *** + + // Test setting a key containing unbalanced } without delineation. Expecting failure (?) + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun}Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting a key containing unbalanced { without delineation. Expecting failure (?) + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun{Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus"); + Assert.That(value, Is.EqualTo("")); + } + +// // Commented out as this currently unexpectedly fails. +// // Test setting a key containing unbalanced } +// { +// UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); +// +// int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun}Circus}", "Times"); +// Assert.That(result, Is.EqualTo(0)); +// } + + // Test setting a key containing unbalanced { with delineation + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Circus}", "Times"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Circus}"); + Assert.That(value, Is.EqualTo("Times")); + } + + // Test setting a key containing balanced {} with delineation. This should fail. + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Filled}Circus}", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Filled}Circus}"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting to location that does not exist. This should fail. + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); + + int result = (int)InvokeOp("JsonSetValue", storeId, "Fun.Circus", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test with fake store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueSet = (int)InvokeOp("JsonSetValue", fakeStoreId, "Hello", "World"); + Assert.That(fakeStoreValueSet, Is.EqualTo(0)); + } + } + + [Test] + public void TestJsonSetJson() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + // Single quoted token case + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + + int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "'Times'"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); + Assert.That(value, Is.EqualTo("Times")); + } + + // Sub-tree case + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + + int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "{ 'Filled' : 'Times' }"); + Assert.That(result, Is.EqualTo(1)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled"); + Assert.That(value, Is.EqualTo("Times")); + } + + // If setting single strings in JsonSetValueJson, these must be single quoted tokens, not bare strings. + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + + int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "Times"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun"); + Assert.That(value, Is.EqualTo("")); + } + + // Test setting to location that does not exist. This should fail. + { + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); + + int result = (int)InvokeOp("JsonSetJson", storeId, "Fun.Circus", "'Times'"); + Assert.That(result, Is.EqualTo(0)); + + string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus"); + Assert.That(value, Is.EqualTo("")); + } + + // Test with fake store + { + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + int fakeStoreValueSet = (int)InvokeOp("JsonSetJson", fakeStoreId, "Hello", "'World'"); + Assert.That(fakeStoreValueSet, Is.EqualTo(0)); + } + } + + /// + /// Test for writing json to a notecard + /// + /// + /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching + /// it via the MockScriptEngine or perhaps by a dummy script instance. + /// + [Test] + public void TestJsonWriteNotecard() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); + m_scene.AddSceneObject(so); + + UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); + + { + string notecardName = "nc1"; + + // Write notecard + UUID writeNotecardRequestId = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "", notecardName); + Assert.That(writeNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + TaskInventoryItem nc1Item = so.RootPart.Inventory.GetInventoryItem(notecardName); + Assert.That(nc1Item, Is.Not.Null); + + // TODO: Should independently check the contents. + } + + // TODO: Write partial test + + { + // Try to write notecard for a bad path + // In this case we do get a request id but no notecard is written. + string badPathNotecardName = "badPathNotecardName"; + + UUID writeNotecardBadPathRequestId + = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, storeId, "flibble", badPathNotecardName); + Assert.That(writeNotecardBadPathRequestId, Is.Not.EqualTo(UUID.Zero)); + + TaskInventoryItem badPathItem = so.RootPart.Inventory.GetInventoryItem(badPathNotecardName); + Assert.That(badPathItem, Is.Null); + } + + { + // Test with fake store + // In this case we do get a request id but no notecard is written. + string fakeStoreNotecardName = "fakeStoreNotecardName"; + + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + UUID fakeStoreWriteNotecardValue + = (UUID)InvokeOpOnHost("JsonWriteNotecard", so.UUID, fakeStoreId, "", fakeStoreNotecardName); + Assert.That(fakeStoreWriteNotecardValue, Is.Not.EqualTo(UUID.Zero)); + + TaskInventoryItem fakeStoreItem = so.RootPart.Inventory.GetInventoryItem(fakeStoreNotecardName); + Assert.That(fakeStoreItem, Is.Null); + } + } + + /// + /// Test for reading json from a notecard + /// + /// + /// TODO: Really needs to test correct receipt of the link_message event. Could do this by directly fetching + /// it via the MockScriptEngine or perhaps by a dummy script instance. + /// + [Test] + public void TestJsonReadNotecard() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + string notecardName = "nc1"; + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, TestHelpers.ParseTail(0x1)); + m_scene.AddSceneObject(so); + + UUID creatingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello':'World' }"); + + // Write notecard + InvokeOpOnHost("JsonWriteNotecard", so.UUID, creatingStoreId, "", notecardName); + + { + // Read notecard + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "", notecardName); + Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); + Assert.That(value, Is.EqualTo("World")); + } + + { + // Read notecard to new single component path + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make", notecardName); + Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); + Assert.That(value, Is.EqualTo("")); + + value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.Hello"); + Assert.That(value, Is.EqualTo("World")); + } + + { + // Read notecard to new multi-component path. This should not work. + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{}"); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName); + Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); + Assert.That(value, Is.EqualTo("")); + + value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello"); + Assert.That(value, Is.EqualTo("")); + } + + { + // Read notecard to existing multi-component path. This should work + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }"); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "make.it", notecardName); + Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); + Assert.That(value, Is.EqualTo("")); + + value = (string)InvokeOp("JsonGetValue", receivingStoreId, "make.it.Hello"); + Assert.That(value, Is.EqualTo("World")); + } + + { + // Read notecard to invalid path. This should not work. + UUID receivingStoreId = (UUID)InvokeOp("JsonCreateStore", "{ 'make' : { 'it' : 'so' } }"); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, receivingStoreId, "/", notecardName); + Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", receivingStoreId, "Hello"); + Assert.That(value, Is.EqualTo("")); + } + + { + // Try read notecard to fake store. + UUID fakeStoreId = TestHelpers.ParseTail(0x500); + UUID readNotecardRequestId = (UUID)InvokeOpOnHost("JsonReadNotecard", so.UUID, fakeStoreId, "", notecardName); + Assert.That(readNotecardRequestId, Is.Not.EqualTo(UUID.Zero)); + + string value = (string)InvokeOp("JsonGetValue", fakeStoreId, "Hello"); + Assert.That(value, Is.EqualTo("")); + } + } + + public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; } + } +} diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs index 6fb28e2..4bafe2f 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs @@ -180,6 +180,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule /// * Internet /// * Everything /// +#pragma warning disable 0618 public static AppDomain CreateRestrictedDomain(string permissionSetName, string appDomainName) { if (permissionSetName == null) @@ -240,6 +241,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule return restrictedDomain; } +#pragma warning restore 0618 void EventManager_OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource) diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs index 5ed1514..47b9c09 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs @@ -34,7 +34,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.OptionalModules.Scripting.Minimodule.Object; -using OpenSim.Region.Physics.Manager; +using OpenSim.Region.PhysicsModules.SharedBase; using PrimType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.PrimType; using SculptType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.SculptType; diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index c550c44..870c0bb 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -105,7 +105,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady m_scene.LoginLock = true; m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue; - m_log.InfoFormat("[RegionReady]: Region {0} - LOGINS DISABLED DURING INITIALIZATION.", m_scene.Name); + // This should always show up to the user but should not trigger warn/errors as these messages are + // expected and are not simulator problems. Ideally, there would be a status level in log4net but + // failing that, we will print out to console instead. + MainConsole.Instance.OutputFormat("Region {0} - LOGINS DISABLED DURING INITIALIZATION.", m_scene.Name); if (m_uri != string.Empty) { @@ -169,7 +172,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady c.Channel = m_channelNotify; c.Message += numScriptsFailed.ToString() + "," + message; c.Type = ChatTypeEnum.Region; - c.Position = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30); + if (m_scene != null) + c.Position = new Vector3((m_scene.RegionInfo.RegionSizeX * 0.5f), (m_scene.RegionInfo.RegionSizeY * 0.5f), 30); + else + c.Position = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30); c.Sender = null; c.SenderUUID = UUID.Zero; c.Scene = m_scene; @@ -215,8 +221,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); - m_log.InfoFormat( - "[RegionReady]: INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name); + // Putting this out to console to make it eye-catching for people who are running OpenSimulator + // without info log messages enabled. Making this a warning is arguably misleading since it isn't a + // warning, and monitor scripts looking for warn/error/fatal messages will received false positives. + // Arguably, log4net needs a status log level (like Apache). + MainConsole.Instance.OutputFormat("INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name); } m_scene.SceneGridService.InformNeighborsThatRegionisUp( @@ -297,7 +306,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady finally { if (os != null) - os.Close(); + os.Dispose(); } } } diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs index 709d389..744d1e3 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs @@ -35,7 +35,6 @@ using OpenMetaverse; using Mono.Addins; using OpenSim.Framework; -using OpenSim.Framework.Communications; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Client; -- cgit v1.1