Merge branch 'master' of ssh://justincc@opensimulator.org/var/git/opensim
						commit
						a1e688bdf3
					
				| 
						 | 
				
			
			@ -48,7 +48,7 @@ namespace OpenSim.Data
 | 
			
		|||
    public interface IRegionData
 | 
			
		||||
    {
 | 
			
		||||
        RegionData Get(UUID regionID, UUID ScopeID);
 | 
			
		||||
        RegionData Get(string regionName, UUID ScopeID);
 | 
			
		||||
        List<RegionData> Get(string regionName, UUID ScopeID);
 | 
			
		||||
        RegionData Get(int x, int y, UUID ScopeID);
 | 
			
		||||
        List<RegionData> Get(int xStart, int yStart, int xEnd, int yEnd, UUID ScopeID);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
BEGIN;
 | 
			
		||||
 | 
			
		||||
ALTER TABLE regions add column ScopeID char(36) not null default '00000000-0000-0000-0000-000000000000';
 | 
			
		||||
 | 
			
		||||
create index ScopeID on regions(ScopeID);
 | 
			
		||||
 | 
			
		||||
COMMIT;
 | 
			
		||||
| 
						 | 
				
			
			@ -178,25 +178,38 @@ namespace OpenSim.Data.NHibernate
 | 
			
		|||
 | 
			
		||||
        private SceneObjectGroup LoadObject(UUID uuid, UUID region)
 | 
			
		||||
        {
 | 
			
		||||
            SceneObjectGroup group = new SceneObjectGroup();
 | 
			
		||||
 | 
			
		||||
            ICriteria criteria = manager.GetSession().CreateCriteria(typeof(SceneObjectPart));
 | 
			
		||||
            criteria.Add(Expression.Eq("RegionID", region));
 | 
			
		||||
            criteria.Add(Expression.Eq("ParentUUID", uuid));
 | 
			
		||||
            criteria.AddOrder(Order.Asc("ParentID"));
 | 
			
		||||
 | 
			
		||||
            foreach (SceneObjectPart p in criteria.List())
 | 
			
		||||
            IList<SceneObjectPart> parts = criteria.List<SceneObjectPart>();
 | 
			
		||||
 | 
			
		||||
            SceneObjectGroup group = null;
 | 
			
		||||
 | 
			
		||||
            // Find the root part
 | 
			
		||||
            for (int i = 0; i < parts.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                // root part
 | 
			
		||||
                if (p.UUID == uuid)
 | 
			
		||||
                if (parts[i].UUID == uuid)
 | 
			
		||||
                {
 | 
			
		||||
                    group.SetRootPart(p);
 | 
			
		||||
                    group = new SceneObjectGroup(parts[i]);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Add the children parts
 | 
			
		||||
            if (group != null)
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < parts.Count; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    group.AddPart(p);
 | 
			
		||||
                    if (parts[i].UUID != uuid)
 | 
			
		||||
                        group.AddPart(parts[i]);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                m_log.Error("[NHIBERNATE]: LoadObject() Attempted to load a SceneObjectGroup with no root SceneObjectPart ");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return group;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -237,8 +250,7 @@ namespace OpenSim.Data.NHibernate
 | 
			
		|||
                // root part
 | 
			
		||||
                if (p.UUID == p.ParentUUID)
 | 
			
		||||
                {
 | 
			
		||||
                    SceneObjectGroup group = new SceneObjectGroup();
 | 
			
		||||
                    group.SetRootPart(p);
 | 
			
		||||
                    SceneObjectGroup group = new SceneObjectGroup(p);
 | 
			
		||||
                    SOG.Add(p.ParentUUID, group);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,136 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Data;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.Null
 | 
			
		||||
{
 | 
			
		||||
    public class NullRegionData : IRegionData
 | 
			
		||||
    {
 | 
			
		||||
        Dictionary<UUID, RegionData> m_regionData = new Dictionary<UUID, RegionData>();
 | 
			
		||||
 | 
			
		||||
        public NullRegionData(string connectionString, string realm)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<RegionData> Get(string regionName, UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            List<RegionData> ret = new List<RegionData>();
 | 
			
		||||
 | 
			
		||||
            foreach(RegionData r in m_regionData.Values)
 | 
			
		||||
            {
 | 
			
		||||
                if (regionName.Contains("%"))
 | 
			
		||||
                {
 | 
			
		||||
                    if (r.RegionName.Contains(regionName.Replace("%", "")))
 | 
			
		||||
                        ret.Add(r);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (r.RegionName == regionName)
 | 
			
		||||
                        ret.Add(r);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (ret.Count > 0)
 | 
			
		||||
                return ret;
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public RegionData Get(int posX, int posY, UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            List<RegionData> ret = new List<RegionData>();
 | 
			
		||||
 | 
			
		||||
            foreach(RegionData r in m_regionData.Values)
 | 
			
		||||
            {
 | 
			
		||||
                if (r.posX == posX && r.posY == posY)
 | 
			
		||||
                    ret.Add(r);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (ret.Count > 0)
 | 
			
		||||
                return ret[0];
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public RegionData Get(UUID regionID, UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            if (m_regionData.ContainsKey(regionID))
 | 
			
		||||
                return m_regionData[regionID];
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            List<RegionData> ret = new List<RegionData>();
 | 
			
		||||
 | 
			
		||||
            foreach(RegionData r in m_regionData.Values)
 | 
			
		||||
            {
 | 
			
		||||
                if (r.posX >= startX && r.posX <= endX && r.posY >= startY && r.posY <= endY)
 | 
			
		||||
                    ret.Add(r);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (ret.Count > 0)
 | 
			
		||||
                return ret;
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Store(RegionData data)
 | 
			
		||||
        {
 | 
			
		||||
            m_regionData[data.RegionID] = data;
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool SetDataItem(UUID regionID, string item, string value)
 | 
			
		||||
        {
 | 
			
		||||
            if (!m_regionData.ContainsKey(regionID))
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            m_regionData[regionID].Data[item] = value;
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Delete(UUID regionID)
 | 
			
		||||
        {
 | 
			
		||||
            if (!m_regionData.ContainsKey(regionID))
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            m_regionData.Remove(regionID);
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -416,7 +416,6 @@ namespace OpenSim.Data.SQLite
 | 
			
		|||
                        
 | 
			
		||||
                        if (uuid == objID) //is new SceneObjectGroup ?
 | 
			
		||||
                        {
 | 
			
		||||
                            SceneObjectGroup group = new SceneObjectGroup();
 | 
			
		||||
                            prim = buildPrim(primRow);
 | 
			
		||||
                            DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
 | 
			
		||||
                            if (shapeRow != null)
 | 
			
		||||
| 
						 | 
				
			
			@ -430,7 +429,7 @@ namespace OpenSim.Data.SQLite
 | 
			
		|||
                                prim.Shape = PrimitiveBaseShape.Default;
 | 
			
		||||
                            }
 | 
			
		||||
                            
 | 
			
		||||
                            group.SetRootPart(prim);
 | 
			
		||||
                            SceneObjectGroup group = new SceneObjectGroup(prim);
 | 
			
		||||
                            createdObjects.Add(group.UUID, group);
 | 
			
		||||
                            retvals.Add(group);
 | 
			
		||||
                            LoadItems(prim);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -322,9 +322,8 @@ namespace OpenSim.Data.Tests
 | 
			
		|||
            // This is necessary or object will not be inserted in DB            
 | 
			
		||||
            sop.ObjectFlags = 0;
 | 
			
		||||
 | 
			
		||||
            SceneObjectGroup sog = new SceneObjectGroup();
 | 
			
		||||
            SceneObjectGroup sog = new SceneObjectGroup(sop);
 | 
			
		||||
            sog.SetScene(scene); // Reguired by nhibernate database module.
 | 
			
		||||
            sog.SetRootPart(sop);
 | 
			
		||||
            
 | 
			
		||||
            // Inserts group in DB
 | 
			
		||||
            db.StoreObject(sog,region3);
 | 
			
		||||
| 
						 | 
				
			
			@ -1003,9 +1002,8 @@ namespace OpenSim.Data.Tests
 | 
			
		|||
            sop.UUID = uuid;
 | 
			
		||||
            sop.Shape = PrimitiveBaseShape.Default;
 | 
			
		||||
 | 
			
		||||
            SceneObjectGroup sog = new SceneObjectGroup();
 | 
			
		||||
            SceneObjectGroup sog = new SceneObjectGroup(sop);
 | 
			
		||||
            sog.SetScene(scene);
 | 
			
		||||
            sog.SetRootPart(sop); 
 | 
			
		||||
 | 
			
		||||
            return sog;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,205 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Framework.Statistics;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Framework.Servers
 | 
			
		||||
{
 | 
			
		||||
    public abstract class BaseGetAssetStreamHandler : BaseStreamHandler
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        protected BaseGetAssetStreamHandler(string httpMethod, string path) : base(httpMethod, path)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected abstract AssetBase GetAsset(UUID assetID);
 | 
			
		||||
 | 
			
		||||
        public override byte[] Handle(string path, Stream request,
 | 
			
		||||
                                      OSHttpRequest httpRequest, OSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] result = new byte[] { };
 | 
			
		||||
 | 
			
		||||
            string[] p = SplitParams(path);
 | 
			
		||||
 | 
			
		||||
            if (p.Length > 0)
 | 
			
		||||
            {
 | 
			
		||||
                UUID assetID;
 | 
			
		||||
                
 | 
			
		||||
                if (!UUID.TryParse(p[0], out assetID))
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.DebugFormat(
 | 
			
		||||
                        "[REST]: GET:/asset ignoring request with malformed UUID {0}", p[0]);
 | 
			
		||||
                    return result;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (StatsManager.AssetStats != null)
 | 
			
		||||
                {
 | 
			
		||||
                    StatsManager.AssetStats.AddRequest();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                AssetBase asset = GetAsset(assetID); 
 | 
			
		||||
 | 
			
		||||
                if (asset != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (p.Length > 1 && p[1] == "data")
 | 
			
		||||
                    {
 | 
			
		||||
                        httpResponse.StatusCode = (int)HttpStatusCode.OK;
 | 
			
		||||
                        httpResponse.ContentType = SLAssetTypeToContentType(asset.Type);
 | 
			
		||||
                        result = asset.Data;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        result = GetXml(asset);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.DebugFormat("[REST]: GET:/asset failed to find {0}", assetID);
 | 
			
		||||
                    
 | 
			
		||||
                    httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
 | 
			
		||||
                    
 | 
			
		||||
                    if (StatsManager.AssetStats != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        StatsManager.AssetStats.AddNotFoundRequest();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static byte[] GetXml(AssetBase asset)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] result;
 | 
			
		||||
            XmlSerializer xs = new XmlSerializer(typeof(AssetBase));
 | 
			
		||||
            MemoryStream ms = new MemoryStream();
 | 
			
		||||
            XmlTextWriter xw = new XmlTextWriter(ms, Encoding.UTF8);
 | 
			
		||||
            xw.Formatting = Formatting.Indented;
 | 
			
		||||
            xs.Serialize(xw, asset);
 | 
			
		||||
            xw.Flush();
 | 
			
		||||
 | 
			
		||||
            ms.Seek(0, SeekOrigin.Begin);
 | 
			
		||||
            //StreamReader sr = new StreamReader(ms);
 | 
			
		||||
 | 
			
		||||
            result = ms.GetBuffer();
 | 
			
		||||
 | 
			
		||||
            Array.Resize<byte>(ref result, (int)ms.Length);
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string ProcessAssetDataString(string data)
 | 
			
		||||
        {
 | 
			
		||||
            Regex regex = new Regex("(creator_id|owner_id)\\s+(\\S+)");
 | 
			
		||||
 | 
			
		||||
            // IUserService userService = null;
 | 
			
		||||
 | 
			
		||||
            data = regex.Replace(data, delegate(Match m)
 | 
			
		||||
                                           {
 | 
			
		||||
                                               string result = String.Empty;
 | 
			
		||||
 | 
			
		||||
//                string key = m.Groups[1].Captures[0].Value;
 | 
			
		||||
//
 | 
			
		||||
//                string value = m.Groups[2].Captures[0].Value;
 | 
			
		||||
//
 | 
			
		||||
//                Guid userUri;
 | 
			
		||||
//
 | 
			
		||||
//                switch (key)
 | 
			
		||||
//                {
 | 
			
		||||
//                    case "creator_id":
 | 
			
		||||
//                        userUri = new Guid(value);
 | 
			
		||||
//                        //         result = "creator_url " + userService(userService, userUri);
 | 
			
		||||
//                        break;
 | 
			
		||||
//
 | 
			
		||||
//                    case "owner_id":
 | 
			
		||||
//                        userUri = new Guid(value);
 | 
			
		||||
//                        //       result = "owner_url " + ResolveUserUri(userService, userUri);
 | 
			
		||||
//                        break;
 | 
			
		||||
//                }
 | 
			
		||||
 | 
			
		||||
                                               return result;
 | 
			
		||||
                                           });
 | 
			
		||||
 | 
			
		||||
            return data;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string SLAssetTypeToContentType(int assetType)
 | 
			
		||||
        {
 | 
			
		||||
            switch (assetType)
 | 
			
		||||
            {
 | 
			
		||||
                case 0:
 | 
			
		||||
                    return "image/jp2";
 | 
			
		||||
                case 1:
 | 
			
		||||
                    return "application/ogg";
 | 
			
		||||
                case 2:
 | 
			
		||||
                    return "application/x-metaverse-callingcard";
 | 
			
		||||
                case 3:
 | 
			
		||||
                    return "application/x-metaverse-landmark";
 | 
			
		||||
                case 5:
 | 
			
		||||
                    return "application/x-metaverse-clothing";
 | 
			
		||||
                case 6:
 | 
			
		||||
                    return "application/x-metaverse-primitive";
 | 
			
		||||
                case 7:
 | 
			
		||||
                    return "application/x-metaverse-notecard";
 | 
			
		||||
                case 8:
 | 
			
		||||
                    return "application/x-metaverse-folder";
 | 
			
		||||
                case 10:
 | 
			
		||||
                    return "application/x-metaverse-lsl";
 | 
			
		||||
                case 11:
 | 
			
		||||
                    return "application/x-metaverse-lso";
 | 
			
		||||
                case 12:
 | 
			
		||||
                    return "image/tga";
 | 
			
		||||
                case 13:
 | 
			
		||||
                    return "application/x-metaverse-bodypart";
 | 
			
		||||
                case 17:
 | 
			
		||||
                    return "audio/x-wav";
 | 
			
		||||
                case 19:
 | 
			
		||||
                    return "image/jpeg";
 | 
			
		||||
                case 20:
 | 
			
		||||
                    return "application/x-metaverse-animation";
 | 
			
		||||
                case 21:
 | 
			
		||||
                    return "application/x-metaverse-gesture";
 | 
			
		||||
                case 22:
 | 
			
		||||
                    return "application/x-metaverse-simstate";
 | 
			
		||||
                default:
 | 
			
		||||
                    return "application/octet-stream";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,72 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Data;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Framework.Servers
 | 
			
		||||
{
 | 
			
		||||
    public class PostAssetStreamHandler : BaseStreamHandler
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        // private OpenAsset_Main m_assetManager;
 | 
			
		||||
        private IAssetDataPlugin m_assetProvider;
 | 
			
		||||
 | 
			
		||||
        public override byte[] Handle(string path, Stream request,
 | 
			
		||||
                                      OSHttpRequest httpRequest, OSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
            string param = GetParam(path);
 | 
			
		||||
 | 
			
		||||
            UUID assetId;
 | 
			
		||||
            if (param.Length > 0)
 | 
			
		||||
                UUID.TryParse(param, out assetId);
 | 
			
		||||
            // byte[] txBuffer = new byte[4096];
 | 
			
		||||
 | 
			
		||||
            XmlSerializer xs = new XmlSerializer(typeof (AssetBase));
 | 
			
		||||
            AssetBase asset = (AssetBase) xs.Deserialize(request);
 | 
			
		||||
 | 
			
		||||
            m_log.InfoFormat("[REST]: Creating asset {0}", asset.FullID);
 | 
			
		||||
            m_assetProvider.StoreAsset(asset);
 | 
			
		||||
 | 
			
		||||
            return new byte[] {};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public PostAssetStreamHandler(IAssetDataPlugin assetProvider)
 | 
			
		||||
            : base("POST", "/assets")
 | 
			
		||||
        {
 | 
			
		||||
            // m_assetManager = assetManager;
 | 
			
		||||
            m_assetProvider = assetProvider;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,135 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Net;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using HttpServer;
 | 
			
		||||
using NUnit.Framework;
 | 
			
		||||
using OpenSim.Data;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Tests.Common;
 | 
			
		||||
using OpenSim.Tests.Common.Mock;
 | 
			
		||||
using OpenSim.Tests.Common.Setup;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Framework.Servers.Tests
 | 
			
		||||
{
 | 
			
		||||
    [TestFixture]
 | 
			
		||||
    public class GetAssetStreamHandlerTests
 | 
			
		||||
    {
 | 
			
		||||
        private const string ASSETS_PATH = "/assets";
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void TestConstructor()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelper.InMethod();
 | 
			
		||||
 | 
			
		||||
            // GetAssetStreamHandler handler = 
 | 
			
		||||
            new GetAssetStreamHandler(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void TestGetParams()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelper.InMethod();
 | 
			
		||||
 | 
			
		||||
            GetAssetStreamHandler handler = new GetAssetStreamHandler(null);
 | 
			
		||||
            BaseRequestHandlerTestHelper.BaseTestGetParams(handler, ASSETS_PATH);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void TestSplitParams()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelper.InMethod();
 | 
			
		||||
 | 
			
		||||
            GetAssetStreamHandler handler = new GetAssetStreamHandler(null);
 | 
			
		||||
            BaseRequestHandlerTestHelper.BaseTestSplitParams(handler, ASSETS_PATH);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void TestHandleNoParams()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelper.InMethod();
 | 
			
		||||
 | 
			
		||||
            GetAssetStreamHandler handler = new GetAssetStreamHandler(null);
 | 
			
		||||
 | 
			
		||||
            BaseRequestHandlerTestHelper.BaseTestHandleNoParams(handler, ASSETS_PATH);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void TestHandleMalformedGuid()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelper.InMethod();
 | 
			
		||||
 | 
			
		||||
            GetAssetStreamHandler handler = new GetAssetStreamHandler(null);
 | 
			
		||||
 | 
			
		||||
            BaseRequestHandlerTestHelper.BaseTestHandleMalformedGuid(handler, ASSETS_PATH);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void TestHandleFetchMissingAsset()
 | 
			
		||||
        {
 | 
			
		||||
            GetAssetStreamHandler handler;
 | 
			
		||||
            OSHttpResponse response;
 | 
			
		||||
            CreateTestEnvironment(out handler, out response);
 | 
			
		||||
 | 
			
		||||
            GetAssetStreamHandlerTestHelpers.BaseFetchMissingAsset(handler, response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void TestHandleFetchExistingAssetData()
 | 
			
		||||
        {
 | 
			
		||||
            GetAssetStreamHandler handler;
 | 
			
		||||
            OSHttpResponse response;
 | 
			
		||||
            AssetBase asset = CreateTestEnvironment(out handler, out response);
 | 
			
		||||
 | 
			
		||||
            GetAssetStreamHandlerTestHelpers.BaseFetchExistingAssetDataTest(asset, handler, response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void TestHandleFetchExistingAssetXml()
 | 
			
		||||
        {
 | 
			
		||||
            GetAssetStreamHandler handler;
 | 
			
		||||
            OSHttpResponse response;
 | 
			
		||||
            AssetBase asset = CreateTestEnvironment(out handler, out response);
 | 
			
		||||
 | 
			
		||||
            GetAssetStreamHandlerTestHelpers.BaseFetchExistingAssetXmlTest(asset, handler, response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static AssetBase CreateTestEnvironment(out GetAssetStreamHandler handler, out OSHttpResponse response)
 | 
			
		||||
        {
 | 
			
		||||
            AssetBase asset = GetAssetStreamHandlerTestHelpers.CreateCommonTestResources(out response);
 | 
			
		||||
 | 
			
		||||
            IAssetDataPlugin assetDataPlugin = new TestAssetDataPlugin();
 | 
			
		||||
            handler = new GetAssetStreamHandler(assetDataPlugin);
 | 
			
		||||
 | 
			
		||||
            assetDataPlugin.StoreAsset(asset);
 | 
			
		||||
            return asset;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +69,6 @@ namespace OpenSim
 | 
			
		|||
        /// of the code that is too old. 
 | 
			
		||||
        ///   
 | 
			
		||||
        /// </value>
 | 
			
		||||
        public readonly static int MajorInterfaceVersion = 5;
 | 
			
		||||
        public readonly static int MajorInterfaceVersion = 6;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,146 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using log4net.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Data;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.AssetLoader.Filesystem;
 | 
			
		||||
using OpenSim.Framework.Console;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Framework.Statistics;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Grid.AssetServer
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// An asset server
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class OpenAsset_Main : BaseOpenSimServer
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        public static OpenAsset_Main assetserver;
 | 
			
		||||
 | 
			
		||||
        // Temporarily hardcoded - should be a plugin
 | 
			
		||||
        protected IAssetLoader assetLoader = new AssetLoaderFileSystem();
 | 
			
		||||
 | 
			
		||||
        private IAssetDataPlugin m_assetProvider;
 | 
			
		||||
 | 
			
		||||
        public static void Main(string[] args)
 | 
			
		||||
        {
 | 
			
		||||
            XmlConfigurator.Configure();
 | 
			
		||||
 | 
			
		||||
            assetserver = new OpenAsset_Main();
 | 
			
		||||
            assetserver.Startup();
 | 
			
		||||
 | 
			
		||||
            assetserver.Work();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Work()
 | 
			
		||||
        {
 | 
			
		||||
            m_console.Output("Enter help for a list of commands");
 | 
			
		||||
 | 
			
		||||
            while (true)
 | 
			
		||||
            {
 | 
			
		||||
                m_console.Prompt();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public OpenAsset_Main()
 | 
			
		||||
        {
 | 
			
		||||
            m_console = new LocalConsole("Asset");
 | 
			
		||||
 | 
			
		||||
            MainConsole.Instance = m_console;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void StartupSpecific()
 | 
			
		||||
        {
 | 
			
		||||
            AssetConfig config = new AssetConfig("ASSET SERVER", (Path.Combine(Util.configDir(), "AssetServer_Config.xml")));
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[ASSET]: Setting up asset DB");
 | 
			
		||||
            setupDB(config);
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[ASSET]: Loading default asset set from '" + config.AssetSetsLocation + "'");
 | 
			
		||||
            LoadDefaultAssets(config.AssetSetsLocation);
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[ASSET]: Starting HTTP process");
 | 
			
		||||
            m_httpServer = new BaseHttpServer(config.HttpPort);
 | 
			
		||||
 | 
			
		||||
            m_stats = StatsManager.StartCollectingAssetStats();
 | 
			
		||||
 | 
			
		||||
            AddHttpHandlers();
 | 
			
		||||
 | 
			
		||||
            m_httpServer.Start();
 | 
			
		||||
 | 
			
		||||
            base.StartupSpecific();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void AddHttpHandlers()
 | 
			
		||||
        {
 | 
			
		||||
            m_httpServer.AddStreamHandler(new GetAssetStreamHandler(m_assetProvider));
 | 
			
		||||
            m_httpServer.AddStreamHandler(new PostAssetStreamHandler(m_assetProvider));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public byte[] GetAssetData(UUID assetID, bool isTexture)
 | 
			
		||||
        {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void setupDB(AssetConfig config)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                m_assetProvider = DataPluginFactory.LoadDataPlugin<IAssetDataPlugin>(config.DatabaseProvider, config.DatabaseConnect);
 | 
			
		||||
                if (m_assetProvider == null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Error("[ASSET]: Failed to load a database plugin, server halting");
 | 
			
		||||
                    Environment.Exit(-1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.Warn("[ASSET]: setupDB() - Exception occured");
 | 
			
		||||
                m_log.Warn("[ASSET]: " + e.ToString());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void LoadDefaultAssets(string pAssetSetsLocation)
 | 
			
		||||
        {
 | 
			
		||||
            assetLoader.ForEachDefaultXmlAsset(pAssetSetsLocation, StoreAsset);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void StoreAsset(AssetBase asset)
 | 
			
		||||
        {
 | 
			
		||||
            m_assetProvider.StoreAsset(asset);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,63 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Reflection;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
// General information about an assembly is controlled through the following
 | 
			
		||||
// set of attributes. Change these attribute values to modify the information
 | 
			
		||||
// associated with an assembly.
 | 
			
		||||
 | 
			
		||||
[assembly : AssemblyTitle("OGS-AssetServer")]
 | 
			
		||||
[assembly : AssemblyDescription("")]
 | 
			
		||||
[assembly : AssemblyConfiguration("")]
 | 
			
		||||
[assembly : AssemblyCompany("http://opensimulator.org")]
 | 
			
		||||
[assembly : AssemblyProduct("OGS-AssetServer")]
 | 
			
		||||
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
 | 
			
		||||
[assembly : AssemblyTrademark("")]
 | 
			
		||||
[assembly : AssemblyCulture("")]
 | 
			
		||||
 | 
			
		||||
// Setting ComVisible to false makes the types in this assembly not visible
 | 
			
		||||
// to COM components.  If you need to access a type in this assembly from
 | 
			
		||||
// COM, set the ComVisible attribute to true on that type.
 | 
			
		||||
 | 
			
		||||
[assembly : ComVisible(false)]
 | 
			
		||||
 | 
			
		||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
 | 
			
		||||
 | 
			
		||||
[assembly : Guid("b541b244-3d1d-4625-9003-bc2a3a6a39a4")]
 | 
			
		||||
 | 
			
		||||
// Version information for an assembly consists of the following four values:
 | 
			
		||||
//
 | 
			
		||||
//      Major Version
 | 
			
		||||
//      Minor Version
 | 
			
		||||
//      Build Number
 | 
			
		||||
//      Revision
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
[assembly : AssemblyVersion("0.6.5.*")]
 | 
			
		||||
[assembly : AssemblyFileVersion("0.6.5.0")]
 | 
			
		||||
| 
						 | 
				
			
			@ -1,133 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Grid.InventoryServer
 | 
			
		||||
{
 | 
			
		||||
    public class AuthedSessionCache
 | 
			
		||||
    {
 | 
			
		||||
        public class CacheData
 | 
			
		||||
        {
 | 
			
		||||
            private static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1);
 | 
			
		||||
            private string m_session_id;
 | 
			
		||||
            private string m_agent_id;
 | 
			
		||||
            private int m_expire;
 | 
			
		||||
 | 
			
		||||
            private int get_current_unix_time()
 | 
			
		||||
            {
 | 
			
		||||
                return (int)(DateTime.UtcNow - UNIX_EPOCH).TotalSeconds;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public CacheData(string sid, string aid)
 | 
			
		||||
            {
 | 
			
		||||
                m_session_id = sid;
 | 
			
		||||
                m_agent_id = aid;
 | 
			
		||||
                m_expire = get_current_unix_time() + DEFAULT_LIFETIME;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public CacheData(string sid, string aid, int time_now)
 | 
			
		||||
            {
 | 
			
		||||
                m_session_id = sid;
 | 
			
		||||
                m_agent_id = aid;
 | 
			
		||||
                m_expire = time_now + DEFAULT_LIFETIME;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public string SessionID
 | 
			
		||||
            {
 | 
			
		||||
                get { return m_session_id; }
 | 
			
		||||
                set { m_session_id = value; }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public string AgentID
 | 
			
		||||
            {
 | 
			
		||||
                get { return m_agent_id; }
 | 
			
		||||
                set { m_agent_id = value; }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public bool isExpired
 | 
			
		||||
            {
 | 
			
		||||
                get { return m_expire < get_current_unix_time(); }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public void Renew()
 | 
			
		||||
            {
 | 
			
		||||
                m_expire = get_current_unix_time() + DEFAULT_LIFETIME;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static readonly int DEFAULT_LIFETIME = 30;
 | 
			
		||||
        private Dictionary<string, CacheData> m_authed_sessions = new Dictionary<string,CacheData>();
 | 
			
		||||
        // private int m_session_lifetime = DEFAULT_LIFETIME;
 | 
			
		||||
 | 
			
		||||
        public AuthedSessionCache()
 | 
			
		||||
        {
 | 
			
		||||
            // m_session_lifetime = DEFAULT_LIFETIME;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthedSessionCache(int timeout)
 | 
			
		||||
        {
 | 
			
		||||
            // m_session_lifetime = timeout;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public CacheData getCachedSession(string session_id, string agent_id)
 | 
			
		||||
        {
 | 
			
		||||
            CacheData ret = null;
 | 
			
		||||
            lock (m_authed_sessions)
 | 
			
		||||
            {
 | 
			
		||||
                if (m_authed_sessions.ContainsKey(session_id))
 | 
			
		||||
                {
 | 
			
		||||
                    CacheData cached_session = m_authed_sessions[session_id];
 | 
			
		||||
                    if (!cached_session.isExpired && cached_session.AgentID == agent_id)
 | 
			
		||||
                    {
 | 
			
		||||
                        ret = m_authed_sessions[session_id];
 | 
			
		||||
                        // auto renew
 | 
			
		||||
                        m_authed_sessions[session_id].Renew();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Add(string session_id, string agent_id)
 | 
			
		||||
        {
 | 
			
		||||
            CacheData data = new CacheData(session_id, agent_id);
 | 
			
		||||
            lock (m_authed_sessions)
 | 
			
		||||
            {
 | 
			
		||||
                if (m_authed_sessions.ContainsKey(session_id))
 | 
			
		||||
                {
 | 
			
		||||
                    m_authed_sessions[session_id] = data;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    m_authed_sessions.Add(session_id, data);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,256 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using Nwc.XmlRpc;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Communications;
 | 
			
		||||
using OpenSim.Framework.Communications.Cache;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Grid.InventoryServer
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Used on a grid server to satisfy external inventory requests
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class GridInventoryService : InventoryServiceBase
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
        
 | 
			
		||||
        private bool m_doLookup = false;
 | 
			
		||||
 | 
			
		||||
        public bool DoLookup
 | 
			
		||||
        {
 | 
			
		||||
            get { return m_doLookup; }
 | 
			
		||||
            set { m_doLookup = value; }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        private static readonly int INVENTORY_DEFAULT_SESSION_TIME = 30; // secs
 | 
			
		||||
 | 
			
		||||
        private string m_userserver_url;
 | 
			
		||||
        private AuthedSessionCache m_session_cache = new AuthedSessionCache(INVENTORY_DEFAULT_SESSION_TIME);
 | 
			
		||||
 | 
			
		||||
        public GridInventoryService(string userserver_url)
 | 
			
		||||
        {
 | 
			
		||||
            m_userserver_url = userserver_url;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Check that the source of an inventory request is one that we trust.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="peer"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public bool CheckTrustSource(IPEndPoint peer)
 | 
			
		||||
        {
 | 
			
		||||
            if (m_doLookup)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.InfoFormat("[GRID AGENT INVENTORY]: Checking trusted source {0}", peer);
 | 
			
		||||
                UriBuilder ub = new UriBuilder(m_userserver_url);
 | 
			
		||||
                IPAddress[] uaddrs = Dns.GetHostAddresses(ub.Host);
 | 
			
		||||
                foreach (IPAddress uaddr in uaddrs)
 | 
			
		||||
                {
 | 
			
		||||
                    if (uaddr.Equals(peer.Address))
 | 
			
		||||
                    {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                m_log.WarnFormat(
 | 
			
		||||
                    "[GRID AGENT INVENTORY]: Rejecting request since source {0} was not in the list of trusted sources",
 | 
			
		||||
                    peer);
 | 
			
		||||
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Check that the source of an inventory request for a particular agent is a current session belonging to
 | 
			
		||||
        /// that agent.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="session_id"></param>
 | 
			
		||||
        /// <param name="avatar_id"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public bool CheckAuthSession(string session_id, string avatar_id)
 | 
			
		||||
        {
 | 
			
		||||
            if (m_doLookup)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.InfoFormat("[GRID AGENT INVENTORY]: checking authed session {0} {1}", session_id, avatar_id);
 | 
			
		||||
 | 
			
		||||
                if (m_session_cache.getCachedSession(session_id, avatar_id) == null)
 | 
			
		||||
                {
 | 
			
		||||
                    // cache miss, ask userserver
 | 
			
		||||
                    Hashtable requestData = new Hashtable();
 | 
			
		||||
                    requestData["avatar_uuid"] = avatar_id;
 | 
			
		||||
                    requestData["session_id"] = session_id;
 | 
			
		||||
                    ArrayList SendParams = new ArrayList();
 | 
			
		||||
                    SendParams.Add(requestData);
 | 
			
		||||
                    XmlRpcRequest UserReq = new XmlRpcRequest("check_auth_session", SendParams);
 | 
			
		||||
                    XmlRpcResponse UserResp = UserReq.Send(m_userserver_url, 3000);
 | 
			
		||||
 | 
			
		||||
                    Hashtable responseData = (Hashtable)UserResp.Value;
 | 
			
		||||
                    if (responseData.ContainsKey("auth_session") && responseData["auth_session"].ToString() == "TRUE")
 | 
			
		||||
                    {
 | 
			
		||||
                        m_log.Info("[GRID AGENT INVENTORY]: got authed session from userserver");
 | 
			
		||||
                        // add to cache; the session time will be automatically renewed
 | 
			
		||||
                        m_session_cache.Add(session_id, avatar_id);
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // cache hits
 | 
			
		||||
                    m_log.Info("[GRID AGENT INVENTORY]: got authed session from cache");
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                m_log.Warn("[GRID AGENT INVENTORY]: unknown session_id, request rejected");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Return a user's entire inventory
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="rawUserID"></param>
 | 
			
		||||
        /// <returns>The user's inventory.  If an inventory cannot be found then an empty collection is returned.</returns>
 | 
			
		||||
        public InventoryCollection GetUserInventory(Guid rawUserID)
 | 
			
		||||
        {
 | 
			
		||||
            UUID userID = new UUID(rawUserID);
 | 
			
		||||
 | 
			
		||||
            m_log.InfoFormat("[GRID AGENT INVENTORY]: Processing request for inventory of {0}", userID);
 | 
			
		||||
 | 
			
		||||
            // Uncomment me to simulate a slow responding inventory server
 | 
			
		||||
            //Thread.Sleep(16000);
 | 
			
		||||
 | 
			
		||||
            InventoryCollection invCollection = new InventoryCollection();
 | 
			
		||||
 | 
			
		||||
            List<InventoryFolderBase> allFolders = GetInventorySkeleton(userID);
 | 
			
		||||
 | 
			
		||||
            if (null == allFolders)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.WarnFormat("[GRID AGENT INVENTORY]: No inventory found for user {0}", rawUserID);
 | 
			
		||||
 | 
			
		||||
                return invCollection;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            List<InventoryItemBase> allItems = new List<InventoryItemBase>();
 | 
			
		||||
 | 
			
		||||
            foreach (InventoryFolderBase folder in allFolders)
 | 
			
		||||
            {
 | 
			
		||||
                List<InventoryItemBase> items = RequestFolderItems(folder.ID);
 | 
			
		||||
 | 
			
		||||
                if (items != null)
 | 
			
		||||
                {
 | 
			
		||||
                    allItems.InsertRange(0, items);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            invCollection.UserID = userID;
 | 
			
		||||
            invCollection.Folders = allFolders;
 | 
			
		||||
            invCollection.Items = allItems;
 | 
			
		||||
 | 
			
		||||
            //            foreach (InventoryFolderBase folder in invCollection.Folders)
 | 
			
		||||
            //            {
 | 
			
		||||
            //                m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back folder {0} {1}", folder.Name, folder.ID);
 | 
			
		||||
            //            }
 | 
			
		||||
            //
 | 
			
		||||
            //            foreach (InventoryItemBase item in invCollection.Items)
 | 
			
		||||
            //            {
 | 
			
		||||
            //                m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back item {0} {1}, folder {2}", item.Name, item.ID, item.Folder);
 | 
			
		||||
            //            }
 | 
			
		||||
 | 
			
		||||
            m_log.InfoFormat(
 | 
			
		||||
                "[GRID AGENT INVENTORY]: Sending back inventory response to user {0} containing {1} folders and {2} items",
 | 
			
		||||
                invCollection.UserID, invCollection.Folders.Count, invCollection.Items.Count);
 | 
			
		||||
 | 
			
		||||
            return invCollection;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<InventoryItemBase> GetFolderItems(Guid folderID)
 | 
			
		||||
        {
 | 
			
		||||
            List<InventoryItemBase> allItems = new List<InventoryItemBase>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            List<InventoryItemBase> items = RequestFolderItems(new UUID(folderID));
 | 
			
		||||
 | 
			
		||||
            if (items != null)
 | 
			
		||||
            {
 | 
			
		||||
                allItems.InsertRange(0, items);
 | 
			
		||||
            }
 | 
			
		||||
            m_log.InfoFormat(
 | 
			
		||||
              "[GRID AGENT INVENTORY]: Sending back inventory response  containing {0} items", allItems.Count.ToString());
 | 
			
		||||
            return allItems;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Guid to UUID wrapper for same name IInventoryServices method
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="rawUserID"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID)
 | 
			
		||||
        {
 | 
			
		||||
            UUID userID = new UUID(rawUserID);
 | 
			
		||||
            return GetInventorySkeleton(userID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Create an inventory for the given user.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="rawUserID"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public bool CreateUsersInventory(Guid rawUserID)
 | 
			
		||||
        {
 | 
			
		||||
            UUID userID = new UUID(rawUserID);
 | 
			
		||||
 | 
			
		||||
            m_log.InfoFormat("[GRID AGENT INVENTORY]: Creating new set of inventory folders for user {0}", userID);
 | 
			
		||||
 | 
			
		||||
            return CreateNewUserInventory(userID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<InventoryItemBase> GetActiveGestures(Guid rawUserID)
 | 
			
		||||
        {
 | 
			
		||||
            UUID userID = new UUID(rawUserID);
 | 
			
		||||
 | 
			
		||||
            m_log.InfoFormat("[GRID AGENT INVENTORY]: fetching active gestures for user {0}", userID);
 | 
			
		||||
 | 
			
		||||
            return GetActiveGestures(userID);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,519 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Data;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Communications;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Grid.InventoryServer
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Abstract base class used by local and grid implementations of an inventory service.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public abstract class InventoryServiceBase : IInterServiceInventoryServices
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        private static readonly ILog m_log
 | 
			
		||||
            = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        protected List<IInventoryDataPlugin> m_plugins = new List<IInventoryDataPlugin>();
 | 
			
		||||
 | 
			
		||||
        #region Plugin methods
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Add a new inventory data plugin - plugins will be requested in the order they were added.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="plugin">The plugin that will provide data</param>
 | 
			
		||||
        public void AddPlugin(IInventoryDataPlugin plugin)
 | 
			
		||||
        {
 | 
			
		||||
            m_plugins.Add(plugin);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds a list of inventory data plugins, as described by `provider'
 | 
			
		||||
        /// and `connect', to `m_plugins'.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="provider">
 | 
			
		||||
        /// The filename of the inventory server plugin DLL.
 | 
			
		||||
        /// </param>
 | 
			
		||||
        /// <param name="connect">
 | 
			
		||||
        /// The connection string for the storage backend.
 | 
			
		||||
        /// </param>
 | 
			
		||||
        public void AddPlugin(string provider, string connect)
 | 
			
		||||
        {
 | 
			
		||||
            m_plugins.AddRange(DataPluginFactory.LoadDataPlugins<IInventoryDataPlugin>(provider, connect));
 | 
			
		||||
        }        
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region IInventoryServices methods
 | 
			
		||||
 | 
			
		||||
        public string Host
 | 
			
		||||
        {
 | 
			
		||||
            get { return "default"; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
 | 
			
		||||
        {
 | 
			
		||||
//            m_log.DebugFormat("[AGENT INVENTORY]: Getting inventory skeleton for {0}", userId);
 | 
			
		||||
 | 
			
		||||
            InventoryFolderBase rootFolder = RequestRootFolder(userId);
 | 
			
		||||
 | 
			
		||||
            // Agent has no inventory structure yet.
 | 
			
		||||
            if (null == rootFolder)
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            List<InventoryFolderBase> userFolders = new List<InventoryFolderBase>();
 | 
			
		||||
 | 
			
		||||
            userFolders.Add(rootFolder);
 | 
			
		||||
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                IList<InventoryFolderBase> folders = plugin.getFolderHierarchy(rootFolder.ID);
 | 
			
		||||
                userFolders.AddRange(folders);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
//            foreach (InventoryFolderBase folder in userFolders)
 | 
			
		||||
//            {
 | 
			
		||||
//                m_log.DebugFormat("[AGENT INVENTORY]: Got folder {0} {1}", folder.name, folder.folderID);
 | 
			
		||||
//            }
 | 
			
		||||
 | 
			
		||||
            return userFolders;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See IInventoryServices
 | 
			
		||||
        public virtual bool HasInventoryForUser(UUID userID)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See IInventoryServices
 | 
			
		||||
        public virtual InventoryFolderBase RequestRootFolder(UUID userID)
 | 
			
		||||
        {
 | 
			
		||||
            // Retrieve the first root folder we get from the list of plugins.
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                InventoryFolderBase rootFolder = plugin.getUserRootFolder(userID);
 | 
			
		||||
                if (rootFolder != null)
 | 
			
		||||
                    return rootFolder;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Return nothing if no plugin was able to supply a root folder
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See IInventoryServices
 | 
			
		||||
        public bool CreateNewUserInventory(UUID user)
 | 
			
		||||
        {
 | 
			
		||||
            InventoryFolderBase existingRootFolder = RequestRootFolder(user);
 | 
			
		||||
 | 
			
		||||
            if (null != existingRootFolder)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.WarnFormat(
 | 
			
		||||
                    "[AGENT INVENTORY]: Did not create a new inventory for user {0} since they already have "
 | 
			
		||||
                    + "a root inventory folder with id {1}",
 | 
			
		||||
                    user, existingRootFolder.ID);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                UsersInventory inven = new UsersInventory();
 | 
			
		||||
                inven.CreateNewInventorySet(user);
 | 
			
		||||
                AddNewInventorySet(inven);
 | 
			
		||||
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<InventoryItemBase> GetActiveGestures(UUID userId)
 | 
			
		||||
        {
 | 
			
		||||
            List<InventoryItemBase> activeGestures = new List<InventoryItemBase>();
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                activeGestures.AddRange(plugin.fetchActiveGestures(userId));
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            return activeGestures;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region Methods used by GridInventoryService
 | 
			
		||||
 | 
			
		||||
        public List<InventoryFolderBase> RequestSubFolders(UUID parentFolderID)
 | 
			
		||||
        {
 | 
			
		||||
            List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>();
 | 
			
		||||
            
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                inventoryList.AddRange(plugin.getInventoryFolders(parentFolderID));
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            return inventoryList;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<InventoryItemBase> RequestFolderItems(UUID folderID)
 | 
			
		||||
        {
 | 
			
		||||
            List<InventoryItemBase> itemsList = new List<InventoryItemBase>();
 | 
			
		||||
            
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                itemsList.AddRange(plugin.getInventoryInFolder(folderID));
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            return itemsList;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        // See IInventoryServices
 | 
			
		||||
        public virtual bool AddFolder(InventoryFolderBase folder)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.DebugFormat(
 | 
			
		||||
                "[AGENT INVENTORY]: Adding folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID);
 | 
			
		||||
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                plugin.addInventoryFolder(folder);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // FIXME: Should return false on failure
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See IInventoryServices
 | 
			
		||||
        public virtual bool UpdateFolder(InventoryFolderBase folder)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.DebugFormat(
 | 
			
		||||
                "[AGENT INVENTORY]: Updating folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID);
 | 
			
		||||
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                plugin.updateInventoryFolder(folder);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // FIXME: Should return false on failure
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See IInventoryServices
 | 
			
		||||
        public virtual bool MoveFolder(InventoryFolderBase folder)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.DebugFormat(
 | 
			
		||||
                "[AGENT INVENTORY]: Moving folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID);
 | 
			
		||||
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                plugin.moveInventoryFolder(folder);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // FIXME: Should return false on failure
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See IInventoryServices
 | 
			
		||||
        public virtual bool AddItem(InventoryItemBase item)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.DebugFormat(
 | 
			
		||||
                "[AGENT INVENTORY]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder);
 | 
			
		||||
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                plugin.addInventoryItem(item);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // FIXME: Should return false on failure
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See IInventoryServices
 | 
			
		||||
        public virtual bool UpdateItem(InventoryItemBase item)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.InfoFormat(
 | 
			
		||||
                "[AGENT INVENTORY]: Updating item {0} {1} in folder {2}", item.Name, item.ID, item.Folder);
 | 
			
		||||
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                plugin.updateInventoryItem(item);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // FIXME: Should return false on failure
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See IInventoryServices
 | 
			
		||||
        public virtual bool DeleteItem(InventoryItemBase item)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.InfoFormat(
 | 
			
		||||
                "[AGENT INVENTORY]: Deleting item {0} {1} from folder {2}", item.Name, item.ID, item.Folder);
 | 
			
		||||
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                plugin.deleteInventoryItem(item.ID);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // FIXME: Should return false on failure
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual InventoryItemBase QueryItem(InventoryItemBase item)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                InventoryItemBase result = plugin.queryInventoryItem(item.ID);
 | 
			
		||||
                if (result != null)
 | 
			
		||||
                    return result;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual InventoryFolderBase QueryFolder(InventoryFolderBase item)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                InventoryFolderBase result = plugin.queryInventoryFolder(item.ID);
 | 
			
		||||
                if (result != null)
 | 
			
		||||
                    return result;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Purge a folder of all items items and subfolders.
 | 
			
		||||
        ///
 | 
			
		||||
        /// FIXME: Really nasty in a sense, because we have to query the database to get information we may
 | 
			
		||||
        /// already know...  Needs heavy refactoring.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="folder"></param>
 | 
			
		||||
        public virtual bool PurgeFolder(InventoryFolderBase folder)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.DebugFormat(
 | 
			
		||||
                "[AGENT INVENTORY]: Purging folder {0} {1} of its contents", folder.Name, folder.ID);
 | 
			
		||||
 | 
			
		||||
            List<InventoryFolderBase> subFolders = RequestSubFolders(folder.ID);
 | 
			
		||||
 | 
			
		||||
            foreach (InventoryFolderBase subFolder in subFolders)
 | 
			
		||||
            {
 | 
			
		||||
//                m_log.DebugFormat("[AGENT INVENTORY]: Deleting folder {0} {1}", subFolder.Name, subFolder.ID);
 | 
			
		||||
 | 
			
		||||
                foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
                {
 | 
			
		||||
                    plugin.deleteInventoryFolder(subFolder.ID);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            List<InventoryItemBase> items = RequestFolderItems(folder.ID);
 | 
			
		||||
 | 
			
		||||
            foreach (InventoryItemBase item in items)
 | 
			
		||||
            {
 | 
			
		||||
                DeleteItem(item);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // FIXME: Should return false on failure
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddNewInventorySet(UsersInventory inventory)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (InventoryFolderBase folder in inventory.Folders.Values)
 | 
			
		||||
            {
 | 
			
		||||
                AddFolder(folder);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public InventoryItemBase GetInventoryItem(UUID itemID)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (IInventoryDataPlugin plugin in m_plugins)
 | 
			
		||||
            {
 | 
			
		||||
                InventoryItemBase item = plugin.getInventoryItem(itemID);
 | 
			
		||||
                if (item != null)
 | 
			
		||||
                    return item;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Used to create a new user inventory.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private class UsersInventory
 | 
			
		||||
        {
 | 
			
		||||
            public Dictionary<UUID, InventoryFolderBase> Folders = new Dictionary<UUID, InventoryFolderBase>();
 | 
			
		||||
            public Dictionary<UUID, InventoryItemBase> Items = new Dictionary<UUID, InventoryItemBase>();
 | 
			
		||||
 | 
			
		||||
            public virtual void CreateNewInventorySet(UUID user)
 | 
			
		||||
            {
 | 
			
		||||
                InventoryFolderBase folder = new InventoryFolderBase();
 | 
			
		||||
 | 
			
		||||
                folder.ParentID = UUID.Zero;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "My Inventory";
 | 
			
		||||
                folder.Type = (short)AssetType.Folder;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                UUID rootFolder = folder.ID;
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Animations";
 | 
			
		||||
                folder.Type = (short)AssetType.Animation;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Body Parts";
 | 
			
		||||
                folder.Type = (short)AssetType.Bodypart;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Calling Cards";
 | 
			
		||||
                folder.Type = (short)AssetType.CallingCard;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Clothing";
 | 
			
		||||
                folder.Type = (short)AssetType.Clothing;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Gestures";
 | 
			
		||||
                folder.Type = (short)AssetType.Gesture;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Landmarks";
 | 
			
		||||
                folder.Type = (short)AssetType.Landmark;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Lost And Found";
 | 
			
		||||
                folder.Type = (short)AssetType.LostAndFoundFolder;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Notecards";
 | 
			
		||||
                folder.Type = (short)AssetType.Notecard;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Objects";
 | 
			
		||||
                folder.Type = (short)AssetType.Object;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Photo Album";
 | 
			
		||||
                folder.Type = (short)AssetType.SnapshotFolder;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Scripts";
 | 
			
		||||
                folder.Type = (short)AssetType.LSLText;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Sounds";
 | 
			
		||||
                folder.Type = (short)AssetType.Sound;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Textures";
 | 
			
		||||
                folder.Type = (short)AssetType.Texture;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
 | 
			
		||||
                folder = new InventoryFolderBase();
 | 
			
		||||
                folder.ParentID = rootFolder;
 | 
			
		||||
                folder.Owner = user;
 | 
			
		||||
                folder.ID = UUID.Random();
 | 
			
		||||
                folder.Name = "Trash";
 | 
			
		||||
                folder.Type = (short)AssetType.TrashFolder;
 | 
			
		||||
                folder.Version = 1;
 | 
			
		||||
                Folders.Add(folder.ID, folder);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,182 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using log4net.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Communications.Services;
 | 
			
		||||
using OpenSim.Framework.Console;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Grid.InventoryServer
 | 
			
		||||
{
 | 
			
		||||
    public class OpenInventory_Main : BaseOpenSimServer
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private GridInventoryService m_inventoryService;
 | 
			
		||||
        //private HGInventoryService m_directInventoryService;
 | 
			
		||||
 | 
			
		||||
        public const string LogName = "INVENTORY";
 | 
			
		||||
 | 
			
		||||
        public static void Main(string[] args)
 | 
			
		||||
        {
 | 
			
		||||
            XmlConfigurator.Configure();
 | 
			
		||||
 | 
			
		||||
            OpenInventory_Main theServer = new OpenInventory_Main();
 | 
			
		||||
            theServer.Startup();
 | 
			
		||||
 | 
			
		||||
            theServer.Work();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public OpenInventory_Main()
 | 
			
		||||
        {
 | 
			
		||||
            m_console = new LocalConsole("Inventory");
 | 
			
		||||
            MainConsole.Instance = m_console;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void StartupSpecific()
 | 
			
		||||
        {
 | 
			
		||||
            InventoryConfig config = new InventoryConfig(LogName, (Path.Combine(Util.configDir(), "InventoryServer_Config.xml")));
 | 
			
		||||
 | 
			
		||||
            m_inventoryService = new GridInventoryService(config.UserServerURL);
 | 
			
		||||
            m_inventoryService.DoLookup = config.SessionLookUp;
 | 
			
		||||
            m_inventoryService.AddPlugin(config.DatabaseProvider, config.DatabaseConnect);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[" + LogName + "]: Starting HTTP server ...");
 | 
			
		||||
 | 
			
		||||
            m_httpServer = new BaseHttpServer(config.HttpPort);
 | 
			
		||||
 | 
			
		||||
            AddHttpHandlers(config.RegionAccessToAgentsInventory);
 | 
			
		||||
 | 
			
		||||
            m_httpServer.Start();
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[" + LogName + "]: Started HTTP server");
 | 
			
		||||
 | 
			
		||||
            base.StartupSpecific();
 | 
			
		||||
 | 
			
		||||
            m_console.Commands.AddCommand("inventoryserver", false, "add user",
 | 
			
		||||
                    "add user",
 | 
			
		||||
                    "Add a random user inventory", HandleAddUser);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void AddHttpHandlers(bool regionAccess)
 | 
			
		||||
        {
 | 
			
		||||
            if (regionAccess)
 | 
			
		||||
            {
 | 
			
		||||
                m_httpServer.AddStreamHandler(
 | 
			
		||||
                    new RestDeserialiseSecureHandler<Guid, InventoryCollection>(
 | 
			
		||||
                        "POST", "/GetInventory/", m_inventoryService.GetUserInventory, m_inventoryService.CheckAuthSession));
 | 
			
		||||
 | 
			
		||||
                m_httpServer.AddStreamHandler(
 | 
			
		||||
                    new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
 | 
			
		||||
                        "POST", "/UpdateFolder/", m_inventoryService.UpdateFolder, m_inventoryService.CheckAuthSession));
 | 
			
		||||
 | 
			
		||||
                m_httpServer.AddStreamHandler(
 | 
			
		||||
                    new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
 | 
			
		||||
                        "POST", "/MoveFolder/", m_inventoryService.MoveFolder, m_inventoryService.CheckAuthSession));
 | 
			
		||||
 | 
			
		||||
                m_httpServer.AddStreamHandler(
 | 
			
		||||
                    new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
 | 
			
		||||
                        "POST", "/PurgeFolder/", m_inventoryService.PurgeFolder, m_inventoryService.CheckAuthSession));
 | 
			
		||||
 | 
			
		||||
                m_httpServer.AddStreamHandler(
 | 
			
		||||
                    new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
 | 
			
		||||
                        "POST", "/DeleteItem/", m_inventoryService.DeleteItem, m_inventoryService.CheckAuthSession));
 | 
			
		||||
 | 
			
		||||
                m_httpServer.AddStreamHandler(
 | 
			
		||||
                    new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
 | 
			
		||||
                        "POST", "/QueryItem/", m_inventoryService.QueryItem, m_inventoryService.CheckAuthSession));
 | 
			
		||||
 | 
			
		||||
                m_httpServer.AddStreamHandler(
 | 
			
		||||
                    new RestDeserialiseSecureHandler<InventoryFolderBase, InventoryFolderBase>(
 | 
			
		||||
                        "POST", "/QueryFolder/", m_inventoryService.QueryFolder, m_inventoryService.CheckAuthSession));
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            m_httpServer.AddStreamHandler(
 | 
			
		||||
                new RestDeserialiseTrustedHandler<Guid, bool>(
 | 
			
		||||
                    "POST", "/CreateInventory/", m_inventoryService.CreateUsersInventory, m_inventoryService.CheckTrustSource));
 | 
			
		||||
 | 
			
		||||
            m_httpServer.AddStreamHandler(
 | 
			
		||||
                new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
 | 
			
		||||
                    "POST", "/NewFolder/", m_inventoryService.AddFolder, m_inventoryService.CheckAuthSession));
 | 
			
		||||
 | 
			
		||||
            m_httpServer.AddStreamHandler(
 | 
			
		||||
                new RestDeserialiseTrustedHandler<InventoryFolderBase, bool>(
 | 
			
		||||
                    "POST", "/CreateFolder/", m_inventoryService.AddFolder, m_inventoryService.CheckTrustSource));
 | 
			
		||||
 | 
			
		||||
            m_httpServer.AddStreamHandler(
 | 
			
		||||
                new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
 | 
			
		||||
                    "POST", "/NewItem/", m_inventoryService.AddItem, m_inventoryService.CheckAuthSession));
 | 
			
		||||
 | 
			
		||||
            m_httpServer.AddStreamHandler(
 | 
			
		||||
             new RestDeserialiseTrustedHandler<InventoryItemBase, bool>(
 | 
			
		||||
                 "POST", "/AddNewItem/", m_inventoryService.AddItem, m_inventoryService.CheckTrustSource));
 | 
			
		||||
 | 
			
		||||
            m_httpServer.AddStreamHandler(
 | 
			
		||||
                new RestDeserialiseTrustedHandler<Guid, List<InventoryItemBase>>(
 | 
			
		||||
                    "POST", "/GetItems/", m_inventoryService.GetFolderItems, m_inventoryService.CheckTrustSource));
 | 
			
		||||
 | 
			
		||||
            // for persistent active gestures
 | 
			
		||||
            m_httpServer.AddStreamHandler(
 | 
			
		||||
                new RestDeserialiseTrustedHandler<Guid, List<InventoryItemBase>>
 | 
			
		||||
                    ("POST", "/ActiveGestures/", m_inventoryService.GetActiveGestures, m_inventoryService.CheckTrustSource));
 | 
			
		||||
 | 
			
		||||
            // WARNING: Root folders no longer just delivers the root and immediate child folders (e.g
 | 
			
		||||
            // system folders such as Objects, Textures), but it now returns the entire inventory skeleton.
 | 
			
		||||
            // It would have been better to rename this request, but complexities in the BaseHttpServer
 | 
			
		||||
            // (e.g. any http request not found is automatically treated as an xmlrpc request) make it easier
 | 
			
		||||
            // to do this for now.
 | 
			
		||||
            m_httpServer.AddStreamHandler(
 | 
			
		||||
                new RestDeserialiseTrustedHandler<Guid, List<InventoryFolderBase>>
 | 
			
		||||
                    ("POST", "/RootFolders/", m_inventoryService.GetInventorySkeleton, m_inventoryService.CheckTrustSource));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Work()
 | 
			
		||||
        {
 | 
			
		||||
            m_console.Output("Enter help for a list of commands\n");
 | 
			
		||||
 | 
			
		||||
            while (true)
 | 
			
		||||
            {
 | 
			
		||||
                m_console.Prompt();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void HandleAddUser(string module, string[] args)
 | 
			
		||||
        {
 | 
			
		||||
            m_inventoryService.CreateUsersInventory(UUID.Random().Guid);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -73,10 +73,6 @@ namespace OpenSim.Region.Examples.SimpleModule
 | 
			
		|||
            base.UpdateMovement();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ComplexObject()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ComplexObject(Scene scene, ulong regionHandle, UUID ownerID, uint localID, Vector3 pos)
 | 
			
		||||
            : base(ownerID, pos, PrimitiveBaseShape.Default)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,39 +25,21 @@
 | 
			
		|||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Data;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Framework.Statistics;
 | 
			
		||||
using System.Net;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Framework.Servers
 | 
			
		||||
namespace OpenSim.Region.Framework.Interfaces
 | 
			
		||||
{
 | 
			
		||||
    public class GetAssetStreamHandler : BaseGetAssetStreamHandler
 | 
			
		||||
    public interface IVoiceModule
 | 
			
		||||
    {
 | 
			
		||||
        // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private readonly IAssetDataPlugin m_assetProvider;
 | 
			
		||||
 | 
			
		||||
        public GetAssetStreamHandler(IAssetDataPlugin assetProvider)
 | 
			
		||||
            : base("GET", "/assets")
 | 
			
		||||
        {
 | 
			
		||||
            m_assetProvider = assetProvider;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override AssetBase GetAsset(UUID assetID)
 | 
			
		||||
        {
 | 
			
		||||
            return m_assetProvider.GetAsset(assetID);
 | 
			
		||||
        }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Set the SIP url to be used by a parcel, this will allow manual setting of a SIP address
 | 
			
		||||
        /// for a particular piece of land, allowing region owners to use preconfigured SIP conference channels.
 | 
			
		||||
        /// This is used by osSetParcelSIPAddress
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        void setLandSIPAddress(string SIPAddress,UUID GlobalID);
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -250,16 +250,7 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
        /// </summary>
 | 
			
		||||
        public override Vector3 AbsolutePosition
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (m_rootPart == null)
 | 
			
		||||
                {
 | 
			
		||||
                    throw new NullReferenceException(
 | 
			
		||||
                        string.Format("[SCENE OBJECT GROUP]: Object {0} has no root part.", m_uuid));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return m_rootPart.GroupPosition;
 | 
			
		||||
            }
 | 
			
		||||
            get { return m_rootPart.GroupPosition; }
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                Vector3 val = value;
 | 
			
		||||
| 
						 | 
				
			
			@ -291,41 +282,19 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
 | 
			
		||||
        public override uint LocalId
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (m_rootPart == null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Error("[SCENE OBJECT GROUP]: Unable to find the rootpart for a LocalId Request!");
 | 
			
		||||
                    return 0;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return m_rootPart.LocalId;
 | 
			
		||||
            }
 | 
			
		||||
            get { return m_rootPart.LocalId; }
 | 
			
		||||
            set { m_rootPart.LocalId = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override UUID UUID
 | 
			
		||||
        {
 | 
			
		||||
            get {
 | 
			
		||||
                if (m_rootPart == null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Error("Got a null rootpart while requesting UUID. Called from: ", new Exception());
 | 
			
		||||
                    return UUID.Zero;
 | 
			
		||||
                }
 | 
			
		||||
                else return m_rootPart.UUID;
 | 
			
		||||
            }
 | 
			
		||||
            get { return m_rootPart.UUID; }
 | 
			
		||||
            set { m_rootPart.UUID = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public UUID OwnerID
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (m_rootPart == null)
 | 
			
		||||
                    return UUID.Zero;
 | 
			
		||||
 | 
			
		||||
                return m_rootPart.OwnerID;
 | 
			
		||||
            }
 | 
			
		||||
            get { return m_rootPart.OwnerID; }
 | 
			
		||||
            set { m_rootPart.OwnerID = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -366,7 +335,7 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            {
 | 
			
		||||
                m_isSelected = value;
 | 
			
		||||
                // Tell physics engine that group is selected
 | 
			
		||||
                if (m_rootPart != null && m_rootPart.PhysActor != null)
 | 
			
		||||
                if (m_rootPart.PhysActor != null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_rootPart.PhysActor.Selected = value;
 | 
			
		||||
                    // Pass it on to the children.
 | 
			
		||||
| 
						 | 
				
			
			@ -398,13 +367,6 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
 | 
			
		||||
        #region Constructors
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Constructor
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public SceneObjectGroup()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart.
 | 
			
		||||
        /// The original SceneObjectPart will be used rather than a copy, preserving
 | 
			
		||||
| 
						 | 
				
			
			@ -419,9 +381,8 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
        /// Constructor.  This object is added to the scene later via AttachToScene()
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
 | 
			
		||||
        {
 | 
			
		||||
            Vector3 rootOffset = new Vector3(0, 0, 0);   
 | 
			
		||||
            SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, rootOffset));
 | 
			
		||||
        { 
 | 
			
		||||
            SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -462,11 +423,7 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
 | 
			
		||||
        public UUID GetFromItemID()
 | 
			
		||||
        {
 | 
			
		||||
            if (m_rootPart != null)
 | 
			
		||||
            {
 | 
			
		||||
                return m_rootPart.FromItemID;
 | 
			
		||||
            }
 | 
			
		||||
            return UUID.Zero;
 | 
			
		||||
            return m_rootPart.FromItemID;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -958,11 +915,7 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
 | 
			
		||||
        public byte GetAttachmentPoint()
 | 
			
		||||
        {
 | 
			
		||||
            if (m_rootPart != null)
 | 
			
		||||
            {
 | 
			
		||||
                return m_rootPart.Shape.State;
 | 
			
		||||
            }
 | 
			
		||||
            return (byte)0;
 | 
			
		||||
            return m_rootPart.Shape.State;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ClearPartAttachmentData()
 | 
			
		||||
| 
						 | 
				
			
			@ -1071,7 +1024,10 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
        /// </summary>
 | 
			
		||||
        /// <param name="part"></param>
 | 
			
		||||
        public void SetRootPart(SceneObjectPart part)
 | 
			
		||||
        {            
 | 
			
		||||
        {
 | 
			
		||||
            if (part == null)
 | 
			
		||||
                throw new ArgumentNullException("Cannot give SceneObjectGroup a null root SceneObjectPart");
 | 
			
		||||
 | 
			
		||||
            part.SetParent(this);
 | 
			
		||||
            m_rootPart = part;
 | 
			
		||||
            if (!IsAttachment)
 | 
			
		||||
| 
						 | 
				
			
			@ -1224,7 +1180,7 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
 | 
			
		||||
                        if (!silent)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (m_rootPart != null && part == m_rootPart)
 | 
			
		||||
                            if (part == m_rootPart)
 | 
			
		||||
                                avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1447,7 +1403,7 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
        /// <param name="part"></param>
 | 
			
		||||
        internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags)
 | 
			
		||||
        {
 | 
			
		||||
            if (m_rootPart != null && m_rootPart.UUID == part.UUID)
 | 
			
		||||
            if (m_rootPart.UUID == part.UUID)
 | 
			
		||||
            {
 | 
			
		||||
                if (IsAttachment)
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -1881,12 +1837,6 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            if (m_isDeleted)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            // This is what happens when an orphanced link set child prim's
 | 
			
		||||
            // group was queued when it was linked
 | 
			
		||||
            //
 | 
			
		||||
            if (m_rootPart == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            // Even temporary objects take part in physics (e.g. temp-on-rez bullets)
 | 
			
		||||
            //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
 | 
			
		||||
            //    return;
 | 
			
		||||
| 
						 | 
				
			
			@ -3129,26 +3079,22 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            int yaxis = 4;
 | 
			
		||||
            int zaxis = 8;
 | 
			
		||||
 | 
			
		||||
            if (m_rootPart != null)
 | 
			
		||||
            setX = ((axis & xaxis) != 0) ? true : false;
 | 
			
		||||
            setY = ((axis & yaxis) != 0) ? true : false;
 | 
			
		||||
            setZ = ((axis & zaxis) != 0) ? true : false;
 | 
			
		||||
 | 
			
		||||
            float setval = (rotate10 > 0) ? 1f : 0f;
 | 
			
		||||
 | 
			
		||||
            if (setX)
 | 
			
		||||
                m_rootPart.RotationAxis.X = setval;
 | 
			
		||||
            if (setY)
 | 
			
		||||
                m_rootPart.RotationAxis.Y = setval;
 | 
			
		||||
            if (setZ)
 | 
			
		||||
                m_rootPart.RotationAxis.Z = setval;
 | 
			
		||||
 | 
			
		||||
            if (setX || setY || setZ)
 | 
			
		||||
            {
 | 
			
		||||
                setX = ((axis & xaxis) != 0) ? true : false;
 | 
			
		||||
                setY = ((axis & yaxis) != 0) ? true : false;
 | 
			
		||||
                setZ = ((axis & zaxis) != 0) ? true : false;
 | 
			
		||||
 | 
			
		||||
                float setval = (rotate10 > 0) ? 1f : 0f;
 | 
			
		||||
 | 
			
		||||
                if (setX)
 | 
			
		||||
                    m_rootPart.RotationAxis.X = setval;
 | 
			
		||||
                if (setY)
 | 
			
		||||
                    m_rootPart.RotationAxis.Y = setval;
 | 
			
		||||
                if (setZ)
 | 
			
		||||
                    m_rootPart.RotationAxis.Z = setval;
 | 
			
		||||
 | 
			
		||||
                if (setX || setY || setZ)
 | 
			
		||||
                {
 | 
			
		||||
                    m_rootPart.SetPhysicsAxisRotation();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                m_rootPart.SetPhysicsAxisRotation();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -415,9 +415,10 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            set 
 | 
			
		||||
            { 
 | 
			
		||||
                m_name = value;
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    PhysActor.SOPName = value;
 | 
			
		||||
                    pa.SOPName = value;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -427,10 +428,11 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            get { return (byte) m_material; }
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                m_material = (Material)value;
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    PhysActor.SetMaterial((int)value);
 | 
			
		||||
                    pa.SetMaterial((int)value);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -501,11 +503,12 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            get
 | 
			
		||||
            {
 | 
			
		||||
                // If this is a linkset, we don't want the physics engine mucking up our group position here.
 | 
			
		||||
                if (PhysActor != null && _parentID == 0)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa != null && _parentID == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    m_groupPosition.X = PhysActor.Position.X;
 | 
			
		||||
                    m_groupPosition.Y = PhysActor.Position.Y;
 | 
			
		||||
                    m_groupPosition.Z = PhysActor.Position.Z;
 | 
			
		||||
                    m_groupPosition.X = pa.Position.X;
 | 
			
		||||
                    m_groupPosition.Y = pa.Position.Y;
 | 
			
		||||
                    m_groupPosition.Z = pa.Position.Z;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (IsAttachment)
 | 
			
		||||
| 
						 | 
				
			
			@ -525,26 +528,27 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
 | 
			
		||||
                m_groupPosition = value;
 | 
			
		||||
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        // Root prim actually goes at Position
 | 
			
		||||
                        if (_parentID == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            PhysActor.Position = new PhysicsVector(value.X, value.Y, value.Z);
 | 
			
		||||
                            pa.Position = new PhysicsVector(value.X, value.Y, value.Z);
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            // To move the child prim in respect to the group position and rotation we have to calculate
 | 
			
		||||
                            Vector3 resultingposition = GetWorldPosition();
 | 
			
		||||
                            PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z);
 | 
			
		||||
                            pa.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z);
 | 
			
		||||
                            Quaternion resultingrot = GetWorldRotation();
 | 
			
		||||
                            PhysActor.Orientation = resultingrot;
 | 
			
		||||
                            pa.Orientation = resultingrot;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // Tell the physics engines that this prim changed.
 | 
			
		||||
                        m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
 | 
			
		||||
                        m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception e)
 | 
			
		||||
                    {
 | 
			
		||||
| 
						 | 
				
			
			@ -577,15 +581,16 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
 | 
			
		||||
                if (ParentGroup != null && !ParentGroup.IsDeleted)
 | 
			
		||||
                {
 | 
			
		||||
                     if (_parentID != 0 && PhysActor != null)
 | 
			
		||||
                    PhysicsActor pa = PhysActor;
 | 
			
		||||
                     if (_parentID != 0 && pa != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        Vector3 resultingposition = GetWorldPosition();
 | 
			
		||||
                        PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z);
 | 
			
		||||
                        pa.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z);
 | 
			
		||||
                        Quaternion resultingrot = GetWorldRotation();
 | 
			
		||||
                        PhysActor.Orientation = resultingrot;
 | 
			
		||||
                        pa.Orientation = resultingrot;
 | 
			
		||||
 | 
			
		||||
                        // Tell the physics engines that this prim changed.
 | 
			
		||||
                        m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
 | 
			
		||||
                        m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -595,13 +600,14 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                // We don't want the physics engine mucking up the rotations in a linkset
 | 
			
		||||
                if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0)  && (PhysActor != null))
 | 
			
		||||
                if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0)  && (pa != null))
 | 
			
		||||
                {
 | 
			
		||||
                    if (PhysActor.Orientation.X != 0 || PhysActor.Orientation.Y != 0
 | 
			
		||||
                        || PhysActor.Orientation.Z != 0 || PhysActor.Orientation.W != 0)
 | 
			
		||||
                    if (pa.Orientation.X != 0 || pa.Orientation.Y != 0
 | 
			
		||||
                        || pa.Orientation.Z != 0 || pa.Orientation.W != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_rotationOffset = PhysActor.Orientation;
 | 
			
		||||
                        m_rotationOffset = pa.Orientation;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
| 
						 | 
				
			
			@ -610,27 +616,28 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                StoreUndoState();
 | 
			
		||||
                m_rotationOffset = value;
 | 
			
		||||
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        // Root prim gets value directly
 | 
			
		||||
                        if (_parentID == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            PhysActor.Orientation = value;
 | 
			
		||||
                            pa.Orientation = value;
 | 
			
		||||
                            //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString());
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            // Child prim we have to calculate it's world rotationwel
 | 
			
		||||
                            Quaternion resultingrotation = GetWorldRotation();
 | 
			
		||||
                            PhysActor.Orientation = resultingrotation;
 | 
			
		||||
                            pa.Orientation = resultingrotation;
 | 
			
		||||
                            //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString());
 | 
			
		||||
                        }
 | 
			
		||||
                        m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
 | 
			
		||||
                        m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
 | 
			
		||||
                        //}
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception ex)
 | 
			
		||||
| 
						 | 
				
			
			@ -650,13 +657,14 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
                //if (PhysActor.Velocity.X != 0 || PhysActor.Velocity.Y != 0
 | 
			
		||||
                //|| PhysActor.Velocity.Z != 0)
 | 
			
		||||
                //{
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (PhysActor.IsPhysical)
 | 
			
		||||
                    if (pa.IsPhysical)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_velocity.X = PhysActor.Velocity.X;
 | 
			
		||||
                        m_velocity.Y = PhysActor.Velocity.Y;
 | 
			
		||||
                        m_velocity.Z = PhysActor.Velocity.Z;
 | 
			
		||||
                        m_velocity.X = pa.Velocity.X;
 | 
			
		||||
                        m_velocity.Y = pa.Velocity.Y;
 | 
			
		||||
                        m_velocity.Z = pa.Velocity.Z;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -666,12 +674,13 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            set
 | 
			
		||||
            {
 | 
			
		||||
                m_velocity = value;
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (PhysActor.IsPhysical)
 | 
			
		||||
                    if (pa.IsPhysical)
 | 
			
		||||
                    {
 | 
			
		||||
                        PhysActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z);
 | 
			
		||||
                        m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
 | 
			
		||||
                        pa.Velocity = new PhysicsVector(value.X, value.Y, value.Z);
 | 
			
		||||
                        m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -688,9 +697,10 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if ((PhysActor != null) && PhysActor.IsPhysical)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if ((pa != null) && pa.IsPhysical)
 | 
			
		||||
                {
 | 
			
		||||
                    m_angularVelocity.FromBytes(PhysActor.RotationalVelocity.GetBytes(), 0);
 | 
			
		||||
                    m_angularVelocity.FromBytes(pa.RotationalVelocity.GetBytes(), 0);
 | 
			
		||||
                }
 | 
			
		||||
                return m_angularVelocity;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -709,10 +719,11 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            get { return m_description; }
 | 
			
		||||
            set 
 | 
			
		||||
            {
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                m_description = value;
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    PhysActor.SOPDescription = value;
 | 
			
		||||
                    pa.SOPDescription = value;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -806,14 +817,15 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
if (m_shape != null) {
 | 
			
		||||
                m_shape.Scale = value;
 | 
			
		||||
 | 
			
		||||
                if (PhysActor != null && m_parentGroup != null)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa != null && m_parentGroup != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (m_parentGroup.Scene != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (m_parentGroup.Scene.PhysicsScene != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            PhysActor.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z);
 | 
			
		||||
                            m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
 | 
			
		||||
                            pa.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z);
 | 
			
		||||
                            m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -1343,13 +1355,14 @@ if (m_shape != null) {
 | 
			
		|||
                        RigidBody);
 | 
			
		||||
 | 
			
		||||
                    // Basic Physics returns null..  joy joy joy.
 | 
			
		||||
                    if (PhysActor != null)
 | 
			
		||||
                    PhysicsActor pa = PhysActor;
 | 
			
		||||
                    if (pa != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
 | 
			
		||||
                        PhysActor.SOPDescription = this.Description;
 | 
			
		||||
                        PhysActor.LocalID = LocalId;
 | 
			
		||||
                        pa.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
 | 
			
		||||
                        pa.SOPDescription = this.Description;
 | 
			
		||||
                        pa.LocalID = LocalId;
 | 
			
		||||
                        DoPhysicsPropertyUpdate(RigidBody, true);
 | 
			
		||||
                        PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
 | 
			
		||||
                        pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1563,23 +1576,24 @@ if (m_shape != null) {
 | 
			
		|||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (UsePhysics != PhysActor.IsPhysical || isNew)
 | 
			
		||||
                    if (UsePhysics != pa.IsPhysical || isNew)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (PhysActor.IsPhysical) // implies UsePhysics==false for this block
 | 
			
		||||
                        if (pa.IsPhysical) // implies UsePhysics==false for this block
 | 
			
		||||
                        {
 | 
			
		||||
                            if (!isNew)
 | 
			
		||||
                                ParentGroup.Scene.RemovePhysicalPrim(1);
 | 
			
		||||
 | 
			
		||||
                            PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
 | 
			
		||||
                            PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
 | 
			
		||||
                            PhysActor.delink();
 | 
			
		||||
                            pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
 | 
			
		||||
                            pa.OnOutOfBounds -= PhysicsOutOfBounds;
 | 
			
		||||
                            pa.delink();
 | 
			
		||||
 | 
			
		||||
                            if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew))
 | 
			
		||||
                            {
 | 
			
		||||
                                // destroy all joints connected to this now deactivated body
 | 
			
		||||
                                m_parentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor);
 | 
			
		||||
                                m_parentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // stop client-side interpolation of all joint proxy objects that have just been deleted
 | 
			
		||||
| 
						 | 
				
			
			@ -1598,7 +1612,7 @@ if (m_shape != null) {
 | 
			
		|||
                            //RotationalVelocity = new Vector3(0, 0, 0);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        PhysActor.IsPhysical = UsePhysics;
 | 
			
		||||
                        pa.IsPhysical = UsePhysics;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        // If we're not what we're supposed to be in the physics scene, recreate ourselves.
 | 
			
		||||
| 
						 | 
				
			
			@ -1612,19 +1626,19 @@ if (m_shape != null) {
 | 
			
		|||
                            {
 | 
			
		||||
                                ParentGroup.Scene.AddPhysicalPrim(1);
 | 
			
		||||
 | 
			
		||||
                                PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
 | 
			
		||||
                                PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
 | 
			
		||||
                                pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
 | 
			
		||||
                                pa.OnOutOfBounds += PhysicsOutOfBounds;
 | 
			
		||||
                                if (_parentID != 0 && _parentID != LocalId)
 | 
			
		||||
                                {
 | 
			
		||||
                                    if (ParentGroup.RootPart.PhysActor != null)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        PhysActor.link(ParentGroup.RootPart.PhysActor);
 | 
			
		||||
                                        pa.link(ParentGroup.RootPart.PhysActor);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
 | 
			
		||||
                    m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1690,9 +1704,10 @@ if (m_shape != null) {
 | 
			
		|||
 | 
			
		||||
        public Vector3 GetGeometricCenter()
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z);
 | 
			
		||||
                return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -1702,9 +1717,10 @@ if (m_shape != null) {
 | 
			
		|||
 | 
			
		||||
        public float GetMass()
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                return PhysActor.Mass;
 | 
			
		||||
                return pa.Mass;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -1714,8 +1730,9 @@ if (m_shape != null) {
 | 
			
		|||
 | 
			
		||||
        public PhysicsVector GetForce()
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
                return PhysActor.Force;
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
                return pa.Force;
 | 
			
		||||
            else
 | 
			
		||||
                return new PhysicsVector();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -2094,11 +2111,15 @@ if (m_shape != null) {
 | 
			
		|||
 | 
			
		||||
        public void PhysicsRequestingTerseUpdate()
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
 | 
			
		||||
                Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
 | 
			
		||||
                
 | 
			
		||||
                if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
 | 
			
		||||
                if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | 
 | 
			
		||||
                    m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | 
 | 
			
		||||
                    m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | 
 | 
			
		||||
                    m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
 | 
			
		||||
                {
 | 
			
		||||
                    m_parentGroup.AbsolutePosition = newpos;
 | 
			
		||||
                    return;
 | 
			
		||||
| 
						 | 
				
			
			@ -2294,14 +2315,15 @@ if (m_shape != null) {
 | 
			
		|||
                    if (texture != null)
 | 
			
		||||
                        m_shape.SculptData = texture.Data;
 | 
			
		||||
 | 
			
		||||
                    if (PhysActor != null)
 | 
			
		||||
                    PhysicsActor pa = PhysActor;
 | 
			
		||||
                    if (pa != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        // Tricks physics engine into thinking we've changed the part shape.
 | 
			
		||||
                        PrimitiveBaseShape m_newshape = m_shape.Copy();
 | 
			
		||||
                        PhysActor.Shape = m_newshape;
 | 
			
		||||
                        pa.Shape = m_newshape;
 | 
			
		||||
                        m_shape = m_newshape;
 | 
			
		||||
 | 
			
		||||
                        m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
 | 
			
		||||
                        m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -2520,9 +2542,10 @@ if (m_shape != null) {
 | 
			
		|||
 | 
			
		||||
        public void SetBuoyancy(float fvalue)
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                PhysActor.Buoyancy = fvalue;
 | 
			
		||||
                pa.Buoyancy = fvalue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2538,56 +2561,62 @@ if (m_shape != null) {
 | 
			
		|||
 | 
			
		||||
        public void SetFloatOnWater(int floatYN)
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                if (floatYN == 1)
 | 
			
		||||
                {
 | 
			
		||||
                    PhysActor.FloatOnWater = true;
 | 
			
		||||
                    pa.FloatOnWater = true;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    PhysActor.FloatOnWater = false;
 | 
			
		||||
                    pa.FloatOnWater = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetForce(PhysicsVector force)
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                PhysActor.Force = force;
 | 
			
		||||
                pa.Force = force;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetVehicleType(int type)
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                PhysActor.VehicleType = type;
 | 
			
		||||
                pa.VehicleType = type;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetVehicleFloatParam(int param, float value)
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                PhysActor.VehicleFloatParam(param, value);
 | 
			
		||||
                pa.VehicleFloatParam(param, value);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetVehicleVectorParam(int param, PhysicsVector value)
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                PhysActor.VehicleVectorParam(param, value);
 | 
			
		||||
                pa.VehicleVectorParam(param, value);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetVehicleRotationParam(int param, Quaternion rotation)
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                PhysActor.VehicleRotationParam(param, rotation);
 | 
			
		||||
                pa.VehicleRotationParam(param, rotation);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2615,10 +2644,11 @@ if (m_shape != null) {
 | 
			
		|||
 | 
			
		||||
        public void SetPhysicsAxisRotation()
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                PhysActor.LockAngularMotion(RotationAxis);
 | 
			
		||||
                m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
 | 
			
		||||
                pa.LockAngularMotion(RotationAxis);
 | 
			
		||||
                m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3350,8 +3380,9 @@ if (m_shape != null) {
 | 
			
		|||
                {
 | 
			
		||||
                    IsVD = false;               // Switch it of for the course of this routine
 | 
			
		||||
                    VolumeDetectActive = false; // and also permanently
 | 
			
		||||
                    if (PhysActor != null)
 | 
			
		||||
                        PhysActor.SetVolumeDetect(0);   // Let physics know about it too
 | 
			
		||||
                    PhysicsActor pa = PhysActor;
 | 
			
		||||
                    if (pa != null)
 | 
			
		||||
                        pa.SetVolumeDetect(0);   // Let physics know about it too
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -3399,18 +3430,21 @@ if (m_shape != null) {
 | 
			
		|||
            if (IsPhantom || IsAttachment) // note: this may have been changed above in the case of joints
 | 
			
		||||
            {
 | 
			
		||||
                AddFlag(PrimFlags.Phantom);
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
 | 
			
		||||
                    m_parentGroup.Scene.PhysicsScene.RemovePrim(pa);
 | 
			
		||||
                    /// that's not wholesome.  Had to make Scene public
 | 
			
		||||
                    PhysActor = null;
 | 
			
		||||
                    pa = null;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else // Not phantom
 | 
			
		||||
            {
 | 
			
		||||
                RemFlag(PrimFlags.Phantom);
 | 
			
		||||
 | 
			
		||||
                if (PhysActor == null)
 | 
			
		||||
                // This is NOT safe!!
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa == null)
 | 
			
		||||
                {
 | 
			
		||||
                    // It's not phantom anymore. So make sure the physics engine get's knowledge of it
 | 
			
		||||
                    PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
 | 
			
		||||
| 
						 | 
				
			
			@ -3421,9 +3455,9 @@ if (m_shape != null) {
 | 
			
		|||
                        RotationOffset,
 | 
			
		||||
                        UsePhysics);
 | 
			
		||||
 | 
			
		||||
                    if (PhysActor != null)
 | 
			
		||||
                    if (pa != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        PhysActor.LocalID = LocalId;
 | 
			
		||||
                        pa.LocalID = LocalId;
 | 
			
		||||
                        DoPhysicsPropertyUpdate(UsePhysics, true);
 | 
			
		||||
                        if (m_parentGroup != null)
 | 
			
		||||
                        {
 | 
			
		||||
| 
						 | 
				
			
			@ -3442,14 +3476,14 @@ if (m_shape != null) {
 | 
			
		|||
                            (CollisionSound != UUID.Zero)
 | 
			
		||||
                            )
 | 
			
		||||
                        {
 | 
			
		||||
                                PhysActor.OnCollisionUpdate += PhysicsCollision;
 | 
			
		||||
                                PhysActor.SubscribeEvents(1000);
 | 
			
		||||
                                pa.OnCollisionUpdate += PhysicsCollision;
 | 
			
		||||
                                pa.SubscribeEvents(1000);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else // it already has a physical representation
 | 
			
		||||
                {
 | 
			
		||||
                    PhysActor.IsPhysical = UsePhysics;                    
 | 
			
		||||
                    pa.IsPhysical = UsePhysics;                    
 | 
			
		||||
 | 
			
		||||
                    DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
 | 
			
		||||
                    if (m_parentGroup != null)
 | 
			
		||||
| 
						 | 
				
			
			@ -3472,9 +3506,10 @@ if (m_shape != null) {
 | 
			
		|||
                // Defensive programming calls for a check here.
 | 
			
		||||
                // Better would be throwing an exception that could be catched by a unit test as the internal 
 | 
			
		||||
                // logic should make sure, this Physactor is always here.
 | 
			
		||||
                if (this.PhysActor != null)
 | 
			
		||||
                PhysicsActor pa = this.PhysActor;
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    PhysActor.SetVolumeDetect(1);
 | 
			
		||||
                    pa.SetVolumeDetect(1);
 | 
			
		||||
                    AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
 | 
			
		||||
                    this.VolumeDetectActive = true;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -3482,10 +3517,11 @@ if (m_shape != null) {
 | 
			
		|||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {   // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
 | 
			
		||||
                // (mumbles, well, at least if you have infinte CPU powers :-))
 | 
			
		||||
                if (this.PhysActor != null)
 | 
			
		||||
                // (mumbles, well, at least if you have infinte CPU powers :-) )
 | 
			
		||||
                PhysicsActor pa = this.PhysActor;
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    PhysActor.SetVolumeDetect(0);
 | 
			
		||||
                    pa.SetVolumeDetect(0);
 | 
			
		||||
                }
 | 
			
		||||
                this.VolumeDetectActive = false;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -3543,10 +3579,11 @@ if (m_shape != null) {
 | 
			
		|||
            m_shape.PathTaperY = shapeBlock.PathTaperY;
 | 
			
		||||
            m_shape.PathTwist = shapeBlock.PathTwist;
 | 
			
		||||
            m_shape.PathTwistBegin = shapeBlock.PathTwistBegin;
 | 
			
		||||
            if (PhysActor != null)
 | 
			
		||||
            PhysicsActor pa = PhysActor;
 | 
			
		||||
            if (pa != null)
 | 
			
		||||
            {
 | 
			
		||||
                PhysActor.Shape = m_shape;
 | 
			
		||||
                m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
 | 
			
		||||
                pa.Shape = m_shape;
 | 
			
		||||
                m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // This is what makes vehicle trailers work
 | 
			
		||||
| 
						 | 
				
			
			@ -3647,19 +3684,21 @@ if (m_shape != null) {
 | 
			
		|||
                )
 | 
			
		||||
            {
 | 
			
		||||
                // subscribe to physics updates.
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    PhysActor.OnCollisionUpdate += PhysicsCollision;
 | 
			
		||||
                    PhysActor.SubscribeEvents(1000);
 | 
			
		||||
                    pa.OnCollisionUpdate += PhysicsCollision;
 | 
			
		||||
                    pa.SubscribeEvents(1000);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (PhysActor != null)
 | 
			
		||||
                PhysicsActor pa = PhysActor;
 | 
			
		||||
                if (pa != null)
 | 
			
		||||
                {
 | 
			
		||||
                    PhysActor.UnSubscribeEvents();
 | 
			
		||||
                    PhysActor.OnCollisionUpdate -= PhysicsCollision;
 | 
			
		||||
                    pa.UnSubscribeEvents();
 | 
			
		||||
                    pa.OnCollisionUpdate -= PhysicsCollision;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2269,7 +2269,7 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
                    {
 | 
			
		||||
                        //Record the time we enter this state so we know whether to "land" or not
 | 
			
		||||
                        m_animPersistUntil = DateTime.Now.Ticks;
 | 
			
		||||
                        return "FALLDOWN";
 | 
			
		||||
                        return "FALLDOWN"; // this falling animation is invoked too frequently when capsule tilt correction is used - why?
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,8 +65,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
 | 
			
		|||
            //m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
 | 
			
		||||
            //int time = System.Environment.TickCount;
 | 
			
		||||
 | 
			
		||||
            SceneObjectGroup sceneObject = new SceneObjectGroup();            
 | 
			
		||||
 | 
			
		||||
            // libomv.types changes UUID to Guid
 | 
			
		||||
            xmlData = xmlData.Replace("<UUID>", "<Guid>");
 | 
			
		||||
            xmlData = xmlData.Replace("</UUID>", "</Guid>");
 | 
			
		||||
| 
						 | 
				
			
			@ -88,17 +86,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
 | 
			
		|||
                parts = doc.GetElementsByTagName("RootPart");
 | 
			
		||||
 | 
			
		||||
                if (parts.Count == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    throw new Exception("Invalid Xml format - no root part");
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    sr = new StringReader(parts[0].InnerXml);
 | 
			
		||||
                    reader = new XmlTextReader(sr);
 | 
			
		||||
                    sceneObject.SetRootPart(SceneObjectPart.FromXml(fromUserInventoryItemID, reader));
 | 
			
		||||
                    reader.Close();
 | 
			
		||||
                    sr.Close();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                sr = new StringReader(parts[0].InnerXml);
 | 
			
		||||
                reader = new XmlTextReader(sr);
 | 
			
		||||
                SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(fromUserInventoryItemID, reader));
 | 
			
		||||
                reader.Close();
 | 
			
		||||
                sr.Close();
 | 
			
		||||
 | 
			
		||||
                parts = doc.GetElementsByTagName("Part");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -119,16 +113,15 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
 | 
			
		|||
                // Script state may, or may not, exist. Not having any, is NOT
 | 
			
		||||
                // ever a problem.
 | 
			
		||||
                sceneObject.LoadScriptState(doc);
 | 
			
		||||
 | 
			
		||||
                return sceneObject;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.ErrorFormat(
 | 
			
		||||
                    "[SERIALIZER]: Deserialization of xml failed with {0}.  xml was {1}", e, xmlData);
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //m_log.DebugFormat("[SERIALIZER]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time);
 | 
			
		||||
 | 
			
		||||
            return sceneObject;
 | 
			
		||||
        }      
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -194,8 +187,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
 | 
			
		|||
        {
 | 
			
		||||
            //m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
 | 
			
		||||
            //int time = System.Environment.TickCount;
 | 
			
		||||
 | 
			
		||||
            SceneObjectGroup sceneObject = new SceneObjectGroup();
 | 
			
		||||
            
 | 
			
		||||
            // libomv.types changes UUID to Guid
 | 
			
		||||
            xmlData = xmlData.Replace("<UUID>", "<Guid>");
 | 
			
		||||
| 
						 | 
				
			
			@ -212,21 +203,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
 | 
			
		|||
 | 
			
		||||
                XmlNodeList parts = doc.GetElementsByTagName("SceneObjectPart");
 | 
			
		||||
 | 
			
		||||
                // Process the root part first
 | 
			
		||||
                if (parts.Count > 0)
 | 
			
		||||
                if (parts.Count == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    StringReader      sr = new StringReader(parts[0].OuterXml);
 | 
			
		||||
                    XmlTextReader reader = new XmlTextReader(sr);
 | 
			
		||||
                    sceneObject.SetRootPart(SceneObjectPart.FromXml(reader));
 | 
			
		||||
                    reader.Close();
 | 
			
		||||
                    sr.Close();
 | 
			
		||||
                    m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed: No SceneObjectPart nodes. xml was " + xmlData);
 | 
			
		||||
                    return null;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                StringReader sr = new StringReader(parts[0].OuterXml);
 | 
			
		||||
                XmlTextReader reader = new XmlTextReader(sr);
 | 
			
		||||
                SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader));
 | 
			
		||||
                reader.Close();
 | 
			
		||||
                sr.Close();
 | 
			
		||||
 | 
			
		||||
                // Then deal with the rest
 | 
			
		||||
                for (int i = 1; i < parts.Count; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    StringReader      sr = new StringReader(parts[i].OuterXml);
 | 
			
		||||
                    XmlTextReader reader = new XmlTextReader(sr);
 | 
			
		||||
                    sr = new StringReader(parts[i].OuterXml);
 | 
			
		||||
                    reader = new XmlTextReader(sr);
 | 
			
		||||
                    SceneObjectPart part = SceneObjectPart.FromXml(reader);
 | 
			
		||||
                    sceneObject.AddPart(part);
 | 
			
		||||
                    part.StoreUndoState();
 | 
			
		||||
| 
						 | 
				
			
			@ -238,15 +231,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
 | 
			
		|||
                // ever a problem.
 | 
			
		||||
 | 
			
		||||
                sceneObject.LoadScriptState(doc);
 | 
			
		||||
                return sceneObject;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed with {0}.  xml was {1}", e, xmlData);
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //m_log.DebugFormat("[SERIALIZER]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time);
 | 
			
		||||
 | 
			
		||||
            return sceneObject;
 | 
			
		||||
        }         
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,7 +128,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
 | 
			
		|||
 | 
			
		||||
        private SceneObjectGroup NewSOG()
 | 
			
		||||
        {
 | 
			
		||||
            SceneObjectGroup sog = new SceneObjectGroup();
 | 
			
		||||
            SceneObjectPart sop = new SceneObjectPart(UUID.Random(), PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero);
 | 
			
		||||
            sop.Name = RandomName();
 | 
			
		||||
            sop.Description = sop.Name;
 | 
			
		||||
| 
						 | 
				
			
			@ -136,9 +135,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
 | 
			
		|||
            sop.SitName = RandomName();
 | 
			
		||||
            sop.TouchName = RandomName();
 | 
			
		||||
            sop.ObjectFlags |= (uint)PrimFlags.Phantom;
 | 
			
		||||
            
 | 
			
		||||
            sog.SetRootPart(sop);
 | 
			
		||||
 | 
			
		||||
            SceneObjectGroup sog = new SceneObjectGroup(sop);
 | 
			
		||||
            scene.AddNewSceneObject(sog, false);
 | 
			
		||||
            
 | 
			
		||||
            return sog;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -407,9 +407,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
 | 
			
		|||
            sop.Shape.State = 1;
 | 
			
		||||
            sop.OwnerID = agent;
 | 
			
		||||
 | 
			
		||||
            SceneObjectGroup sog = new SceneObjectGroup();
 | 
			
		||||
            SceneObjectGroup sog = new SceneObjectGroup(sop);
 | 
			
		||||
            sog.SetScene(scene);
 | 
			
		||||
            sog.SetRootPart(sop);
 | 
			
		||||
 | 
			
		||||
            return sog;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ using System.Text.RegularExpressions;
 | 
			
		|||
 | 
			
		||||
namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
 | 
			
		||||
{
 | 
			
		||||
    public class FreeSwitchVoiceModule : IRegionModule
 | 
			
		||||
    public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -101,13 +101,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
 | 
			
		|||
        private FreeSwitchDialplan m_FreeSwitchDialplan;
 | 
			
		||||
 | 
			
		||||
        private readonly Dictionary<string, string> m_UUIDName = new Dictionary<string, string>();
 | 
			
		||||
        private Dictionary<string, string> m_ParcelAddress = new Dictionary<string, string>();
 | 
			
		||||
        
 | 
			
		||||
        private Scene m_scene;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        private IConfig m_config;
 | 
			
		||||
 | 
			
		||||
        public void Initialise(Scene scene, IConfigSource config)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            m_scene = scene;
 | 
			
		||||
            m_config = config.Configs["FreeSwitchVoice"];
 | 
			
		||||
 | 
			
		||||
            if (null == m_config)
 | 
			
		||||
| 
						 | 
				
			
			@ -230,6 +233,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
 | 
			
		|||
                    {
 | 
			
		||||
                        OnRegisterCaps(scene, agentID, caps);
 | 
			
		||||
                    };
 | 
			
		||||
                    
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -255,6 +260,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
 | 
			
		|||
        
 | 
			
		||||
        public void PostInitialise()
 | 
			
		||||
        {
 | 
			
		||||
            if(m_pluginEnabled)
 | 
			
		||||
            {
 | 
			
		||||
	            m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene");
 | 
			
		||||
	            
 | 
			
		||||
	            // register the voice interface for this module, so the script engine can call us
 | 
			
		||||
	            m_scene.RegisterModuleInterface<IVoiceModule>(this);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Close()
 | 
			
		||||
| 
						 | 
				
			
			@ -270,7 +282,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
 | 
			
		|||
        {
 | 
			
		||||
            get { return true; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        // <summary>
 | 
			
		||||
        // implementation of IVoiceModule, called by osSetParcelSIPAddress script function
 | 
			
		||||
        // </summary>
 | 
			
		||||
        public void setLandSIPAddress(string SIPAddress,UUID GlobalID)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.DebugFormat("[FreeSwitchVoice]: setLandSIPAddress parcel id {0}: setting sip address {1}", 
 | 
			
		||||
                                  GlobalID, SIPAddress);
 | 
			
		||||
                                  
 | 
			
		||||
            lock (m_ParcelAddress)
 | 
			
		||||
            {
 | 
			
		||||
                if (m_ParcelAddress.ContainsKey(GlobalID.ToString()))
 | 
			
		||||
                {
 | 
			
		||||
                    m_ParcelAddress[GlobalID.ToString()] = SIPAddress;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    m_ParcelAddress.Add(GlobalID.ToString(), SIPAddress);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // <summary>
 | 
			
		||||
        // OnRegisterCaps is invoked via the scene.EventManager
 | 
			
		||||
| 
						 | 
				
			
			@ -776,6 +808,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
 | 
			
		|||
 | 
			
		||||
            // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same
 | 
			
		||||
            // as the directory ID. Otherwise, it reflects the parcel's ID.
 | 
			
		||||
            
 | 
			
		||||
            lock (m_ParcelAddress)
 | 
			
		||||
            {
 | 
			
		||||
                if (m_ParcelAddress.ContainsKey( land.GlobalID.ToString() ))
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.DebugFormat("[FreeSwitchVoice]: parcel id {0}: using sip address {1}", 
 | 
			
		||||
                                      land.GlobalID, m_ParcelAddress[land.GlobalID.ToString()]);
 | 
			
		||||
                    return m_ParcelAddress[land.GlobalID.ToString()];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (land.LocalID != 1 && (land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -797,6 +839,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
 | 
			
		|||
            // the personal speech indicators as well unless some siren14-3d codec magic happens. we dont have siren143d so we'll settle for the personal speech indicator.
 | 
			
		||||
            channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm);
 | 
			
		||||
            
 | 
			
		||||
            lock (m_ParcelAddress)
 | 
			
		||||
            {
 | 
			
		||||
                if (!m_ParcelAddress.ContainsKey(land.GlobalID.ToString()))
 | 
			
		||||
                {
 | 
			
		||||
                    m_ParcelAddress.Add(land.GlobalID.ToString(),channelUri);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return channelUri;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -281,7 +281,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
 | 
			
		||||
        private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
 | 
			
		||||
        {
 | 
			
		||||
            GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray();
 | 
			
		||||
            if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
 | 
			
		||||
 | 
			
		||||
            //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray();
 | 
			
		||||
            GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID);
 | 
			
		||||
            remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -485,6 +488,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
                        bucket[18] = 0; //dunno
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    
 | 
			
		||||
                    m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket);
 | 
			
		||||
                    if (OnNewGroupNotice != null)
 | 
			
		||||
                    {
 | 
			
		||||
| 
						 | 
				
			
			@ -494,7 +498,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
                    // Send notice out to everyone that wants notices
 | 
			
		||||
                    foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID))
 | 
			
		||||
                    {
 | 
			
		||||
                        if (member.AcceptNotices)
 | 
			
		||||
                         if (m_debugEnabled)
 | 
			
		||||
                        {
 | 
			
		||||
                            UserProfileData targetUserProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(member.AgentID);
 | 
			
		||||
                            if (targetUserProfile != null)
 | 
			
		||||
                            {
 | 
			
		||||
                                m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUserProfile.Name, member.AcceptNotices);
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                       if (member.AcceptNotices)
 | 
			
		||||
                        {
 | 
			
		||||
                            // Build notice IIM
 | 
			
		||||
                            GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
 | 
			
		||||
| 
						 | 
				
			
			@ -614,13 +631,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
            if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
 | 
			
		||||
 | 
			
		||||
            List<GroupMembersData> data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID);
 | 
			
		||||
            if (m_debugEnabled)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (GroupMembersData member in data)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.DebugFormat("[GROUPS]: {0} {1}", member.AgentID, member.Title);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return data;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -632,14 +642,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
 | 
			
		||||
            List<GroupRolesData> data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID);
 | 
			
		||||
 | 
			
		||||
            if (m_debugEnabled)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (GroupRolesData member in data)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.DebugFormat("[GROUPS]: {0} {1}", member.Title, member.Members);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return data;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -650,14 +652,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
 | 
			
		||||
            List<GroupRoleMembersData> data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID);
 | 
			
		||||
 | 
			
		||||
            if (m_debugEnabled)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (GroupRoleMembersData member in data)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.DebugFormat("[GROUPS]: Av: {0}  Role: {1}", member.MemberID, member.RoleID);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            return data;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -808,7 +802,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
        {
 | 
			
		||||
            if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
 | 
			
		||||
 | 
			
		||||
            // TODO: Security Checks?
 | 
			
		||||
            // Security Checks are handled in the Groups Service.
 | 
			
		||||
 | 
			
		||||
            GroupRequestID grID = GetClientGroupRequestID(remoteClient);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -825,6 +819,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
                case OpenMetaverse.GroupRoleUpdate.UpdateAll:
 | 
			
		||||
                case OpenMetaverse.GroupRoleUpdate.UpdateData:
 | 
			
		||||
                case OpenMetaverse.GroupRoleUpdate.UpdatePowers:
 | 
			
		||||
                    if (m_debugEnabled)
 | 
			
		||||
                    {
 | 
			
		||||
                        GroupPowers gp = (GroupPowers)powers;
 | 
			
		||||
                        m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString());
 | 
			
		||||
                    }
 | 
			
		||||
                    m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1195,6 +1194,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
 | 
			
		||||
            foreach (GroupMembershipData membership in data)
 | 
			
		||||
            {
 | 
			
		||||
                if (remoteClient.AgentId != dataForAgentID)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!membership.ListInProfile)
 | 
			
		||||
                    {
 | 
			
		||||
                        // If we're sending group info to remoteclient about another agent, 
 | 
			
		||||
                        // filter out groups the other agent doesn't want to share.
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                OSDMap GroupDataMap = new OSDMap(6);
 | 
			
		||||
                OSDMap NewGroupDataMap = new OSDMap(1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1281,11 +1290,46 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
            // to the core Groups Stub
 | 
			
		||||
            remoteClient.SendGroupMembership(new GroupMembershipData[0]);
 | 
			
		||||
 | 
			
		||||
            GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID).ToArray();
 | 
			
		||||
            GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID);
 | 
			
		||||
            SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray);
 | 
			
		||||
            remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray);
 | 
			
		||||
 | 
			
		||||
            SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipData);
 | 
			
		||||
            remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipData);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get a list of groups memberships for the agent that are marked "ListInProfile"
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="dataForAgentID"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID)
 | 
			
		||||
        {
 | 
			
		||||
            List<GroupMembershipData> membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID);
 | 
			
		||||
            GroupMembershipData[] membershipArray;
 | 
			
		||||
 | 
			
		||||
            if (requestingClient.AgentId != dataForAgentID)
 | 
			
		||||
            {
 | 
			
		||||
                Predicate<GroupMembershipData> showInProfile = delegate(GroupMembershipData membership)
 | 
			
		||||
                {
 | 
			
		||||
                    return membership.ListInProfile;
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                membershipArray = membershipData.FindAll(showInProfile).ToArray();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                membershipArray = membershipData.ToArray();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (m_debugEnabled)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId);
 | 
			
		||||
                foreach (GroupMembershipData membership in membershipArray)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return membershipArray;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -855,16 +855,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
            IList parameters = new ArrayList();
 | 
			
		||||
            parameters.Add(param);
 | 
			
		||||
 | 
			
		||||
            XmlRpcRequest req;
 | 
			
		||||
            if (!m_disableKeepAlive)
 | 
			
		||||
            {
 | 
			
		||||
                req = new XmlRpcRequest(function, parameters);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // This seems to solve a major problem on some windows servers
 | 
			
		||||
                req = new NoKeepAliveXmlRpcRequest(function, parameters);
 | 
			
		||||
            }
 | 
			
		||||
            ConfigurableKeepAliveXmlRpcRequest req;
 | 
			
		||||
            req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive);
 | 
			
		||||
 | 
			
		||||
            XmlRpcResponse resp = null;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -874,10 +866,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
 | 
			
		|||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
                m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function);
 | 
			
		||||
                m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString());
 | 
			
		||||
 | 
			
		||||
                                
 | 
			
		||||
                foreach( string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None))
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                foreach (string key in param.Keys)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString());
 | 
			
		||||
| 
						 | 
				
			
			@ -961,20 +959,24 @@ namespace Nwc.XmlRpc
 | 
			
		|||
    using System.Reflection;
 | 
			
		||||
 | 
			
		||||
    /// <summary>Class supporting the request side of an XML-RPC transaction.</summary>
 | 
			
		||||
    public class NoKeepAliveXmlRpcRequest : XmlRpcRequest
 | 
			
		||||
    public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest
 | 
			
		||||
    {
 | 
			
		||||
        private Encoding _encoding = new ASCIIEncoding();
 | 
			
		||||
        private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer();
 | 
			
		||||
        private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer();
 | 
			
		||||
        private bool _disableKeepAlive = true;
 | 
			
		||||
 | 
			
		||||
        public string RequestResponse = String.Empty;
 | 
			
		||||
 | 
			
		||||
        /// <summary>Instantiate an <c>XmlRpcRequest</c> for a specified method and parameters.</summary>
 | 
			
		||||
        /// <param name="methodName"><c>String</c> designating the <i>object.method</i> on the server the request
 | 
			
		||||
        /// should be directed to.</param>
 | 
			
		||||
        /// <param name="parameters"><c>ArrayList</c> of XML-RPC type parameters to invoke the request with.</param>
 | 
			
		||||
        public NoKeepAliveXmlRpcRequest(String methodName, IList parameters)
 | 
			
		||||
        public ConfigurableKeepAliveXmlRpcRequest(String methodName, IList parameters, bool disableKeepAlive)
 | 
			
		||||
        {
 | 
			
		||||
            MethodName = methodName;
 | 
			
		||||
            _params = parameters;
 | 
			
		||||
            _disableKeepAlive = disableKeepAlive;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>Send the request to the server.</summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -989,7 +991,7 @@ namespace Nwc.XmlRpc
 | 
			
		|||
            request.Method = "POST";
 | 
			
		||||
            request.ContentType = "text/xml";
 | 
			
		||||
            request.AllowWriteStreamBuffering = true;
 | 
			
		||||
            request.KeepAlive = false;
 | 
			
		||||
            request.KeepAlive = !_disableKeepAlive;
 | 
			
		||||
 | 
			
		||||
            Stream stream = request.GetRequestStream();
 | 
			
		||||
            XmlTextWriter xml = new XmlTextWriter(stream, _encoding);
 | 
			
		||||
| 
						 | 
				
			
			@ -1000,7 +1002,17 @@ namespace Nwc.XmlRpc
 | 
			
		|||
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 | 
			
		||||
            StreamReader input = new StreamReader(response.GetResponseStream());
 | 
			
		||||
 | 
			
		||||
            XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input);
 | 
			
		||||
            string inputXml = input.ReadToEnd();
 | 
			
		||||
            XmlRpcResponse resp;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                RequestResponse = inputXml;
 | 
			
		||||
                throw e;
 | 
			
		||||
            }
 | 
			
		||||
            input.Close();
 | 
			
		||||
            response.Close();
 | 
			
		||||
            return resp;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,7 +66,6 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
 | 
			
		|||
 | 
			
		||||
        private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos)
 | 
			
		||||
        {
 | 
			
		||||
            SceneObjectGroup x = new SceneObjectGroup();
 | 
			
		||||
            SceneObjectPart y = new SceneObjectPart();
 | 
			
		||||
 | 
			
		||||
            //Initialize part
 | 
			
		||||
| 
						 | 
				
			
			@ -93,8 +92,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
 | 
			
		|||
            y.TrimPermissions();
 | 
			
		||||
 | 
			
		||||
            //Initialize group and add part as root part
 | 
			
		||||
            SceneObjectGroup x = new SceneObjectGroup(y);
 | 
			
		||||
            x.SetScene(scene);
 | 
			
		||||
            x.SetRootPart(y);
 | 
			
		||||
            x.RegionHandle = scene.RegionInfo.RegionHandle;
 | 
			
		||||
            x.SetScene(scene);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,6 +107,7 @@ namespace OpenSim.Region.Physics.OdePlugin
 | 
			
		|||
        public float MinimumGroundFlightOffset = 3f;
 | 
			
		||||
 | 
			
		||||
        private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes. 
 | 
			
		||||
        private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f; // used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private float m_buoyancy = 0f;
 | 
			
		||||
| 
						 | 
				
			
			@ -477,7 +478,71 @@ namespace OpenSim.Region.Physics.OdePlugin
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        private void AlignAvatarTiltWithCurrentDirectionOfMovement(PhysicsVector movementVector)
 | 
			
		||||
        {
 | 
			
		||||
            movementVector.Z = 0f;
 | 
			
		||||
            float magnitude = (float)Math.Sqrt((double)(movementVector.X * movementVector.X + movementVector.Y * movementVector.Y));
 | 
			
		||||
            if (magnitude < 0.1f) return;
 | 
			
		||||
 | 
			
		||||
            // normalize the velocity vector
 | 
			
		||||
            float invMagnitude = 1.0f / magnitude;
 | 
			
		||||
            movementVector.X *= invMagnitude;
 | 
			
		||||
            movementVector.Y *= invMagnitude;
 | 
			
		||||
 | 
			
		||||
            // if we change the capsule heading too often, the capsule can fall down
 | 
			
		||||
            // therefore we snap movement vector to just 1 of 4 predefined directions (ne, nw, se, sw),
 | 
			
		||||
            // meaning only 4 possible capsule tilt orientations
 | 
			
		||||
            if (movementVector.X > 0)
 | 
			
		||||
            {
 | 
			
		||||
                // east
 | 
			
		||||
                if (movementVector.Y > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    // northeast
 | 
			
		||||
                    movementVector.X = (float)Math.Sqrt(2.0);
 | 
			
		||||
                    movementVector.Y = (float)Math.Sqrt(2.0);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // southeast
 | 
			
		||||
                    movementVector.X = (float)Math.Sqrt(2.0);
 | 
			
		||||
                    movementVector.Y = -(float)Math.Sqrt(2.0);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // west
 | 
			
		||||
                if (movementVector.Y > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    // northwest
 | 
			
		||||
                    movementVector.X = -(float)Math.Sqrt(2.0);
 | 
			
		||||
                    movementVector.Y = (float)Math.Sqrt(2.0);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // southwest
 | 
			
		||||
                    movementVector.X = -(float)Math.Sqrt(2.0);
 | 
			
		||||
                    movementVector.Y = -(float)Math.Sqrt(2.0);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // movementVector.Z is zero
 | 
			
		||||
 | 
			
		||||
            // calculate tilt components based on desired amount of tilt and current (snapped) heading.
 | 
			
		||||
            // the "-" sign is to force the tilt to be OPPOSITE the direction of movement.
 | 
			
		||||
            float xTiltComponent = -movementVector.X * m_tiltMagnitudeWhenProjectedOnXYPlane;
 | 
			
		||||
            float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane;
 | 
			
		||||
 | 
			
		||||
            //m_log.Debug("[PHYSICS] changing avatar tilt");
 | 
			
		||||
            d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent);
 | 
			
		||||
            d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced
 | 
			
		||||
            d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent);
 | 
			
		||||
            d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, yTiltComponent); // same as lowstop
 | 
			
		||||
            d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, 0f);
 | 
			
		||||
            d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// This creates the Avatar's physical Surrogate at the position supplied
 | 
			
		||||
        /// </summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -576,71 +641,13 @@ namespace OpenSim.Region.Physics.OdePlugin
 | 
			
		|||
                // (with -0..0 motor stops) falls into the terrain for reasons yet
 | 
			
		||||
                // to be comprehended in their entirety.
 | 
			
		||||
                #endregion
 | 
			
		||||
                AlignAvatarTiltWithCurrentDirectionOfMovement(new PhysicsVector(0,0,0));
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f);
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f);
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f);
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.HiStop,  0.08f); // must be same as lowstop, else a different, spurious tilt is introduced
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop
 | 
			
		||||
                #region Documentation of capsule motor StopERP and StopCFM parameters
 | 
			
		||||
                // In addition to the above tilt, we allow a dynamic tilt, or
 | 
			
		||||
                // wobble, to emerge as the capsule is pushed around the environment.
 | 
			
		||||
                // We do this with an experimentally determined combination of
 | 
			
		||||
                // StopERP and StopCFM which make the above motor stops soft.
 | 
			
		||||
                // The softness of the stops should be tweaked according to two
 | 
			
		||||
                // requirements:
 | 
			
		||||
                //
 | 
			
		||||
                // 1. Motor stops should be weak enough to allow enough wobble such 
 | 
			
		||||
                // that the capsule can tilt slightly more when moving, to allow 
 | 
			
		||||
                // "gliding" over obstacles:
 | 
			
		||||
                //
 | 
			
		||||
                // 
 | 
			
		||||
                //                                        .-.
 | 
			
		||||
                //                                       / /
 | 
			
		||||
                //                                      / /
 | 
			
		||||
                //     _                               / /       _ 
 | 
			
		||||
                //    / \                     .-.     / /       / \
 | 
			
		||||
                //    | | ---->              / /     / /        | |
 | 
			
		||||
                //    | |                   / /     `-'         | |
 | 
			
		||||
                //    | |                  / / +------+         | |
 | 
			
		||||
                //    | |                 / /  |      |         | |
 | 
			
		||||
                //    | |                / /   |      |         | |
 | 
			
		||||
                //    \_/               `-'    +------+         \_/
 | 
			
		||||
                // ----------------------------------------------------------
 | 
			
		||||
                // 
 | 
			
		||||
                // Note that requirement 1 is made complicated by the ever-present
 | 
			
		||||
                // slight avatar tilt (assigned in the above code to prevent avatar
 | 
			
		||||
                // from falling through terrain), which introduces a direction-dependent
 | 
			
		||||
                // bias into the wobble (wobbling against the existing tilt is harder
 | 
			
		||||
                // than wobbling with the tilt), which makes it easier to walk over
 | 
			
		||||
                // prims from some directions. I have tried to minimize this effect by
 | 
			
		||||
                // minimizing the avatar tilt to the minimum that prevents the avatar from
 | 
			
		||||
                // falling through the terrain.
 | 
			
		||||
                // 
 | 
			
		||||
                // 2. Motor stops should be strong enough to prevent the capsule
 | 
			
		||||
                // from being forced all the way to the ground; otherwise the
 | 
			
		||||
                // capsule could slip underneath obstacles like this:
 | 
			
		||||
                //     _                                         _ 
 | 
			
		||||
                //    / \                      +------+         / \
 | 
			
		||||
                //    | | ---->                |      |         | |
 | 
			
		||||
                //    | |                      |      |         | |
 | 
			
		||||
                //    | |             .--.___  +------+         | |
 | 
			
		||||
                //    | |              `--.__`--.__             | |
 | 
			
		||||
                //    | |                    `--.__`--.         | |
 | 
			
		||||
                //    \_/                          `--'         \_/
 | 
			
		||||
                // ----------------------------------------------------------
 | 
			
		||||
                // 
 | 
			
		||||
                //
 | 
			
		||||
                // It is strongly recommended you enable USE_DRAWSTUFF if you want to
 | 
			
		||||
                // tweak these values, to see how the capsule is reacting in various
 | 
			
		||||
                // situations.
 | 
			
		||||
                #endregion
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0.0035f); 
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0.0035f);
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0.0035f);
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f);
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f);
 | 
			
		||||
                d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Fudge factor is 1f by default, we're setting it to 0.  We don't want it to Fudge or the
 | 
			
		||||
| 
						 | 
				
			
			@ -939,6 +946,7 @@ namespace OpenSim.Region.Physics.OdePlugin
 | 
			
		|||
 | 
			
		||||
            PhysicsVector vec = new PhysicsVector();
 | 
			
		||||
            d.Vector3 vel = d.BodyGetLinearVel(Body);
 | 
			
		||||
 | 
			
		||||
            float movementdivisor = 1f;
 | 
			
		||||
 | 
			
		||||
            if (!m_alwaysRun)
 | 
			
		||||
| 
						 | 
				
			
			@ -1052,6 +1060,10 @@ namespace OpenSim.Region.Physics.OdePlugin
 | 
			
		|||
            if (PhysicsVector.isFinite(vec))
 | 
			
		||||
            {
 | 
			
		||||
                doForce(vec);
 | 
			
		||||
                if (!_zeroFlag)
 | 
			
		||||
                {
 | 
			
		||||
                  AlignAvatarTiltWithCurrentDirectionOfMovement(new PhysicsVector(vec.X, vec.Y, vec.Z));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1164,6 +1164,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 | 
			
		|||
 | 
			
		||||
            land.SetMediaUrl(url);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public void osSetParcelSIPAddress(string SIPAddress)
 | 
			
		||||
        {
 | 
			
		||||
            // What actually is the difference to the LL function?
 | 
			
		||||
            //
 | 
			
		||||
            CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL");
 | 
			
		||||
 | 
			
		||||
            m_host.AddScriptLPS(1);
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            ILandObject land
 | 
			
		||||
                = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
 | 
			
		||||
 | 
			
		||||
            if (land.landData.OwnerID != m_host.ObjectOwner)
 | 
			
		||||
            {
 | 
			
		||||
                OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            // get the voice module
 | 
			
		||||
            IVoiceModule voiceModule = World.RequestModuleInterface<IVoiceModule>();
 | 
			
		||||
            
 | 
			
		||||
            if (voiceModule != null) 
 | 
			
		||||
                voiceModule.setLandSIPAddress(SIPAddress,land.landData.GlobalID);
 | 
			
		||||
            else
 | 
			
		||||
                OSSLError("osSetParcelSIPAddress: No voice module enabled for this land");
 | 
			
		||||
            
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string osGetScriptEngineName()
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,6 +75,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
 | 
			
		|||
        bool osConsoleCommand(string Command);
 | 
			
		||||
        void osSetParcelMediaURL(string url);
 | 
			
		||||
        void osSetPrimFloatOnWater(int floatYN);
 | 
			
		||||
        void osSetParcelSIPAddress(string SIPAddress);
 | 
			
		||||
 | 
			
		||||
        // Avatar Info Commands
 | 
			
		||||
        string osGetAgentIP(string agent);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -183,6 +183,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
 | 
			
		|||
        {
 | 
			
		||||
            m_OSSL_Functions.osSetParcelMediaURL(url);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public void osSetParcelSIPAddress(string SIPAddress)
 | 
			
		||||
        {
 | 
			
		||||
            m_OSSL_Functions.osSetParcelSIPAddress(SIPAddress);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void osSetPrimFloatOnWater(int floatYN)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -236,42 +236,8 @@ namespace OpenSim.Services.Connectors
 | 
			
		|||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                // Maybe we're talking to an old inventory server. Try this other thing.
 | 
			
		||||
                m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed, {0} {1} (old server?). Trying GetInventory.",
 | 
			
		||||
                m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed, {0} {1} (old server?).",
 | 
			
		||||
                     e.Source, e.Message);
 | 
			
		||||
 | 
			
		||||
                InventoryCollection inventory;
 | 
			
		||||
                List<InventoryFolderBase> folders = null;
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    inventory = SynchronousRestSessionObjectPoster<Guid, InventoryCollection>.BeginPostObject(
 | 
			
		||||
                        "POST", m_ServerURI + "/GetInventory/", new Guid(userID), sessionID.ToString(), userID.ToString());
 | 
			
		||||
                    if (inventory != null)
 | 
			
		||||
                        folders = inventory.Folders;
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetInventory operation also failed, {0} {1}. Giving up.",
 | 
			
		||||
                         e.Source, ex.Message);
 | 
			
		||||
                    return new InventoryCollection();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if ((folders != null) && (folders.Count > 0))
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.DebugFormat("[INVENTORY CONNECTOR]: Received entire inventory ({0} folders) for user {1}",
 | 
			
		||||
                        folders.Count, userID);
 | 
			
		||||
 | 
			
		||||
                    folders = folders.FindAll(delegate(InventoryFolderBase f) { return f.ParentID == folderID; });
 | 
			
		||||
                    List<InventoryItemBase> items = inventory.Items;
 | 
			
		||||
                    if (items != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        items = items.FindAll(delegate(InventoryItemBase i) { return i.Folder == folderID; });
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    inventory.Items = items;
 | 
			
		||||
                    inventory.Folders = folders;
 | 
			
		||||
                    return inventory;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            InventoryCollection nullCollection = new InventoryCollection();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,15 +72,5 @@ namespace OpenSim.Tests.Common.Setup
 | 
			
		|||
 | 
			
		||||
        public static byte[] EmptyByteArray = new byte[] {};
 | 
			
		||||
 | 
			
		||||
        public static void BaseTestHandleNoParams(BaseGetAssetStreamHandler handler, string assetsPath)
 | 
			
		||||
        {
 | 
			
		||||
            Assert.AreEqual(EmptyByteArray, handler.Handle(assetsPath, null, null, null), "Failed on empty params.");
 | 
			
		||||
            Assert.AreEqual(EmptyByteArray, handler.Handle(assetsPath + "/", null, null, null), "Failed on single slash.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void BaseTestHandleMalformedGuid(BaseGetAssetStreamHandler handler, string assetsPath)
 | 
			
		||||
        {
 | 
			
		||||
            Assert.AreEqual(EmptyByteArray, handler.Handle(assetsPath + "/badGuid", null, null, null), "Failed on bad guid.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,122 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using NUnit.Framework;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Server.Base;
 | 
			
		||||
using OpenSim.Tests.Common.Mock;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Tests.Common.Setup
 | 
			
		||||
{
 | 
			
		||||
    public class GetAssetStreamHandlerTestHelpers
 | 
			
		||||
    {
 | 
			
		||||
        private const string EXPECTED_CONTENT_TYPE = "application/x-metaverse-callingcard";
 | 
			
		||||
 | 
			
		||||
        public static void BaseFetchExistingAssetXmlTest(AssetBase asset, BaseGetAssetStreamHandler handler, OSHttpResponse response)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] expected = BaseGetAssetStreamHandler.GetXml(asset);
 | 
			
		||||
 | 
			
		||||
            byte[] actual = handler.Handle("/assets/" + asset.ID , null, null, response);
 | 
			
		||||
 | 
			
		||||
            Assert.Greater(actual.Length, 10, "Too short xml on fetching xml without trailing slash.");
 | 
			
		||||
            Assert.AreEqual(expected, actual, "Failed on fetching xml without trailing slash.");            
 | 
			
		||||
            // Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on first fetch."); 
 | 
			
		||||
 | 
			
		||||
            actual = handler.Handle("/assets/" + asset.ID + "/", null, null, response);
 | 
			
		||||
            Assert.Greater(actual.Length, 10, "Too short xml on fetching xml with trailing slash.");
 | 
			
		||||
            Assert.AreEqual(expected, actual, "Failed on fetching xml with trailing slash.");
 | 
			
		||||
            // Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch.");
 | 
			
		||||
            
 | 
			
		||||
            actual = handler.Handle("/assets/" + asset.ID + "/badData", null, null, response);
 | 
			
		||||
            Assert.Greater(actual.Length, 10, "Too short xml on fetching xml with bad trailing data.");
 | 
			
		||||
            Assert.AreEqual(expected, actual, "Failed on fetching xml with bad trailing trailing slash.");
 | 
			
		||||
            // Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void BaseFetchExistingAssetDataTest(AssetBase asset, BaseGetAssetStreamHandler handler, OSHttpResponse response)
 | 
			
		||||
        {
 | 
			
		||||
            Assert.AreEqual(asset.Data, handler.Handle("/assets/" + asset.ID + "/data", null, null, response), "Failed on fetching data without trailing slash.");
 | 
			
		||||
            Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on first fetch.");
 | 
			
		||||
            Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on first fetch.");
 | 
			
		||||
 | 
			
		||||
            Assert.AreEqual(asset.Data, handler.Handle("/assets/" + asset.ID + "/data/", null, null, response), "Failed on fetching data with trailing slash.");
 | 
			
		||||
            Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch.");
 | 
			
		||||
            Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on second fetch.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void BaseFetchExistingAssetMetaDataTest(AssetBase asset, BaseGetAssetStreamHandler handler, OSHttpResponse response)
 | 
			
		||||
        {
 | 
			
		||||
            XmlSerializer xs = new XmlSerializer(typeof(AssetMetadata));
 | 
			
		||||
 | 
			
		||||
            byte[] expected = ServerUtils.SerializeResult(xs, asset.Metadata);
 | 
			
		||||
 | 
			
		||||
            Assert.AreEqual(expected, handler.Handle("/assets/" + asset.ID + "/metadata", null, null, response), "Failed on fetching data without trailing slash.");
 | 
			
		||||
            Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on first fetch.");
 | 
			
		||||
            Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on first fetch.");
 | 
			
		||||
 | 
			
		||||
            Assert.AreEqual(expected, handler.Handle("/assets/" + asset.ID + "/metadata/", null, null, response), "Failed on fetching data with trailing slash.");
 | 
			
		||||
            Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch.");
 | 
			
		||||
            Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on second fetch.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static AssetBase CreateCommonTestResources(out OSHttpResponse response)
 | 
			
		||||
        {
 | 
			
		||||
            AssetBase asset = CreateTestAsset();
 | 
			
		||||
            response = new TestOSHttpResponse();
 | 
			
		||||
            return asset;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static AssetBase CreateTestAsset()
 | 
			
		||||
        {
 | 
			
		||||
            byte[] expected = new byte[] { 1,2,3 };
 | 
			
		||||
            AssetBase asset = new AssetBase();
 | 
			
		||||
            asset.ID = Guid.NewGuid().ToString();
 | 
			
		||||
            asset.Data = expected;
 | 
			
		||||
            asset.Type = 2;
 | 
			
		||||
       
 | 
			
		||||
            return asset;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void BaseFetchMissingAsset(BaseGetAssetStreamHandler handler, OSHttpResponse response)
 | 
			
		||||
        {
 | 
			
		||||
            Assert.AreEqual(
 | 
			
		||||
                BaseRequestHandlerTestHelper.EmptyByteArray, 
 | 
			
		||||
                handler.Handle("/assets/" + Guid.NewGuid(), null, null, response), "Failed on bad guid.");
 | 
			
		||||
            Assert.AreEqual((int)HttpStatusCode.NotFound, response.StatusCode, "Response code wrong in BaseFetchMissingAsset");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								prebuild.xml
								
								
								
								
							
							
						
						
									
										65
									
								
								prebuild.xml
								
								
								
								
							| 
						 | 
				
			
			@ -956,38 +956,6 @@
 | 
			
		|||
    </Project>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <Project frameworkVersion="v3_5" name="OpenSim.Grid.AssetServer" path="OpenSim/Grid/AssetServer" type="Exe">
 | 
			
		||||
      <Configuration name="Debug">
 | 
			
		||||
        <Options>
 | 
			
		||||
          <OutputPath>../../../bin/</OutputPath>
 | 
			
		||||
        </Options>
 | 
			
		||||
      </Configuration>
 | 
			
		||||
      <Configuration name="Release">
 | 
			
		||||
        <Options>
 | 
			
		||||
          <OutputPath>../../../bin/</OutputPath>
 | 
			
		||||
        </Options>
 | 
			
		||||
      </Configuration>
 | 
			
		||||
 | 
			
		||||
      <ReferencePath>../../../bin/</ReferencePath>
 | 
			
		||||
      <Reference name="System"/>
 | 
			
		||||
      <Reference name="System.Data"/>
 | 
			
		||||
      <Reference name="System.Xml"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework.AssetLoader.Filesystem"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework.Console"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework.Servers"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework.Servers.HttpServer"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework.Communications"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework.Statistics"/>
 | 
			
		||||
      <Reference name="OpenSim.Data"/>
 | 
			
		||||
      <Reference name="OpenMetaverseTypes.dll"/>
 | 
			
		||||
      <Reference name="log4net.dll"/>
 | 
			
		||||
 | 
			
		||||
      <Files>
 | 
			
		||||
        <Match pattern="*.cs" recurse="true"/>
 | 
			
		||||
      </Files>
 | 
			
		||||
    </Project>
 | 
			
		||||
 | 
			
		||||
    <Project frameworkVersion="v3_5" name="OpenSim.Grid.UserServer.Modules" path="OpenSim/Grid/UserServer.Modules" type="Library">
 | 
			
		||||
      <Configuration name="Debug">
 | 
			
		||||
        <Options>
 | 
			
		||||
| 
						 | 
				
			
			@ -1068,38 +1036,6 @@
 | 
			
		|||
      </Files>
 | 
			
		||||
    </Project>
 | 
			
		||||
 | 
			
		||||
    <Project frameworkVersion="v3_5" name="OpenSim.Grid.InventoryServer" path="OpenSim/Grid/InventoryServer" type="Exe">
 | 
			
		||||
      <Configuration name="Debug">
 | 
			
		||||
        <Options>
 | 
			
		||||
          <OutputPath>../../../bin/</OutputPath>
 | 
			
		||||
        </Options>
 | 
			
		||||
      </Configuration>
 | 
			
		||||
      <Configuration name="Release">
 | 
			
		||||
        <Options>
 | 
			
		||||
          <OutputPath>../../../bin/</OutputPath>
 | 
			
		||||
        </Options>
 | 
			
		||||
      </Configuration>
 | 
			
		||||
 | 
			
		||||
      <ReferencePath>../../../bin/</ReferencePath>
 | 
			
		||||
      <Reference name="System"/>
 | 
			
		||||
      <Reference name="System.Data"/>
 | 
			
		||||
      <Reference name="System.Xml"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework.Console"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework.Communications"/>
 | 
			
		||||
      <Reference name="OpenSim.Data"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework.Servers"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework.Servers.HttpServer"/>
 | 
			
		||||
      <Reference name="OpenSim.Services.Interfaces"/>
 | 
			
		||||
      <Reference name="OpenMetaverseTypes.dll"/>
 | 
			
		||||
      <Reference name="log4net.dll"/>
 | 
			
		||||
      <Reference name="XMLRPC.dll"/>
 | 
			
		||||
 | 
			
		||||
      <Files>
 | 
			
		||||
        <Match pattern="*.cs" recurse="true"/>
 | 
			
		||||
      </Files>
 | 
			
		||||
    </Project>
 | 
			
		||||
 | 
			
		||||
    <Project frameworkVersion="v3_5" name="OpenSim.Grid.MessagingServer.Modules" path="OpenSim/Grid/MessagingServer.Modules" type="Library">
 | 
			
		||||
      <Configuration name="Debug">
 | 
			
		||||
        <Options>
 | 
			
		||||
| 
						 | 
				
			
			@ -1819,6 +1755,7 @@
 | 
			
		|||
      <ReferencePath>../../../bin/</ReferencePath>
 | 
			
		||||
      <Reference name="System"/>
 | 
			
		||||
      <Reference name="System.Xml"/>
 | 
			
		||||
      <Reference name="OpenSim.Data"/>
 | 
			
		||||
      <Reference name="OpenMetaverseTypes.dll"/>
 | 
			
		||||
      <Reference name="OpenSim.Framework"/>
 | 
			
		||||
      <Reference name="OpenSim.Region.Framework"/>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue