Merge branch 'master' of /home/opensim/var/repo/opensim

integration
BlueWall 2012-04-18 15:22:03 -04:00
commit 28f0bf7f08
21 changed files with 1647 additions and 151 deletions

View File

@ -322,7 +322,7 @@ namespace OpenSim.Framework
l_EstateManagers.Remove(avatarID);
}
public bool IsEstateManager(UUID avatarID)
public bool IsEstateManagerOrOwner(UUID avatarID)
{
if (IsEstateOwner(avatarID))
return true;
@ -368,7 +368,7 @@ namespace OpenSim.Framework
public bool HasAccess(UUID user)
{
if (IsEstateManager(user))
if (IsEstateManagerOrOwner(user))
return true;
return l_EstateAccess.Contains(user);

View File

@ -227,10 +227,10 @@ namespace OpenSim.Framework.Tests
es.AddEstateManager(UUID.Zero);
es.AddEstateManager(bannedUserId);
Assert.IsTrue(es.IsEstateManager(bannedUserId), "bannedUserId should be EstateManager but isn't.");
Assert.IsTrue(es.IsEstateManagerOrOwner(bannedUserId), "bannedUserId should be EstateManager but isn't.");
es.RemoveEstateManager(bannedUserId);
Assert.IsFalse(es.IsEstateManager(bannedUserId), "bannedUserID is estateManager but shouldn't be");
Assert.IsFalse(es.IsEstateManagerOrOwner(bannedUserId), "bannedUserID is estateManager but shouldn't be");
Assert.IsFalse(es.HasAccess(bannedUserId), "bannedUserID has access but shouldn't");

View File

@ -967,7 +967,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
{
RegionHandshakeArgs args = new RegionHandshakeArgs();
args.isEstateManager = Scene.RegionInfo.EstateSettings.IsEstateManager(remoteClient.AgentId);
args.isEstateManager = Scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(remoteClient.AgentId);
if (Scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero && Scene.RegionInfo.EstateSettings.EstateOwner == remoteClient.AgentId)
args.isEstateManager = true;

View File

@ -469,7 +469,7 @@ namespace OpenSim.Region.CoreModules.World.Land
if (m_scene.Permissions.IsAdministrator(avatar))
return false;
if (m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar))
if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar))
return false;
if (avatar == LandData.OwnerID)
@ -499,7 +499,7 @@ namespace OpenSim.Region.CoreModules.World.Land
if (m_scene.Permissions.IsAdministrator(avatar))
return false;
if (m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar))
if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar))
return false;
if (avatar == LandData.OwnerID)

View File

@ -282,7 +282,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName);
sb.AppendFormat("Parent: {0}",
sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID));
sb.AppendFormat("Parts: {0}\n", !sop.IsRoot ? "1" : sop.ParentGroup.PrimCount.ToString());;
sb.AppendFormat("Link number: {0}\n", sop.LinkNum);
return sb;
}

View File

@ -503,7 +503,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
{
if (user == UUID.Zero) return false;
return m_scene.RegionInfo.EstateSettings.IsEstateManager(user);
return m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(user);
}
#endregion

View File

@ -0,0 +1,48 @@
/*
* 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 System;
using System.Reflection;
using OpenMetaverse;
namespace OpenSim.Region.Framework.Interfaces
{
public delegate void TakeValueCallback(string s);
public interface IJsonStoreModule
{
bool CreateStore(string value, out UUID result);
bool DestroyStore(UUID storeID);
bool TestPath(UUID storeID, string path, bool useJson);
bool SetValue(UUID storeID, string path, string value, bool useJson);
bool RemoveValue(UUID storeID, string path);
bool GetValue(UUID storeID, string path, bool useJson, out string value);
void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
}
}

View File

@ -91,6 +91,9 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>();
/// <summary>
/// Lock to prevent object group update, linking and delinking operations from running concurrently.
/// </summary>
private Object m_updateLock = new Object();
#endregion

View File

@ -1962,6 +1962,10 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary>
/// Link the prims in a given group to this group
/// </summary>
/// <remarks>
/// Do not call this method directly - use Scene.LinkObjects() instead to avoid races between threads.
/// FIXME: There are places where scripts call these methods directly without locking. This is a potential race condition.
/// </remarks>
/// <param name="objectGroup">The group of prims which should be linked to this group</param>
public void LinkToGroup(SceneObjectGroup objectGroup)
{
@ -2045,6 +2049,11 @@ namespace OpenSim.Region.Framework.Scenes
/// Delink the given prim from this group. The delinked prim is established as
/// an independent SceneObjectGroup.
/// </summary>
/// <remarks>
/// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
/// condition. But currently there is no
/// alternative method that does take a lonk to delink a single prim.
/// </remarks>
/// <param name="partID"></param>
/// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
public SceneObjectGroup DelinkFromGroup(uint partID)
@ -2056,6 +2065,11 @@ namespace OpenSim.Region.Framework.Scenes
/// Delink the given prim from this group. The delinked prim is established as
/// an independent SceneObjectGroup.
/// </summary>
/// <remarks>
/// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
/// condition. But currently there is no
/// alternative method that does take a lonk to delink a single prim.
/// </remarks>
/// <param name="partID"></param>
/// <param name="sendEvents"></param>
/// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
@ -2081,6 +2095,11 @@ namespace OpenSim.Region.Framework.Scenes
/// Delink the given prim from this group. The delinked prim is established as
/// an independent SceneObjectGroup.
/// </summary>
/// <remarks>
/// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
/// condition. But currently there is no
/// alternative method that does take a lonk to delink a single prim.
/// </remarks>
/// <param name="partID"></param>
/// <param name="sendEvents"></param>
/// <returns>The object group of the newly delinked prim.</returns>

View File

@ -3832,7 +3832,7 @@ namespace OpenSim.Region.Framework.Scenes
land.LandData.UserLocation != Vector3.Zero &&
land.LandData.OwnerID != m_uuid &&
(!m_scene.Permissions.IsGod(m_uuid)) &&
(!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
(!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)))
{
float curr = Vector3.Distance(AbsolutePosition, pos);
if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
@ -3852,7 +3852,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (GodLevel < 200 &&
((!m_scene.Permissions.IsGod(m_uuid) &&
!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) ||
!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
(m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
(m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
{
@ -3920,7 +3920,7 @@ namespace OpenSim.Region.Framework.Scenes
GodLevel < 200 &&
((land.LandData.OwnerID != m_uuid &&
!m_scene.Permissions.IsGod(m_uuid) &&
!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) ||
!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
(m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
(m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
{

View File

@ -44,24 +44,111 @@ namespace OpenSim.Region.Framework.Scenes.Tests
[TestFixture]
public class SceneObjectSpatialTests
{
TestScene m_scene;
UUID m_ownerId = TestHelpers.ParseTail(0x1);
[SetUp]
public void SetUp()
{
m_scene = SceneHelpers.SetupScene();
}
[Test]
public void TestGetSceneObjectGroupPosition()
{
TestHelpers.InMethod();
Vector3 position = new Vector3(10, 20, 30);
SceneObjectGroup so
= SceneHelpers.CreateSceneObject(1, m_ownerId, "obj1", 0x10);
so.AbsolutePosition = position;
m_scene.AddNewSceneObject(so, false);
Assert.That(so.AbsolutePosition, Is.EqualTo(position));
}
[Test]
public void TestGetRootPartPosition()
{
TestHelpers.InMethod();
Scene scene = SceneHelpers.SetupScene();
UUID ownerId = TestHelpers.ParseTail(0x1);
Vector3 partPosition = new Vector3(10, 20, 30);
SceneObjectGroup so
= SceneHelpers.CreateSceneObject(1, ownerId, "obj1", 0x10);
= SceneHelpers.CreateSceneObject(1, m_ownerId, "obj1", 0x10);
so.AbsolutePosition = partPosition;
scene.AddNewSceneObject(so, false);
m_scene.AddNewSceneObject(so, false);
Assert.That(so.AbsolutePosition, Is.EqualTo(partPosition));
Assert.That(so.RootPart.AbsolutePosition, Is.EqualTo(partPosition));
Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero));
Assert.That(so.RootPart.GroupPosition, Is.EqualTo(partPosition));
Assert.That(so.RootPart.GetWorldPosition(), Is.EqualTo(partPosition));
Assert.That(so.RootPart.RelativePosition, Is.EqualTo(partPosition));
Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero));
}
[Test]
public void TestGetChildPartPosition()
{
TestHelpers.InMethod();
Vector3 rootPartPosition = new Vector3(10, 20, 30);
Vector3 childOffsetPosition = new Vector3(2, 3, 4);
SceneObjectGroup so
= SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10);
so.AbsolutePosition = rootPartPosition;
so.Parts[1].OffsetPosition = childOffsetPosition;
m_scene.AddNewSceneObject(so, false);
// Calculate child absolute position.
Vector3 childPosition = new Vector3(rootPartPosition + childOffsetPosition);
SceneObjectPart childPart = so.Parts[1];
Assert.That(childPart.AbsolutePosition, Is.EqualTo(childPosition));
Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition));
Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition));
Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition));
Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition));
}
[Test]
public void TestGetChildPartPositionAfterObjectRotation()
{
TestHelpers.InMethod();
Vector3 rootPartPosition = new Vector3(10, 20, 30);
Vector3 childOffsetPosition = new Vector3(2, 3, 4);
SceneObjectGroup so
= SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10);
so.AbsolutePosition = rootPartPosition;
so.Parts[1].OffsetPosition = childOffsetPosition;
m_scene.AddNewSceneObject(so, false);
so.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 0, -90 * Utils.DEG_TO_RAD));
// Calculate child absolute position.
Vector3 rotatedChildOffsetPosition
= new Vector3(childOffsetPosition.Y, -childOffsetPosition.X, childOffsetPosition.Z);
Vector3 childPosition = new Vector3(rootPartPosition + rotatedChildOffsetPosition);
SceneObjectPart childPart = so.Parts[1];
// FIXME: Should be childPosition after rotation?
Assert.That(childPart.AbsolutePosition, Is.EqualTo(rootPartPosition + childOffsetPosition));
Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition));
Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition));
// Relative to root part as (0, 0, 0)
Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition));
// Relative to root part as (0, 0, 0)
Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition));
}
}
}

View File

@ -0,0 +1,500 @@
/*
* 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
{
public class JsonStore
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private OSD m_ValueStore;
protected class TakeValueCallbackClass
{
public string Path { get; set; }
public bool UseJson { get; set; }
public TakeValueCallback Callback { get; set; }
public TakeValueCallbackClass(string spath, bool usejson, TakeValueCallback cback)
{
Path = spath;
UseJson = usejson;
Callback = cback;
}
}
protected List<TakeValueCallbackClass> m_TakeStore;
protected List<TakeValueCallbackClass> m_ReadStore;
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public JsonStore() : this("") {}
public JsonStore(string value)
{
m_TakeStore = new List<TakeValueCallbackClass>();
m_ReadStore = new List<TakeValueCallbackClass>();
if (String.IsNullOrEmpty(value))
m_ValueStore = new OSDMap();
else
m_ValueStore = OSDParser.DeserializeJson(value);
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool TestPath(string expr, bool useJson)
{
Stack<string> path = ParsePathExpression(expr);
OSD result = ProcessPathExpression(m_ValueStore,path);
if (result == null)
return false;
if (useJson || result.Type == OSDType.String)
return true;
return false;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool GetValue(string expr, out string value, bool useJson)
{
Stack<string> path = ParsePathExpression(expr);
OSD result = ProcessPathExpression(m_ValueStore,path);
return ConvertOutputValue(result,out value,useJson);
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool RemoveValue(string expr)
{
return SetValueFromExpression(expr,null);
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool SetValue(string expr, string value, bool useJson)
{
OSD ovalue = useJson ? OSDParser.DeserializeJson(value) : new OSDString(value);
return SetValueFromExpression(expr,ovalue);
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool TakeValue(string expr, bool useJson, TakeValueCallback cback)
{
Stack<string> path = ParsePathExpression(expr);
string pexpr = PathExpressionToKey(path);
OSD result = ProcessPathExpression(m_ValueStore,path);
if (result == null)
{
m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
return false;
}
string value = String.Empty;
if (! ConvertOutputValue(result,out value,useJson))
{
// the structure does not match the request so i guess we'll wait
m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
return false;
}
SetValueFromExpression(expr,null);
cback(value);
return true;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool ReadValue(string expr, bool useJson, TakeValueCallback cback)
{
Stack<string> path = ParsePathExpression(expr);
string pexpr = PathExpressionToKey(path);
OSD result = ProcessPathExpression(m_ValueStore,path);
if (result == null)
{
m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
return false;
}
string value = String.Empty;
if (! ConvertOutputValue(result,out value,useJson))
{
// the structure does not match the request so i guess we'll wait
m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
return false;
}
cback(value);
return true;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected bool SetValueFromExpression(string expr, OSD ovalue)
{
Stack<string> path = ParsePathExpression(expr);
if (path.Count == 0)
{
m_ValueStore = ovalue;
return true;
}
string pkey = path.Pop();
string pexpr = PathExpressionToKey(path);
if (pexpr != "")
pexpr += ".";
OSD result = ProcessPathExpression(m_ValueStore,path);
if (result == null)
return false;
Regex aPattern = new Regex("\\[([0-9]+|\\+)\\]");
MatchCollection amatches = aPattern.Matches(pkey,0);
if (amatches.Count > 0)
{
if (result.Type != OSDType.Array)
return false;
OSDArray amap = result as OSDArray;
Match match = amatches[0];
GroupCollection groups = match.Groups;
string akey = groups[1].Value;
if (akey == "+")
{
string npkey = String.Format("[{0}]",amap.Count);
amap.Add(ovalue);
InvokeNextCallback(pexpr + npkey);
return true;
}
int aval = Convert.ToInt32(akey);
if (0 <= aval && aval < amap.Count)
{
if (ovalue == null)
amap.RemoveAt(aval);
else
{
amap[aval] = ovalue;
InvokeNextCallback(pexpr + pkey);
}
return true;
}
return false;
}
Regex hPattern = new Regex("{([^}]+)}");
MatchCollection hmatches = hPattern.Matches(pkey,0);
if (hmatches.Count > 0)
{
Match match = hmatches[0];
GroupCollection groups = match.Groups;
string hkey = groups[1].Value;
if (result is OSDMap)
{
OSDMap hmap = result as OSDMap;
if (ovalue != null)
{
hmap[hkey] = ovalue;
InvokeNextCallback(pexpr + pkey);
}
else if (hmap.ContainsKey(hkey))
hmap.Remove(hkey);
return true;
}
return false;
}
// Shouldn't get here if the path was checked correctly
m_log.WarnFormat("[JsonStore] invalid path expression");
return false;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected bool InvokeNextCallback(string pexpr)
{
// Process all of the reads that match the expression first
List<TakeValueCallbackClass> reads =
m_ReadStore.FindAll(delegate(TakeValueCallbackClass tb) { return pexpr.StartsWith(tb.Path); });
foreach (TakeValueCallbackClass readcb in reads)
{
m_ReadStore.Remove(readcb);
ReadValue(readcb.Path,readcb.UseJson,readcb.Callback);
}
// Process one take next
TakeValueCallbackClass takecb =
m_TakeStore.Find(delegate(TakeValueCallbackClass tb) { return pexpr.StartsWith(tb.Path); });
if (takecb != null)
{
m_TakeStore.Remove(takecb);
TakeValue(takecb.Path,takecb.UseJson,takecb.Callback);
return true;
}
return false;
}
// -----------------------------------------------------------------
/// <summary>
/// Parse the path expression and put the components into a stack. We
/// use a stack because we process the path in inverse order later
/// </summary>
// -----------------------------------------------------------------
protected static Stack<string> ParsePathExpression(string path)
{
Stack<string> m_path = new Stack<string>();
// add front and rear separators
path = "." + path + ".";
// 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 quotes to bare identifier
Regex pass3 = new Regex("\\.([a-zA-Z]+)");
path = pass3.Replace(path,".{$1}",-1,0);
// remove extra separators
Regex pass4 = new Regex("\\.+");
path = pass4.Replace(path,".",-1,0);
Regex validate = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$");
if (validate.IsMatch(path))
{
Regex parser = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)");
MatchCollection matches = parser.Matches(path,0);
foreach (Match match in matches)
m_path.Push(match.Groups[1].Value);
}
return m_path;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
/// <param>path is a stack where the top level of the path is at the bottom of the stack</param>
// -----------------------------------------------------------------
protected static OSD ProcessPathExpression(OSD map, Stack<string> path)
{
if (path.Count == 0)
return map;
string pkey = path.Pop();
OSD rmap = ProcessPathExpression(map,path);
if (rmap == null)
return null;
// ---------- Check for an array index ----------
Regex aPattern = new Regex("\\[([0-9]+)\\]");
MatchCollection amatches = aPattern.Matches(pkey,0);
if (amatches.Count > 0)
{
if (rmap.Type != OSDType.Array)
{
m_log.WarnFormat("[JsonStore] wrong type for key {2}, expecting {0}, got {1}",OSDType.Array,rmap.Type,pkey);
return null;
}
OSDArray amap = rmap as OSDArray;
Match match = amatches[0];
GroupCollection groups = match.Groups;
string akey = groups[1].Value;
int aval = Convert.ToInt32(akey);
if (aval < amap.Count)
return (OSD) amap[aval];
return null;
}
// ---------- Check for a hash index ----------
Regex hPattern = new Regex("{([^}]+)}");
MatchCollection hmatches = hPattern.Matches(pkey,0);
if (hmatches.Count > 0)
{
if (rmap.Type != OSDType.Map)
{
m_log.WarnFormat("[JsonStore] wrong type for key {2}, expecting {0}, got {1}",OSDType.Map,rmap.Type,pkey);
return null;
}
OSDMap hmap = rmap as OSDMap;
Match match = hmatches[0];
GroupCollection groups = match.Groups;
string hkey = groups[1].Value;
if (hmap.ContainsKey(hkey))
return (OSD) hmap[hkey];
return null;
}
// Shouldn't get here if the path was checked correctly
m_log.WarnFormat("[JsonStore] Path type (unknown) does not match the structure");
return null;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected static bool ConvertOutputValue(OSD result, out string value, bool useJson)
{
value = String.Empty;
// If we couldn't process the path
if (result == null)
return false;
if (useJson)
{
// The path pointed to an intermediate hash structure
if (result.Type == OSDType.Map)
{
value = OSDParser.SerializeJsonString(result as OSDMap);
return true;
}
// The path pointed to an intermediate hash structure
if (result.Type == OSDType.Array)
{
value = OSDParser.SerializeJsonString(result as OSDArray);
return true;
}
value = "'" + result.AsString() + "'";
return true;
}
if (result.Type == OSDType.String)
{
value = result.AsString();
return true;
}
return false;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected static string PathExpressionToKey(Stack<string> path)
{
if (path.Count == 0)
return "";
string pkey = "";
foreach (string k in path)
pkey = (pkey == "") ? k : (k + "." + pkey);
return pkey;
}
}
}

View File

@ -0,0 +1,430 @@
/*
* 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 = "JsonStoreModule")]
public class JsonStoreModule : INonSharedRegionModule, IJsonStoreModule
{
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 Dictionary<UUID,JsonStore> m_JsonValueStore;
private UUID m_sharedStore;
#region IRegionModule Members
// -----------------------------------------------------------------
/// <summary>
/// Name of this shared module is it's class name
/// </summary>
// -----------------------------------------------------------------
public string Name
{
get { return this.GetType().Name; }
}
// -----------------------------------------------------------------
/// <summary>
/// Initialise this shared module
/// </summary>
/// <param name="scene">this region is getting initialised</param>
/// <param name="source">nini config, we are not using this</param>
// -----------------------------------------------------------------
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.ErrorFormat("[JsonStore] initialization error: {0}",e.Message);
return;
}
if (m_enabled)
m_log.DebugFormat("[JsonStore] module is enabled");
}
// -----------------------------------------------------------------
/// <summary>
/// everything is loaded, perform post load configuration
/// </summary>
// -----------------------------------------------------------------
public void PostInitialise()
{
}
// -----------------------------------------------------------------
/// <summary>
/// Nothing to do on close
/// </summary>
// -----------------------------------------------------------------
public void Close()
{
}
// -----------------------------------------------------------------
/// <summary>
/// </summary>
// -----------------------------------------------------------------
public void AddRegion(Scene scene)
{
if (m_enabled)
{
m_scene = scene;
m_scene.RegisterModuleInterface<IJsonStoreModule>(this);
m_sharedStore = UUID.Zero;
m_JsonValueStore = new Dictionary<UUID,JsonStore>();
m_JsonValueStore.Add(m_sharedStore,new JsonStore(""));
}
}
// -----------------------------------------------------------------
/// <summary>
/// </summary>
// -----------------------------------------------------------------
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
}
// -----------------------------------------------------------------
/// <summary>
/// Called when all modules have been added for a region. This is
/// where we hook up events
/// </summary>
// -----------------------------------------------------------------
public void RegionLoaded(Scene scene)
{
if (m_enabled) {}
}
/// -----------------------------------------------------------------
/// <summary>
/// </summary>
// -----------------------------------------------------------------
public Type ReplaceableInterface
{
get { return null; }
}
#endregion
#region ScriptInvocationInteface
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool CreateStore(string value, out UUID result)
{
result = UUID.Zero;
if (! m_enabled) return false;
UUID uuid = UUID.Random();
JsonStore map = null;
try
{
map = new JsonStore(value);
}
catch (Exception e)
{
m_log.InfoFormat("[JsonStore] Unable to initialize store from {0}; {1}",value,e.Message);
return false;
}
lock (m_JsonValueStore)
m_JsonValueStore.Add(uuid,map);
result = uuid;
return true;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool DestroyStore(UUID storeID)
{
if (! m_enabled) return false;
lock (m_JsonValueStore)
m_JsonValueStore.Remove(storeID);
return true;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool TestPath(UUID storeID, string path, bool useJson)
{
if (! m_enabled) return false;
JsonStore map = null;
lock (m_JsonValueStore)
{
if (! m_JsonValueStore.TryGetValue(storeID,out map))
{
m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
return true;
}
}
try
{
lock (map)
return map.TestPath(path,useJson);
}
catch (Exception e)
{
m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message);
}
return false;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool SetValue(UUID storeID, string path, string value, bool useJson)
{
if (! m_enabled) return false;
JsonStore map = null;
lock (m_JsonValueStore)
{
if (! m_JsonValueStore.TryGetValue(storeID,out map))
{
m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
return false;
}
}
try
{
lock (map)
if (map.SetValue(path,value,useJson))
return true;
}
catch (Exception e)
{
m_log.InfoFormat("[JsonStore] Unable to assign {0} to {1} in {2}; {3}",value,path,storeID,e.Message);
}
return false;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool RemoveValue(UUID storeID, string path)
{
if (! m_enabled) return false;
JsonStore map = null;
lock (m_JsonValueStore)
{
if (! m_JsonValueStore.TryGetValue(storeID,out map))
{
m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
return false;
}
}
try
{
lock (map)
if (map.RemoveValue(path))
return true;
}
catch (Exception e)
{
m_log.InfoFormat("[JsonStore] Unable to remove {0} in {1}; {2}",path,storeID,e.Message);
}
return false;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public bool GetValue(UUID storeID, string path, bool useJson, out string value)
{
value = String.Empty;
if (! m_enabled) return false;
JsonStore map = null;
lock (m_JsonValueStore)
{
if (! m_JsonValueStore.TryGetValue(storeID,out map))
return false;
}
try
{
lock (map)
{
return map.GetValue(path, out value, useJson);
}
}
catch (Exception e)
{
m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.Message);
}
return false;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
{
if (! m_enabled)
{
cback(String.Empty);
return;
}
JsonStore map = null;
lock (m_JsonValueStore)
{
if (! m_JsonValueStore.TryGetValue(storeID,out map))
{
cback(String.Empty);
return;
}
}
try
{
lock (map)
{
map.TakeValue(path, useJson, cback);
return;
}
}
catch (Exception e)
{
m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString());
}
cback(String.Empty);
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
public void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
{
if (! m_enabled)
{
cback(String.Empty);
return;
}
JsonStore map = null;
lock (m_JsonValueStore)
{
if (! m_JsonValueStore.TryGetValue(storeID,out map))
{
cback(String.Empty);
return;
}
}
try
{
lock (map)
{
map.ReadValue(path, useJson, cback);
return;
}
}
catch (Exception e)
{
m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString());
}
cback(String.Empty);
}
#endregion
}
}

View File

@ -0,0 +1,490 @@
/*
* 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 = "JsonStoreScriptModule")]
public class JsonStoreScriptModule : 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 IScriptModuleComms m_comms;
private IJsonStoreModule m_store;
#region IRegionModule Members
// -----------------------------------------------------------------
/// <summary>
/// Name of this shared module is it's class name
/// </summary>
// -----------------------------------------------------------------
public string Name
{
get { return this.GetType().Name; }
}
// -----------------------------------------------------------------
/// <summary>
/// Initialise this shared module
/// </summary>
/// <param name="scene">this region is getting initialised</param>
/// <param name="source">nini config, we are not using this</param>
// -----------------------------------------------------------------
public void Initialise(IConfigSource config)
{
try
{
if ((m_config = config.Configs["JsonStore"]) == null)
{
// There is no configuration, the module is disabled
// m_log.InfoFormat("[JsonStoreScripts] no configuration info");
return;
}
m_enabled = m_config.GetBoolean("Enabled", m_enabled);
}
catch (Exception e)
{
m_log.ErrorFormat("[JsonStoreScripts] initialization error: {0}",e.Message);
return;
}
if (m_enabled)
m_log.DebugFormat("[JsonStoreScripts] module is enabled");
}
// -----------------------------------------------------------------
/// <summary>
/// everything is loaded, perform post load configuration
/// </summary>
// -----------------------------------------------------------------
public void PostInitialise()
{
}
// -----------------------------------------------------------------
/// <summary>
/// Nothing to do on close
/// </summary>
// -----------------------------------------------------------------
public void Close()
{
}
// -----------------------------------------------------------------
/// <summary>
/// </summary>
// -----------------------------------------------------------------
public void AddRegion(Scene scene)
{
}
// -----------------------------------------------------------------
/// <summary>
/// </summary>
// -----------------------------------------------------------------
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
}
// -----------------------------------------------------------------
/// <summary>
/// Called when all modules have been added for a region. This is
/// where we hook up events
/// </summary>
// -----------------------------------------------------------------
public void RegionLoaded(Scene scene)
{
if (m_enabled)
{
m_scene = scene;
m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>();
if (m_comms == null)
{
m_log.ErrorFormat("[JsonStoreScripts] ScriptModuleComms interface not defined");
m_enabled = false;
return;
}
m_store = m_scene.RequestModuleInterface<IJsonStoreModule>();
if (m_store == null)
{
m_log.ErrorFormat("[JsonStoreScripts] JsonModule interface not defined");
m_enabled = false;
return;
}
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");
}
}
/// -----------------------------------------------------------------
/// <summary>
/// </summary>
// -----------------------------------------------------------------
public Type ReplaceableInterface
{
get { return null; }
}
#endregion
#region ScriptInvocationInteface
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected void GenerateRuntimeError(string msg)
{
throw new Exception("JsonStore Runtime Error: " + msg);
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value)
{
UUID uuid = UUID.Zero;
if (! m_store.CreateStore(value, out uuid))
GenerateRuntimeError("Failed to create Json store");
return uuid;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID)
{
return m_store.DestroyStore(storeID) ? 1 : 0;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID)
{
UUID reqID = UUID.Random();
Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); });
return reqID;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected 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); });
return reqID;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path)
{
return m_store.TestPath(storeID,path,false) ? 1 : 0;
}
protected int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path)
{
return m_store.TestPath(storeID,path,true) ? 1 : 0;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected 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)
{
return m_store.SetValue(storeID,path,value,true) ? 1 : 0;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path)
{
return m_store.RemoveValue(storeID,path) ? 1 : 0;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected 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)
{
string value = String.Empty;
m_store.GetValue(storeID,path,true, out value);
return value;
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected 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); });
return reqID;
}
protected 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); });
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);
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected 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); });
return reqID;
}
protected 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); });
return reqID;
}
private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
{
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);
}
#endregion
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
protected void DispatchValue(UUID scriptID, UUID reqID, string value)
{
m_comms.DispatchReply(scriptID,1,value,reqID.ToString());
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
private void DoJsonReadNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID)
{
AssetBase a = m_scene.AssetService.Get(assetID.ToString());
if (a == null)
GenerateRuntimeError(String.Format("Unable to find notecard asset {0}",assetID));
if (a.Type != (sbyte)AssetType.Notecard)
GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID));
m_log.DebugFormat("[JsonStoreScripts] read notecard in context {0}",storeID);
try
{
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
string jsondata = SLUtil.ParseNotecardToString(enc.GetString(a.Data));
int result = m_store.SetValue(storeID,path,jsondata,true) ? 1 : 0;
m_comms.DispatchReply(scriptID,result,"",reqID.ToString());
return;
}
catch (Exception e)
{
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());
}
// -----------------------------------------------------------------
/// <summary>
///
/// </summary>
// -----------------------------------------------------------------
private void DoJsonWriteNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string name)
{
string data;
if (! m_store.GetValue(storeID,path,true, out data))
{
m_comms.DispatchReply(scriptID,0,UUID.Zero.ToString(),reqID.ToString());
return;
}
SceneObjectPart host = m_scene.GetSceneObjectPart(hostID);
// Create new asset
UUID assetID = UUID.Random();
AssetBase asset = new AssetBase(assetID, name, (sbyte)AssetType.Notecard, host.OwnerID.ToString());
asset.Description = "Json store";
int textLength = data.Length;
data = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length "
+ textLength.ToString() + "\n" + data + "}\n";
asset.Data = Util.UTF8.GetBytes(data);
m_scene.AssetService.Store(asset);
// Create Task Entry
TaskInventoryItem taskItem = new TaskInventoryItem();
taskItem.ResetIDs(host.UUID);
taskItem.ParentID = host.UUID;
taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch();
taskItem.Name = asset.Name;
taskItem.Description = asset.Description;
taskItem.Type = (int)AssetType.Notecard;
taskItem.InvType = (int)InventoryType.Notecard;
taskItem.OwnerID = host.OwnerID;
taskItem.CreatorID = host.OwnerID;
taskItem.BasePermissions = (uint)PermissionMask.All;
taskItem.CurrentPermissions = (uint)PermissionMask.All;
taskItem.EveryonePermissions = 0;
taskItem.NextPermissions = (uint)PermissionMask.All;
taskItem.GroupID = host.GroupID;
taskItem.GroupPermissions = 0;
taskItem.Flags = 0;
taskItem.PermsGranter = UUID.Zero;
taskItem.PermsMask = 0;
taskItem.AssetID = asset.FullID;
host.Inventory.AddInventoryItem(taskItem, false);
m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString());
}
}
}

View File

@ -38,7 +38,7 @@ using OpenMetaverse;
using System.Linq;
using System.Linq.Expressions;
namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms

View File

@ -9255,7 +9255,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// child agents have a mass of 1.0
return 1;
else
return (double)avatar.PhysicsActor.Mass;
return (double)avatar.GetMass();
}
catch (KeyNotFoundException)
{
@ -10887,7 +10887,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
bool isAccount = false;
bool isGroup = false;
if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManager(m_host.OwnerID))
if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManagerOrOwner(m_host.OwnerID))
return 0;
UUID id = new UUID();

View File

@ -449,7 +449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSShoutError("LightShare functions are not enabled.");
return 0;
}
if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
{
LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
return 0;
@ -477,7 +477,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSShoutError("LightShare functions are not enabled.");
return;
}
if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
{
LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
return;
@ -500,7 +500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSShoutError("LightShare functions are not enabled.");
return 0;
}
if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
{
LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners.");
return 0;

View File

@ -369,7 +369,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("ESTATE_MANAGER"))
{
//Only Estate Managers may use the function
if (World.RegionInfo.EstateSettings.IsEstateManager(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID)
if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID)
{
return;
}

View File

@ -1021,11 +1021,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine
AppDomain sandbox;
if (m_AppDomainLoading)
{
sandbox = AppDomain.CreateDomain(
m_Scene.RegionInfo.RegionID.ToString(),
evidence, appSetup);
m_AppDomains[appDomain].AssemblyResolve +=
new ResolveEventHandler(
AssemblyResolver.OnAssemblyResolve);
}
else
{
sandbox = AppDomain.CurrentDomain;
}
//PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
//AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
@ -1037,9 +1044,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
m_AppDomains[appDomain] = sandbox;
m_AppDomains[appDomain].AssemblyResolve +=
new ResolveEventHandler(
AssemblyResolver.OnAssemblyResolve);
m_DomainScripts[appDomain] = new List<UUID>();
}
catch (Exception e)
@ -1984,4 +1988,4 @@ namespace OpenSim.Region.ScriptEngine.XEngine
// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
}
}
}
}

View File

@ -90,7 +90,7 @@ namespace OpenSim.Region.UserStatistics
dbConn = new SqliteConnection("URI=file:LocalUserStatistics.db,version=3");
dbConn.Open();
CheckAndUpdateDatabase(dbConn);
CreateTables(dbConn);
Prototype_distributor protodep = new Prototype_distributor();
Updater_distributor updatedep = new Updater_distributor();
@ -131,7 +131,7 @@ namespace OpenSim.Region.UserStatistics
}
}
public void ReceiveClassicSimStatsPacket(SimStats stats)
private void ReceiveClassicSimStatsPacket(SimStats stats)
{
if (!enabled)
{
@ -163,7 +163,7 @@ namespace OpenSim.Region.UserStatistics
}
}
public Hashtable HandleUnknownCAPSRequest(Hashtable request)
private Hashtable HandleUnknownCAPSRequest(Hashtable request)
{
//string regpath = request["uri"].ToString();
int response_code = 200;
@ -178,7 +178,7 @@ namespace OpenSim.Region.UserStatistics
return responsedata;
}
public Hashtable HandleStatsRequest(Hashtable request)
private Hashtable HandleStatsRequest(Hashtable request)
{
lastHit = System.Environment.TickCount;
Hashtable responsedata = new Hashtable();
@ -237,36 +237,12 @@ namespace OpenSim.Region.UserStatistics
return responsedata;
}
public void CheckAndUpdateDatabase(SqliteConnection db)
{
lock (db)
{
// TODO: FIXME: implement stats migrations
const string SQL = @"SELECT * FROM migrations LIMIT 1";
using (SqliteCommand cmd = new SqliteCommand(SQL, db))
{
try
{
cmd.ExecuteNonQuery();
}
catch (SqliteSyntaxException)
{
CreateTables(db);
}
}
}
}
public void CreateTables(SqliteConnection db)
private void CreateTables(SqliteConnection db)
{
using (SqliteCommand createcmd = new SqliteCommand(SQL_STATS_TABLE_CREATE, db))
{
createcmd.ExecuteNonQuery();
createcmd.CommandText = SQL_MIGRA_TABLE_CREATE;
createcmd.ExecuteNonQuery();
}
}
@ -301,7 +277,7 @@ namespace OpenSim.Region.UserStatistics
get { return true; }
}
public void OnRegisterCaps(UUID agentID, Caps caps)
private void OnRegisterCaps(UUID agentID, Caps caps)
{
// m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
@ -316,7 +292,7 @@ namespace OpenSim.Region.UserStatistics
}));
}
public void OnDeRegisterCaps(UUID agentID, Caps caps)
private void OnDeRegisterCaps(UUID agentID, Caps caps)
{
}
@ -336,7 +312,7 @@ namespace OpenSim.Region.UserStatistics
}
}
public void OnMakeRootAgent(ScenePresence agent)
private void OnMakeRootAgent(ScenePresence agent)
{
UUID regionUUID = GetRegionUUIDFromHandle(agent.RegionHandle);
@ -365,11 +341,11 @@ namespace OpenSim.Region.UserStatistics
}
}
public void OnMakeChildAgent(ScenePresence agent)
private void OnMakeChildAgent(ScenePresence agent)
{
}
public void OnClientClosed(UUID agentID, Scene scene)
private void OnClientClosed(UUID agentID, Scene scene)
{
lock (m_sessions)
{
@ -380,7 +356,7 @@ namespace OpenSim.Region.UserStatistics
}
}
public string readLogLines(int amount)
private string readLogLines(int amount)
{
Encoding encoding = Encoding.ASCII;
int sizeOfChar = encoding.GetByteCount("\n");
@ -418,7 +394,7 @@ namespace OpenSim.Region.UserStatistics
return encoding.GetString(buffer);
}
public UUID GetRegionUUIDFromHandle(ulong regionhandle)
private UUID GetRegionUUIDFromHandle(ulong regionhandle)
{
lock (m_scenes)
{
@ -441,17 +417,17 @@ namespace OpenSim.Region.UserStatistics
/// <param name="agentID"></param>
/// <param name="caps"></param>
/// <returns></returns>
public string ViewerStatsReport(string request, string path, string param,
private string ViewerStatsReport(string request, string path, string param,
UUID agentID, Caps caps)
{
// m_log.DebugFormat("[WEB STATS MODULE]: Received viewer starts report from {0}", agentID);
UpdateUserStats(ParseViewerStats(request,agentID), dbConn);
UpdateUserStats(ParseViewerStats(request, agentID), dbConn);
return String.Empty;
}
public UserSessionID ParseViewerStats(string request, UUID agentID)
private UserSessionID ParseViewerStats(string request, UUID agentID)
{
UserSessionID uid = new UserSessionID();
UserSessionData usd;
@ -592,14 +568,14 @@ namespace OpenSim.Region.UserStatistics
return uid;
}
public void UpdateUserStats(UserSessionID uid, SqliteConnection db)
private void UpdateUserStats(UserSessionID uid, SqliteConnection db)
{
if (uid.session_id == UUID.Zero)
return;
lock (db)
{
using (SqliteCommand updatecmd = new SqliteCommand(SQL_STATS_TABLE_UPDATE, db))
using (SqliteCommand updatecmd = new SqliteCommand(SQL_STATS_TABLE_INSERT, db))
{
updatecmd.Parameters.Add(new SqliteParameter(":session_id", uid.session_data.session_id.ToString()));
updatecmd.Parameters.Add(new SqliteParameter(":agent_id", uid.session_data.agent_id.ToString()));
@ -648,44 +624,26 @@ namespace OpenSim.Region.UserStatistics
updatecmd.Parameters.Add(new SqliteParameter(":f_dropped", uid.session_data.f_dropped));
updatecmd.Parameters.Add(new SqliteParameter(":f_failed_resends", uid.session_data.f_failed_resends));
updatecmd.Parameters.Add(new SqliteParameter(":f_invalid", uid.session_data.f_invalid));
updatecmd.Parameters.Add(new SqliteParameter(":f_off_circuit", uid.session_data.f_off_circuit));
updatecmd.Parameters.Add(new SqliteParameter(":f_resent", uid.session_data.f_resent));
updatecmd.Parameters.Add(new SqliteParameter(":f_send_packet", uid.session_data.f_send_packet));
updatecmd.Parameters.Add(new SqliteParameter(":session_key", uid.session_data.session_id.ToString()));
updatecmd.Parameters.Add(new SqliteParameter(":agent_key", uid.session_data.agent_id.ToString()));
updatecmd.Parameters.Add(new SqliteParameter(":region_key", uid.session_data.region_id.ToString()));
// StringBuilder parameters = new StringBuilder();
// SqliteParameterCollection spc = updatecmd.Parameters;
// foreach (SqliteParameter sp in spc)
// parameters.AppendFormat("{0}={1},", sp.ParameterName, sp.Value);
//
// m_log.DebugFormat("[WEB STATS MODULE]: Parameters {0}", parameters);
// m_log.DebugFormat("[WEB STATS MODULE]: Database stats update for {0}", uid.session_data.agent_id);
int result = updatecmd.ExecuteNonQuery();
if (result == 0)
{
// m_log.DebugFormat("[WEB STATS MODULE]: Database stats insert for {0}", uid.session_data.agent_id);
updatecmd.CommandText = SQL_STATS_TABLE_INSERT;
try
{
updatecmd.ExecuteNonQuery();
}
catch (Exception e)
{
m_log.WarnFormat(
"[WEB STATS MODULE]: failed to write stats for {0}, storage Execution Exception {1}{2}",
uid.session_data.agent_id, e.Message, e.StackTrace);
}
}
updatecmd.ExecuteNonQuery();
}
}
}
#region SQL
private const string SQL_MIGRA_TABLE_CREATE = @"create table migrations(name varchar(100), version int)";
private const string SQL_STATS_TABLE_CREATE = @"CREATE TABLE stats_session_data (
private const string SQL_STATS_TABLE_CREATE = @"CREATE TABLE IF NOT EXISTS stats_session_data (
session_id VARCHAR(36) NOT NULL PRIMARY KEY,
agent_id VARCHAR(36) NOT NULL DEFAULT '',
region_id VARCHAR(36) NOT NULL DEFAULT '',
@ -735,11 +693,11 @@ namespace OpenSim.Region.UserStatistics
f_send_packet INT NOT NULL DEFAULT '0'
);";
private const string SQL_STATS_TABLE_INSERT = @"INSERT INTO stats_session_data (
private const string SQL_STATS_TABLE_INSERT = @"INSERT OR REPLACE INTO stats_session_data (
session_id, agent_id, region_id, last_updated, remote_ip, name_f, name_l, avg_agents_in_view, min_agents_in_view, max_agents_in_view,
mode_agents_in_view, avg_fps, min_fps, max_fps, mode_fps, a_language, mem_use, meters_traveled, avg_ping, min_ping, max_ping, mode_ping,
regions_visited, run_time, avg_sim_fps, min_sim_fps, max_sim_fps, mode_sim_fps, start_time, client_version, s_cpu, s_gpu, s_os, s_ram,
d_object_kb, d_texture_kb, n_in_kb, n_in_pk, n_out_kb, n_out_pk, f_dropped, f_failed_resends, f_invalid, f_invalid, f_off_circuit,
d_object_kb, d_texture_kb, d_world_kb, n_in_kb, n_in_pk, n_out_kb, n_out_pk, f_dropped, f_failed_resends, f_invalid, f_off_circuit,
f_resent, f_send_packet
)
VALUES
@ -747,62 +705,13 @@ VALUES
:session_id, :agent_id, :region_id, :last_updated, :remote_ip, :name_f, :name_l, :avg_agents_in_view, :min_agents_in_view, :max_agents_in_view,
:mode_agents_in_view, :avg_fps, :min_fps, :max_fps, :mode_fps, :a_language, :mem_use, :meters_traveled, :avg_ping, :min_ping, :max_ping, :mode_ping,
:regions_visited, :run_time, :avg_sim_fps, :min_sim_fps, :max_sim_fps, :mode_sim_fps, :start_time, :client_version, :s_cpu, :s_gpu, :s_os, :s_ram,
:d_object_kb, :d_texture_kb, :n_in_kb, :n_in_pk, :n_out_kb, :n_out_pk, :f_dropped, :f_failed_resends, :f_invalid, :f_invalid, :f_off_circuit,
:d_object_kb, :d_texture_kb, :d_world_kb, :n_in_kb, :n_in_pk, :n_out_kb, :n_out_pk, :f_dropped, :f_failed_resends, :f_invalid, :f_off_circuit,
:f_resent, :f_send_packet
)
";
private const string SQL_STATS_TABLE_UPDATE = @"
UPDATE stats_session_data
set session_id=:session_id,
agent_id=:agent_id,
region_id=:region_id,
last_updated=:last_updated,
remote_ip=:remote_ip,
name_f=:name_f,
name_l=:name_l,
avg_agents_in_view=:avg_agents_in_view,
min_agents_in_view=:min_agents_in_view,
max_agents_in_view=:max_agents_in_view,
mode_agents_in_view=:mode_agents_in_view,
avg_fps=:avg_fps,
min_fps=:min_fps,
max_fps=:max_fps,
mode_fps=:mode_fps,
a_language=:a_language,
mem_use=:mem_use,
meters_traveled=:meters_traveled,
avg_ping=:avg_ping,
min_ping=:min_ping,
max_ping=:max_ping,
mode_ping=:mode_ping,
regions_visited=:regions_visited,
run_time=:run_time,
avg_sim_fps=:avg_sim_fps,
min_sim_fps=:min_sim_fps,
max_sim_fps=:max_sim_fps,
mode_sim_fps=:mode_sim_fps,
start_time=:start_time,
client_version=:client_version,
s_cpu=:s_cpu,
s_gpu=:s_gpu,
s_os=:s_os,
s_ram=:s_ram,
d_object_kb=:d_object_kb,
d_texture_kb=:d_texture_kb,
d_world_kb=:d_world_kb,
n_in_kb=:n_in_kb,
n_in_pk=:n_in_pk,
n_out_kb=:n_out_kb,
n_out_pk=:n_out_pk,
f_dropped=:f_dropped,
f_failed_resends=:f_failed_resends,
f_invalid=:f_invalid,
f_off_circuit=:f_off_circuit,
f_resent=:f_resent,
f_send_packet=:f_send_packet
WHERE session_id=:session_key AND agent_id=:agent_key AND region_id=:region_key";
#endregion
#endregion
}
public static class UserSessionUtil

View File

@ -1560,6 +1560,12 @@
MaptileURL = "http://www.mygrid.com/Grid/"
RefreshTime = 3600
;;
;; JsonStore module provides structured store for scripts
;;
[JsonStore]
Enabled = False
;;
;; These are defaults that are overwritten below in [Architecture].
;; These defaults allow OpenSim to work out of the box with