diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs new file mode 100644 index 0000000000..e188896bc5 --- /dev/null +++ b/OpenSim/Capabilities/Caps.cs @@ -0,0 +1,176 @@ +/* + * 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.IO; +using System.Reflection; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Services.Interfaces; + +// using OpenSim.Region.Framework.Interfaces; + +namespace OpenSim.Framework.Capabilities +{ + /// + /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that + /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want + /// to just pass the whole Scene into CAPS. + /// + public delegate IClientAPI GetClientDelegate(UUID agentID); + + public class Caps + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private string m_httpListenerHostName; + private uint m_httpListenPort; + + /// + /// This is the uuid portion of every CAPS path. It is used to make capability urls private to the requester. + /// + private string m_capsObjectPath; + public string CapsObjectPath { get { return m_capsObjectPath; } } + + private CapsHandlers m_capsHandlers; + private Dictionary m_externalCapsHandlers; + + private IHttpServer m_httpListener; + private UUID m_agentID; + private string m_regionName; + + public UUID AgentID + { + get { return m_agentID; } + } + + public string RegionName + { + get { return m_regionName; } + } + + public string HostName + { + get { return m_httpListenerHostName; } + } + + public uint Port + { + get { return m_httpListenPort; } + } + + public IHttpServer HttpListener + { + get { return m_httpListener; } + } + + public bool SSLCaps + { + get { return m_httpListener.UseSSL; } + } + public string SSLCommonName + { + get { return m_httpListener.SSLCommonName; } + } + public CapsHandlers CapsHandlers + { + get { return m_capsHandlers; } + } + public Dictionary ExternalCapsHandlers + { + get { return m_externalCapsHandlers; } + } + + public Caps(IHttpServer httpServer, string httpListen, uint httpPort, string capsPath, + UUID agent, string regionName) + { + m_capsObjectPath = capsPath; + m_httpListener = httpServer; + m_httpListenerHostName = httpListen; + + m_httpListenPort = httpPort; + + if (httpServer != null && httpServer.UseSSL) + { + m_httpListenPort = httpServer.SSLPort; + httpListen = httpServer.SSLCommonName; + httpPort = httpServer.SSLPort; + } + + m_agentID = agent; + m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL); + m_externalCapsHandlers = new Dictionary(); + m_regionName = regionName; + } + + /// + /// Register a handler. This allows modules to register handlers. + /// + /// + /// + public void RegisterHandler(string capName, IRequestHandler handler) + { + m_capsHandlers[capName] = handler; + //m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path); + } + + /// + /// Register an external handler. The service for this capability is somewhere else + /// given by the URL. + /// + /// + /// + public void RegisterHandler(string capsName, string url) + { + m_externalCapsHandlers.Add(capsName, url); + } + + /// + /// Remove all CAPS service handlers. + /// + /// + /// + /// + /// + public void DeregisterHandlers() + { + if (m_capsHandlers != null) + { + foreach (string capsName in m_capsHandlers.Caps) + { + m_capsHandlers.Remove(capsName); + } + } + } + } +} diff --git a/OpenSim/Framework/Capabilities/CapsHandlers.cs b/OpenSim/Capabilities/CapsHandlers.cs similarity index 100% rename from OpenSim/Framework/Capabilities/CapsHandlers.cs rename to OpenSim/Capabilities/CapsHandlers.cs diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs similarity index 74% rename from OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs rename to OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs index fc1ddef38c..c60abb1fb1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs @@ -31,7 +31,6 @@ using System.Collections.Specialized; using System.Reflection; using System.IO; using System.Web; -using Mono.Addins; using log4net; using Nini.Config; using OpenMetaverse; @@ -39,90 +38,23 @@ using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Avatar.Assets +namespace OpenSim.Capabilities.Handlers { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GetMeshModule : INonSharedRegionModule + public class GetMeshHandler { // private static readonly ILog m_log = // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Scene m_scene; private IAssetService m_assetService; - private bool m_enabled = true; - #region IRegionModuleBase Members - - - public Type ReplaceableInterface + public GetMeshHandler(IAssetService assService) { - get { return null; } + m_assetService = assService; } - public void Initialise(IConfigSource source) - { - IConfig meshConfig = source.Configs["Mesh"]; - if (meshConfig == null) - return; - - m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true); - } - - public void AddRegion(Scene pScene) - { - m_scene = pScene; - } - - public void RemoveRegion(Scene scene) - { - - m_scene.EventManager.OnRegisterCaps -= RegisterCaps; - m_scene = null; - } - - public void RegionLoaded(Scene scene) - { - - m_assetService = m_scene.RequestModuleInterface(); - m_scene.EventManager.OnRegisterCaps += RegisterCaps; - } - - #endregion - - - #region IRegionModule Members - - - - public void Close() { } - - public string Name { get { return "GetMeshModule"; } } - - - public void RegisterCaps(UUID agentID, Caps caps) - { - if(!m_enabled) - return; - - UUID capID = UUID.Random(); - -// m_log.Info("[GETMESH]: /CAPS/" + capID); - - caps.RegisterHandler("GetMesh", - new RestHTTPHandler("GET", "/CAPS/" + capID, - delegate(Hashtable m_dhttpMethod) - { - return ProcessGetMesh(m_dhttpMethod, agentID, caps); - })); - } - - #endregion - public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) { diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs new file mode 100644 index 0000000000..2ecfa3c23b --- /dev/null +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs @@ -0,0 +1,78 @@ +/* + * 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 Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using OpenSim.Framework.Servers; + +using OpenMetaverse; + +namespace OpenSim.Capabilities.Handlers +{ + public class GetMeshServerConnector : ServiceConnector + { + private IAssetService m_AssetService; + private string m_ConfigName = "CapsService"; + + public GetMeshServerConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + if (configName != String.Empty) + m_ConfigName = configName; + + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName)); + + string assetService = serverConfig.GetString("AssetService", String.Empty); + + if (assetService == String.Empty) + throw new Exception("No AssetService in config file"); + + Object[] args = new Object[] { config }; + m_AssetService = + ServerUtils.LoadPlugin(assetService, args); + + if (m_AssetService == null) + throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); + + GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); + IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), + delegate(Hashtable m_dhttpMethod) + { + return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null); + }); + server.AddStreamHandler(reqHandler); + } + + } +} diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs similarity index 88% rename from OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs rename to OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index df4d561024..00ff3d0b5b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -42,39 +42,16 @@ using OpenSim.Framework; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps +namespace OpenSim.Capabilities.Handlers { - #region Stream Handler - public delegate byte[] StreamHandlerCallback(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse); - - public class StreamHandler : BaseStreamHandler - { - StreamHandlerCallback m_callback; - - public StreamHandler(string httpMethod, string path, StreamHandlerCallback callback) - : base(httpMethod, path) - { - m_callback = callback; - } - - public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - return m_callback(path, request, httpRequest, httpResponse); - } - } - - #endregion Stream Handler - - public class GetTextureModule : IRegionModule + public class GetTextureHandler : BaseStreamHandler { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Scene m_scene; private IAssetService m_assetService; public const string DefaultFormat = "x-j2c"; @@ -82,44 +59,22 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps // TODO: Change this to a config option const string REDIRECT_URL = null; - - #region IRegionModule Members - - public void Initialise(Scene pScene, IConfigSource pSource) + public GetTextureHandler(string path, IAssetService assService) : + base("GET", path) { - m_scene = pScene; + m_assetService = assService; } - public void PostInitialise() + public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { - m_assetService = m_scene.RequestModuleInterface(); - m_scene.EventManager.OnRegisterCaps += RegisterCaps; - } - - public void Close() { } - - public string Name { get { return "GetTextureModule"; } } - public bool IsSharedModule { get { return false; } } - - public void RegisterCaps(UUID agentID, Caps caps) - { - UUID capID = UUID.Random(); - -// m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); - caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); - } - - #endregion - - private byte[] ProcessGetTexture(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - //m_log.DebugFormat("[GETTEXTURE]: called in {0}", m_scene.RegionInfo.RegionName); // Try to parse the texture ID from the request URL NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); string textureStr = query.GetOne("texture_id"); string format = query.GetOne("format"); + m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr); + if (m_assetService == null) { m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs new file mode 100644 index 0000000000..0d072f71ff --- /dev/null +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs @@ -0,0 +1,69 @@ +/* + * 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 Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using OpenMetaverse; + +namespace OpenSim.Capabilities.Handlers +{ + public class GetTextureServerConnector : ServiceConnector + { + private IAssetService m_AssetService; + private string m_ConfigName = "CapsService"; + + public GetTextureServerConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + if (configName != String.Empty) + m_ConfigName = configName; + + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName)); + + string assetService = serverConfig.GetString("AssetService", String.Empty); + + if (assetService == String.Empty) + throw new Exception("No AssetService in config file"); + + Object[] args = new Object[] { config }; + m_AssetService = + ServerUtils.LoadPlugin(assetService, args); + + if (m_AssetService == null) + throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); + + server.AddStreamHandler(new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService)); + } + + } +} diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs new file mode 100644 index 0000000000..6fd79469a4 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs @@ -0,0 +1,299 @@ +/* + * 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.Reflection; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Framework.Capabilities; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Capabilities.Handlers +{ + + public class WebFetchInvDescHandler + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IInventoryService m_InventoryService; + private ILibraryService m_LibraryService; + private object m_fetchLock = new Object(); + + public WebFetchInvDescHandler(IInventoryService invService, ILibraryService libService) + { + m_InventoryService = invService; + m_LibraryService = libService; + } + + public string FetchInventoryDescendentsRequest(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + // nasty temporary hack here, the linden client falsely + // identifies the uuid 00000000-0000-0000-0000-000000000000 + // as a string which breaks us + // + // correctly mark it as a uuid + // + request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); + + // another hack 1 results in a + // System.ArgumentException: Object type System.Int32 cannot + // be converted to target type: System.Boolean + // + request = request.Replace("fetch_folders0", "fetch_folders0"); + request = request.Replace("fetch_folders1", "fetch_folders1"); + + Hashtable hash = new Hashtable(); + try + { + hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); + } + catch (LLSD.LLSDParseException pe) + { + m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); + m_log.Error("Request: " + request.ToString()); + } + + ArrayList foldersrequested = (ArrayList)hash["folders"]; + + string response = ""; + lock (m_fetchLock) + { + for (int i = 0; i < foldersrequested.Count; i++) + { + string inventoryitemstr = ""; + Hashtable inventoryhash = (Hashtable)foldersrequested[i]; + + LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); + + try + { + LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); + } + catch (Exception e) + { + m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); + } + LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); + + inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); + inventoryitemstr = inventoryitemstr.Replace("folders", ""); + inventoryitemstr = inventoryitemstr.Replace("", ""); + + response += inventoryitemstr; + } + + + if (response.Length == 0) + { + // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. + // Therefore, I'm concluding that the client only has so many threads available to do requests + // and when a thread stalls.. is stays stalled. + // Therefore we need to return something valid + response = "folders"; + } + else + { + response = "folders" + response + ""; + } + + //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); + //m_log.Debug("[CAPS] "+response); + + } + return response; + } + + /// + /// Construct an LLSD reply packet to a CAPS inventory request + /// + /// + /// + private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) + { + LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); + LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); + contents.agent_id = invFetch.owner_id; + contents.owner_id = invFetch.owner_id; + contents.folder_id = invFetch.folder_id; + + reply.folders.Array.Add(contents); + InventoryCollection inv = new InventoryCollection(); + inv.Folders = new List(); + inv.Items = new List(); + int version = 0; + + inv = Fetch(invFetch.owner_id, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); + + if (inv.Folders != null) + { + foreach (InventoryFolderBase invFolder in inv.Folders) + { + contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); + } + } + + if (inv.Items != null) + { + foreach (InventoryItemBase invItem in inv.Items) + { + contents.items.Array.Add(ConvertInventoryItem(invItem)); + } + } + + contents.descendents = contents.items.Array.Count + contents.categories.Array.Count; + contents.version = version; + + return reply; + } + + public InventoryCollection Fetch(UUID agentID, UUID folderID, UUID ownerID, + bool fetchFolders, bool fetchItems, int sortOrder, out int version) + { + m_log.DebugFormat( + "[WEBFETCHINVENTORYDESCENDANTS]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", + fetchFolders, fetchItems, folderID, agentID); + + version = 0; + InventoryFolderImpl fold; + if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner) + if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null) + { + InventoryCollection ret = new InventoryCollection(); + ret.Folders = new List(); + ret.Items = fold.RequestListOfItems(); + + return ret; + } + + InventoryCollection contents = new InventoryCollection(); + + if (folderID != UUID.Zero) + { + contents = m_InventoryService.GetFolderContent(agentID, folderID); + InventoryFolderBase containingFolder = new InventoryFolderBase(); + containingFolder.ID = folderID; + containingFolder.Owner = agentID; + containingFolder = m_InventoryService.GetFolder(containingFolder); + if (containingFolder != null) + version = containingFolder.Version; + } + else + { + // Lost itemsm don't really need a version + version = 1; + } + + return contents; + + } + /// + /// Convert an internal inventory folder object into an LLSD object. + /// + /// + /// + private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder) + { + LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder(); + llsdFolder.folder_id = invFolder.ID; + llsdFolder.parent_id = invFolder.ParentID; + llsdFolder.name = invFolder.Name; + if (invFolder.Type < 0 || invFolder.Type >= TaskInventoryItem.Types.Length) + llsdFolder.type = "-1"; + else + llsdFolder.type = TaskInventoryItem.Types[invFolder.Type]; + llsdFolder.preferred_type = "-1"; + + return llsdFolder; + } + + /// + /// Convert an internal inventory item object into an LLSD object. + /// + /// + /// + private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) + { + LLSDInventoryItem llsdItem = new LLSDInventoryItem(); + llsdItem.asset_id = invItem.AssetID; + llsdItem.created_at = invItem.CreationDate; + llsdItem.desc = invItem.Description; + llsdItem.flags = (int)invItem.Flags; + llsdItem.item_id = invItem.ID; + llsdItem.name = invItem.Name; + llsdItem.parent_id = invItem.Folder; + try + { + // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions. + llsdItem.type = TaskInventoryItem.Types[invItem.AssetType]; + llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType]; + } + catch (Exception e) + { + m_log.ErrorFormat("[CAPS]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}", invItem.AssetType, invItem.InvType, invItem.Name, e.Message); + } + llsdItem.permissions = new LLSDPermissions(); + llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; + llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; + llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; + llsdItem.permissions.group_id = invItem.GroupID; + llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; + llsdItem.permissions.is_owner_group = invItem.GroupOwned; + llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; + llsdItem.permissions.owner_id = invItem.Owner; + llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; + llsdItem.sale_info = new LLSDSaleInfo(); + llsdItem.sale_info.sale_price = invItem.SalePrice; + switch (invItem.SaleType) + { + default: + llsdItem.sale_info.sale_type = "not"; + break; + case 1: + llsdItem.sale_info.sale_type = "original"; + break; + case 2: + llsdItem.sale_info.sale_type = "copy"; + break; + case 3: + llsdItem.sale_info.sale_type = "contents"; + break; + } + + return llsdItem; + } + + } +} diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs new file mode 100644 index 0000000000..92eeb140d0 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs @@ -0,0 +1,76 @@ +/* + * 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 Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using OpenMetaverse; + +namespace OpenSim.Capabilities.Handlers +{ + public class WebFetchInvDescServerConnector : ServiceConnector + { + private IInventoryService m_InventoryService; + private ILibraryService m_LibraryService; + private string m_ConfigName = "CapsService"; + + public WebFetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + if (configName != String.Empty) + m_ConfigName = configName; + + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName)); + + string invService = serverConfig.GetString("InventoryService", String.Empty); + + if (invService == String.Empty) + throw new Exception("No InventoryService in config file"); + + Object[] args = new Object[] { config }; + m_InventoryService = + ServerUtils.LoadPlugin(invService, args); + + if (m_InventoryService == null) + throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName)); + + string libService = serverConfig.GetString("LibraryService", String.Empty); + m_LibraryService = + ServerUtils.LoadPlugin(libService, args); + + WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); + IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, webFetchHandler.FetchInventoryDescendentsRequest); + server.AddStreamHandler(reqHandler); + } + + } +} diff --git a/OpenSim/Framework/Capabilities/LLSD.cs b/OpenSim/Capabilities/LLSD.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSD.cs rename to OpenSim/Capabilities/LLSD.cs diff --git a/OpenSim/Framework/Capabilities/LLSDArray.cs b/OpenSim/Capabilities/LLSDArray.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDArray.cs rename to OpenSim/Capabilities/LLSDArray.cs diff --git a/OpenSim/Framework/Capabilities/LLSDAssetUploadComplete.cs b/OpenSim/Capabilities/LLSDAssetUploadComplete.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDAssetUploadComplete.cs rename to OpenSim/Capabilities/LLSDAssetUploadComplete.cs diff --git a/OpenSim/Framework/Capabilities/LLSDAssetUploadRequest.cs b/OpenSim/Capabilities/LLSDAssetUploadRequest.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDAssetUploadRequest.cs rename to OpenSim/Capabilities/LLSDAssetUploadRequest.cs diff --git a/OpenSim/Framework/Capabilities/LLSDAssetUploadResponse.cs b/OpenSim/Capabilities/LLSDAssetUploadResponse.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDAssetUploadResponse.cs rename to OpenSim/Capabilities/LLSDAssetUploadResponse.cs diff --git a/OpenSim/Framework/Capabilities/LLSDCapEvent.cs b/OpenSim/Capabilities/LLSDCapEvent.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDCapEvent.cs rename to OpenSim/Capabilities/LLSDCapEvent.cs diff --git a/OpenSim/Framework/Capabilities/LLSDEmpty.cs b/OpenSim/Capabilities/LLSDEmpty.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDEmpty.cs rename to OpenSim/Capabilities/LLSDEmpty.cs diff --git a/OpenSim/Framework/Capabilities/LLSDHelpers.cs b/OpenSim/Capabilities/LLSDHelpers.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDHelpers.cs rename to OpenSim/Capabilities/LLSDHelpers.cs diff --git a/OpenSim/Framework/Capabilities/LLSDInventoryFolder.cs b/OpenSim/Capabilities/LLSDInventoryFolder.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDInventoryFolder.cs rename to OpenSim/Capabilities/LLSDInventoryFolder.cs diff --git a/OpenSim/Framework/Capabilities/LLSDInventoryItem.cs b/OpenSim/Capabilities/LLSDInventoryItem.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDInventoryItem.cs rename to OpenSim/Capabilities/LLSDInventoryItem.cs diff --git a/OpenSim/Framework/Capabilities/LLSDItemUpdate.cs b/OpenSim/Capabilities/LLSDItemUpdate.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDItemUpdate.cs rename to OpenSim/Capabilities/LLSDItemUpdate.cs diff --git a/OpenSim/Framework/Capabilities/LLSDMapLayer.cs b/OpenSim/Capabilities/LLSDMapLayer.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDMapLayer.cs rename to OpenSim/Capabilities/LLSDMapLayer.cs diff --git a/OpenSim/Framework/Capabilities/LLSDMapLayerResponse.cs b/OpenSim/Capabilities/LLSDMapLayerResponse.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDMapLayerResponse.cs rename to OpenSim/Capabilities/LLSDMapLayerResponse.cs diff --git a/OpenSim/Framework/Capabilities/LLSDMapRequest.cs b/OpenSim/Capabilities/LLSDMapRequest.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDMapRequest.cs rename to OpenSim/Capabilities/LLSDMapRequest.cs diff --git a/OpenSim/Framework/Capabilities/LLSDMethod.cs b/OpenSim/Capabilities/LLSDMethod.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDMethod.cs rename to OpenSim/Capabilities/LLSDMethod.cs diff --git a/OpenSim/Framework/Capabilities/LLSDMethodString.cs b/OpenSim/Capabilities/LLSDMethodString.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDMethodString.cs rename to OpenSim/Capabilities/LLSDMethodString.cs diff --git a/OpenSim/Framework/Capabilities/LLSDParcelVoiceInfoResponse.cs b/OpenSim/Capabilities/LLSDParcelVoiceInfoResponse.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDParcelVoiceInfoResponse.cs rename to OpenSim/Capabilities/LLSDParcelVoiceInfoResponse.cs diff --git a/OpenSim/Framework/Capabilities/LLSDRemoteParcelResponse.cs b/OpenSim/Capabilities/LLSDRemoteParcelResponse.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDRemoteParcelResponse.cs rename to OpenSim/Capabilities/LLSDRemoteParcelResponse.cs diff --git a/OpenSim/Framework/Capabilities/LLSDStreamHandler.cs b/OpenSim/Capabilities/LLSDStreamHandler.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDStreamHandler.cs rename to OpenSim/Capabilities/LLSDStreamHandler.cs diff --git a/OpenSim/Framework/Capabilities/LLSDTaskInventoryUploadComplete.cs b/OpenSim/Capabilities/LLSDTaskInventoryUploadComplete.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDTaskInventoryUploadComplete.cs rename to OpenSim/Capabilities/LLSDTaskInventoryUploadComplete.cs diff --git a/OpenSim/Framework/Capabilities/LLSDTaskScriptUpdate.cs b/OpenSim/Capabilities/LLSDTaskScriptUpdate.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDTaskScriptUpdate.cs rename to OpenSim/Capabilities/LLSDTaskScriptUpdate.cs diff --git a/OpenSim/Framework/Capabilities/LLSDTaskScriptUploadComplete.cs b/OpenSim/Capabilities/LLSDTaskScriptUploadComplete.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDTaskScriptUploadComplete.cs rename to OpenSim/Capabilities/LLSDTaskScriptUploadComplete.cs diff --git a/OpenSim/Framework/Capabilities/LLSDTest.cs b/OpenSim/Capabilities/LLSDTest.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDTest.cs rename to OpenSim/Capabilities/LLSDTest.cs diff --git a/OpenSim/Framework/Capabilities/LLSDType.cs b/OpenSim/Capabilities/LLSDType.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDType.cs rename to OpenSim/Capabilities/LLSDType.cs diff --git a/OpenSim/Framework/Capabilities/LLSDVoiceAccountResponse.cs b/OpenSim/Capabilities/LLSDVoiceAccountResponse.cs similarity index 100% rename from OpenSim/Framework/Capabilities/LLSDVoiceAccountResponse.cs rename to OpenSim/Capabilities/LLSDVoiceAccountResponse.cs diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs deleted file mode 100644 index 3be97b5c89..0000000000 --- a/OpenSim/Framework/Capabilities/Caps.cs +++ /dev/null @@ -1,1368 +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.IO; -using System.Reflection; -using log4net; -using Nini.Config; -using OpenMetaverse; -using OpenSim.Framework.Servers; -using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Services.Interfaces; - -// using OpenSim.Region.Framework.Interfaces; - -namespace OpenSim.Framework.Capabilities -{ - public delegate void UpLoadedAsset( - string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder, - byte[] data, string inventoryType, string assetType); - - public delegate void UploadedBakedTexture(UUID assetID, byte[] data); - - public delegate UUID UpdateItem(UUID itemID, byte[] data); - - public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); - - public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); - - public delegate void NewAsset(AssetBase asset); - - public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data); - - public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID, - bool isScriptRunning, byte[] data); - - public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, - bool fetchFolders, bool fetchItems, int sortOrder, out int version); - - /// - /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that - /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want - /// to just pass the whole Scene into CAPS. - /// - public delegate IClientAPI GetClientDelegate(UUID agentID); - - public class Caps - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private string m_httpListenerHostName; - private uint m_httpListenPort; - - /// - /// This is the uuid portion of every CAPS path. It is used to make capability urls private to the requester. - /// - private string m_capsObjectPath; - public string CapsObjectPath { get { return m_capsObjectPath; } } - - private CapsHandlers m_capsHandlers; - - private static readonly string m_requestPath = "0000/"; - // private static readonly string m_mapLayerPath = "0001/"; - private static readonly string m_newInventory = "0002/"; - //private static readonly string m_requestTexture = "0003/"; - private static readonly string m_notecardUpdatePath = "0004/"; - private static readonly string m_notecardTaskUpdatePath = "0005/"; -// private static readonly string m_fetchInventoryPath = "0006/"; - - // The following entries are in a module, however, they are also here so that we don't re-assign - // the path to another cap by mistake. - // private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; // This is in a module. - // private static readonly string m_provisionVoiceAccountRequestPath = "0008/";// This is in a module. - - // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. - private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule. - - //private string eventQueue = "0100/"; - private IScene m_Scene; - private IHttpServer m_httpListener; - private UUID m_agentID; - private IAssetService m_assetCache; - private int m_eventQueueCount = 1; - private Queue m_capsEventQueue = new Queue(); - private bool m_dumpAssetsToFile; - private string m_regionName; - private object m_fetchLock = new Object(); - - private bool m_persistBakedTextures = false; - - public bool SSLCaps - { - get { return m_httpListener.UseSSL; } - } - public string SSLCommonName - { - get { return m_httpListener.SSLCommonName; } - } - public CapsHandlers CapsHandlers - { - get { return m_capsHandlers; } - } - - // These are callbacks which will be setup by the scene so that we can update scene data when we - // receive capability calls - public NewInventoryItem AddNewInventoryItem = null; - public NewAsset AddNewAsset = null; - public ItemUpdatedCallback ItemUpdatedCall = null; - public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; - public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null; - public GetClientDelegate GetClient = null; - - public Caps(IScene scene, IAssetService assetCache, IHttpServer httpServer, string httpListen, uint httpPort, string capsPath, - UUID agent, bool dumpAssetsToFile, string regionName) - { - m_Scene = scene; - m_assetCache = assetCache; - m_capsObjectPath = capsPath; - m_httpListener = httpServer; - m_httpListenerHostName = httpListen; - - m_httpListenPort = httpPort; - - m_persistBakedTextures = false; - IConfigSource config = m_Scene.Config; - if (config != null) - { - IConfig sconfig = config.Configs["Startup"]; - if (sconfig != null) - m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures",m_persistBakedTextures); - } - - if (httpServer != null && httpServer.UseSSL) - { - m_httpListenPort = httpServer.SSLPort; - httpListen = httpServer.SSLCommonName; - httpPort = httpServer.SSLPort; - } - - m_agentID = agent; - m_dumpAssetsToFile = dumpAssetsToFile; - m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL); - m_regionName = regionName; - } - - /// - /// Register all CAPS http service handlers - /// - public void RegisterHandlers() - { - DeregisterHandlers(); - - string capsBase = "/CAPS/" + m_capsObjectPath; - - RegisterRegionServiceHandlers(capsBase); - RegisterInventoryServiceHandlers(capsBase); - } - - public void RegisterRegionServiceHandlers(string capsBase) - { - try - { - // the root of all evil - m_capsHandlers["SEED"] = new RestStreamHandler("POST", capsBase + m_requestPath, CapsRequest); - m_log.DebugFormat( - "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_agentID); - - //m_capsHandlers["MapLayer"] = - // new LLSDStreamhandler("POST", - // capsBase + m_mapLayerPath, - // GetMapLayer); - m_capsHandlers["UpdateScriptTaskInventory"] = - new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory); - m_capsHandlers["UpdateScriptTask"] = m_capsHandlers["UpdateScriptTaskInventory"]; - m_capsHandlers["UploadBakedTexture"] = - new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture); - - } - catch (Exception e) - { - m_log.Error("[CAPS]: " + e.ToString()); - } - } - - public void RegisterInventoryServiceHandlers(string capsBase) - { - try - { - // I don't think this one works... - m_capsHandlers["NewFileAgentInventory"] = - new LLSDStreamhandler("POST", - capsBase + m_newInventory, - NewAgentInventoryRequest); - m_capsHandlers["UpdateNotecardAgentInventory"] = - new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory); - m_capsHandlers["UpdateScriptAgentInventory"] = m_capsHandlers["UpdateNotecardAgentInventory"]; - m_capsHandlers["UpdateScriptAgent"] = m_capsHandlers["UpdateScriptAgentInventory"]; - - // As of RC 1.22.9 of the Linden client this is - // supported - - //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); - - // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and - // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires - // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service, - // but when I went on the Linden grid, the - // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead, - // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP - // - // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid - // we will be - // able to get the data we need to implement the necessary part of the protocol to fix the issue above. - // m_capsHandlers["FetchInventoryDescendents"] = - // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest); - - // m_capsHandlers["FetchInventoryDescendents"] = - // new LLSDStreamhandler("POST", - // capsBase + m_fetchInventory, - // FetchInventory)); - // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST", - // capsBase + m_requestTexture, - // RequestTexture); - } - catch (Exception e) - { - m_log.Error("[CAPS]: " + e.ToString()); - } - } - - /// - /// Register a handler. This allows modules to register handlers. - /// - /// - /// - public void RegisterHandler(string capName, IRequestHandler handler) - { - m_capsHandlers[capName] = handler; - //m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path); - } - - /// - /// Remove all CAPS service handlers. - /// - /// - /// - /// - /// - public void DeregisterHandlers() - { - if (m_capsHandlers != null) - { - foreach (string capsName in m_capsHandlers.Caps) - { - m_capsHandlers.Remove(capsName); - } - } - } - - /// - /// Construct a client response detailing all the capabilities this server can provide. - /// - /// - /// - /// - /// HTTP request header object - /// HTTP response header object - /// - public string CapsRequest(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); - - if (!m_Scene.CheckClient(m_agentID, httpRequest.RemoteIPEndPoint)) - { - m_log.DebugFormat("[CAPS]: Unauthorized CAPS client"); - return string.Empty; - } - - string result = LLSDHelpers.SerialiseLLSDReply(m_capsHandlers.CapsDetails); - - //m_log.DebugFormat("[CAPS] CapsRequest {0}", result); - - return result; - } - - // FIXME: these all should probably go into the respective region - // modules - - /// - /// Processes a fetch inventory request and sends the reply - - /// - /// - /// - /// - /// - // Request is like: - // - // folders - // - // - // fetch-folders1fetch-items1folder-id8e1e3a30-b9bf-11dc-95ff-0800200c9a66owner-id11111111-1111-0000-0000-000100bba000sort-order1 - // - // - // - // - // - // multiple fetch-folder maps are allowed within the larger folders map. - public string FetchInventoryRequest(string request, string path, string param) - { - // string unmodifiedRequest = request.ToString(); - - //m_log.DebugFormat("[AGENT INVENTORY]: Received CAPS fetch inventory request {0}", unmodifiedRequest); - m_log.Debug("[CAPS]: Inventory Request in region: " + m_regionName); - - Hashtable hash = new Hashtable(); - try - { - hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); - } - catch (LLSD.LLSDParseException pe) - { - m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); - m_log.Error("Request: " + request.ToString()); - } - - ArrayList foldersrequested = (ArrayList)hash["folders"]; - - string response = ""; - - for (int i = 0; i < foldersrequested.Count; i++) - { - string inventoryitemstr = ""; - Hashtable inventoryhash = (Hashtable)foldersrequested[i]; - - LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); - LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); - LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); - - inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); - inventoryitemstr = inventoryitemstr.Replace("folders", ""); - inventoryitemstr = inventoryitemstr.Replace("", ""); - - response += inventoryitemstr; - } - - if (response.Length == 0) - { - // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. - // Therefore, I'm concluding that the client only has so many threads available to do requests - // and when a thread stalls.. is stays stalled. - // Therefore we need to return something valid - response = "folders"; - } - else - { - response = "folders" + response + ""; - } - - //m_log.DebugFormat("[AGENT INVENTORY]: Replying to CAPS fetch inventory request with following xml"); - //m_log.Debug(Util.GetFormattedXml(response)); - - return response; - } - - public string FetchInventoryDescendentsRequest(string request, string path, string param,OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - // nasty temporary hack here, the linden client falsely - // identifies the uuid 00000000-0000-0000-0000-000000000000 - // as a string which breaks us - // - // correctly mark it as a uuid - // - request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); - - // another hack 1 results in a - // System.ArgumentException: Object type System.Int32 cannot - // be converted to target type: System.Boolean - // - request = request.Replace("fetch_folders0", "fetch_folders0"); - request = request.Replace("fetch_folders1", "fetch_folders1"); - - Hashtable hash = new Hashtable(); - try - { - hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); - } - catch (LLSD.LLSDParseException pe) - { - m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); - m_log.Error("Request: " + request.ToString()); - } - - ArrayList foldersrequested = (ArrayList)hash["folders"]; - - string response = ""; - lock (m_fetchLock) - { - for (int i = 0; i < foldersrequested.Count; i++) - { - string inventoryitemstr = ""; - Hashtable inventoryhash = (Hashtable)foldersrequested[i]; - - LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); - - try{ - LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); - } - catch(Exception e) - { - m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); - } - LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); - - inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); - inventoryitemstr = inventoryitemstr.Replace("folders", ""); - inventoryitemstr = inventoryitemstr.Replace("", ""); - - response += inventoryitemstr; - } - - - if (response.Length == 0) - { - // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. - // Therefore, I'm concluding that the client only has so many threads available to do requests - // and when a thread stalls.. is stays stalled. - // Therefore we need to return something valid - response = "folders"; - } - else - { - response = "folders" + response + ""; - } - - //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); - //m_log.Debug("[CAPS] "+response); - - } - return response; - } - - - - /// - /// Construct an LLSD reply packet to a CAPS inventory request - /// - /// - /// - private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) - { - LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); - LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); - contents.agent_id = m_agentID; - contents.owner_id = invFetch.owner_id; - contents.folder_id = invFetch.folder_id; - - reply.folders.Array.Add(contents); - InventoryCollection inv = new InventoryCollection(); - inv.Folders = new List(); - inv.Items = new List(); - int version = 0; - if (CAPSFetchInventoryDescendents != null) - { - inv = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); - } - - if (inv.Folders != null) - { - foreach (InventoryFolderBase invFolder in inv.Folders) - { - contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); - } - } - - if (inv.Items != null) - { - foreach (InventoryItemBase invItem in inv.Items) - { - contents.items.Array.Add(ConvertInventoryItem(invItem)); - } - } - - contents.descendents = contents.items.Array.Count + contents.categories.Array.Count; - contents.version = version; - - return reply; - } - - /// - /// Convert an internal inventory folder object into an LLSD object. - /// - /// - /// - private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder) - { - LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder(); - llsdFolder.folder_id = invFolder.ID; - llsdFolder.parent_id = invFolder.ParentID; - llsdFolder.name = invFolder.Name; - if (invFolder.Type < 0 || invFolder.Type >= TaskInventoryItem.Types.Length) - llsdFolder.type = "-1"; - else - llsdFolder.type = TaskInventoryItem.Types[invFolder.Type]; - llsdFolder.preferred_type = "-1"; - - return llsdFolder; - } - - /// - /// Convert an internal inventory item object into an LLSD object. - /// - /// - /// - private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) - { - LLSDInventoryItem llsdItem = new LLSDInventoryItem(); - llsdItem.asset_id = invItem.AssetID; - llsdItem.created_at = invItem.CreationDate; - llsdItem.desc = invItem.Description; - llsdItem.flags = (int)invItem.Flags; - llsdItem.item_id = invItem.ID; - llsdItem.name = invItem.Name; - llsdItem.parent_id = invItem.Folder; - try - { - // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions. - llsdItem.type = TaskInventoryItem.Types[invItem.AssetType]; - llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType]; - } - catch (Exception e) - { - m_log.Error("[CAPS]: Problem setting asset/inventory type while converting inventory item " + invItem.Name + " to LLSD:", e); - } - llsdItem.permissions = new LLSDPermissions(); - llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; - llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; - llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; - llsdItem.permissions.group_id = invItem.GroupID; - llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; - llsdItem.permissions.is_owner_group = invItem.GroupOwned; - llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; - llsdItem.permissions.owner_id = m_agentID; - llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; - llsdItem.sale_info = new LLSDSaleInfo(); - llsdItem.sale_info.sale_price = invItem.SalePrice; - switch (invItem.SaleType) - { - default: - llsdItem.sale_info.sale_type = "not"; - break; - case 1: - llsdItem.sale_info.sale_type = "original"; - break; - case 2: - llsdItem.sale_info.sale_type = "copy"; - break; - case 3: - llsdItem.sale_info.sale_type = "contents"; - break; - } - - return llsdItem; - } - - /// - /// - /// - /// - /// - public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) - { - m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName); - LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); - mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); - return mapResponse; - } - - /// - /// - /// - /// - protected static OSDMapLayer GetOSDMapLayerResponse() - { - OSDMapLayer mapLayer = new OSDMapLayer(); - mapLayer.Right = 5000; - mapLayer.Top = 5000; - mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); - - return mapLayer; - } - - /// - /// - /// - /// - /// - /// - /// - public string RequestTexture(string request, string path, string param) - { - m_log.Debug("texture request " + request); - // Needs implementing (added to remove compiler warning) - return String.Empty; - } - - #region EventQueue (Currently not enabled) - - /// - /// - /// - /// - /// - /// - /// - public string ProcessEventQueue(string request, string path, string param) - { - string res = String.Empty; - - if (m_capsEventQueue.Count > 0) - { - lock (m_capsEventQueue) - { - string item = m_capsEventQueue.Dequeue(); - res = item; - } - } - else - { - res = CreateEmptyEventResponse(); - } - return res; - } - - /// - /// - /// - /// - /// - /// - public string CreateEstablishAgentComms(string caps, string ipAddressPort) - { - LLSDCapEvent eventItem = new LLSDCapEvent(); - eventItem.id = m_eventQueueCount; - //should be creating a EstablishAgentComms item, but there isn't a class for it yet - eventItem.events.Array.Add(new LLSDEmpty()); - string res = LLSDHelpers.SerialiseLLSDReply(eventItem); - m_eventQueueCount++; - - m_capsEventQueue.Enqueue(res); - return res; - } - - /// - /// - /// - /// - public string CreateEmptyEventResponse() - { - LLSDCapEvent eventItem = new LLSDCapEvent(); - eventItem.id = m_eventQueueCount; - eventItem.events.Array.Add(new LLSDEmpty()); - string res = LLSDHelpers.SerialiseLLSDReply(eventItem); - m_eventQueueCount++; - return res; - } - - #endregion - - /// - /// Called by the script task update handler. Provides a URL to which the client can upload a new asset. - /// - /// - /// - /// - /// HTTP request header object - /// HTTP response header object - /// - public string ScriptTaskInventory(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - try - { - m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName); - //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param); - - Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Utils.StringToBytes(request)); - LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate(); - LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest); - - string capsBase = "/CAPS/" + m_capsObjectPath; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); - - TaskInventoryScriptUpdater uploader = - new TaskInventoryScriptUpdater( - llsdUpdateRequest.item_id, - llsdUpdateRequest.task_id, - llsdUpdateRequest.is_script_running, - capsBase + uploaderPath, - m_httpListener, - m_dumpAssetsToFile); - uploader.OnUpLoad += TaskScriptUpdated; - - m_httpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); - - string protocol = "http://"; - - if (m_httpListener.UseSSL) - protocol = "https://"; - - string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + - uploaderPath; - - LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); - uploadResponse.uploader = uploaderURL; - uploadResponse.state = "upload"; - -// m_log.InfoFormat("[CAPS]: " + -// "ScriptTaskInventory response: {0}", -// LLSDHelpers.SerialiseLLSDReply(uploadResponse))); - - return LLSDHelpers.SerialiseLLSDReply(uploadResponse); - } - catch (Exception e) - { - m_log.Error("[CAPS]: " + e.ToString()); - } - - return null; - } - - public string UploadBakedTexture(string request, string path, - string param, OSHttpRequest httpRequest, - OSHttpResponse httpResponse) - { - try - { -// m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + -// m_regionName); - - string capsBase = "/CAPS/" + m_capsObjectPath; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); - - BakedTextureUploader uploader = - new BakedTextureUploader(capsBase + uploaderPath, - m_httpListener); - uploader.OnUpLoad += BakedTextureUploaded; - - m_httpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, - uploader.uploaderCaps)); - - string protocol = "http://"; - - if (m_httpListener.UseSSL) - protocol = "https://"; - - string uploaderURL = protocol + m_httpListenerHostName + ":" + - m_httpListenPort.ToString() + capsBase + uploaderPath; - - LLSDAssetUploadResponse uploadResponse = - new LLSDAssetUploadResponse(); - uploadResponse.uploader = uploaderURL; - uploadResponse.state = "upload"; - - return LLSDHelpers.SerialiseLLSDReply(uploadResponse); - } - catch (Exception e) - { - m_log.Error("[CAPS]: " + e.ToString()); - } - - return null; - } - - /// - /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset. - /// - /// - /// - /// - /// - public string NoteCardAgentInventory(string request, string path, string param, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request); - //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request); - - //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request)); - Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Utils.StringToBytes(request)); - LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); - LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest); - - string capsBase = "/CAPS/" + m_capsObjectPath; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); - - ItemUpdater uploader = - new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile); - uploader.OnUpLoad += ItemUpdated; - - m_httpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); - - string protocol = "http://"; - - if (m_httpListener.UseSSL) - protocol = "https://"; - - string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + - uploaderPath; - - LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); - uploadResponse.uploader = uploaderURL; - uploadResponse.state = "upload"; - -// m_log.InfoFormat("[CAPS]: " + -// "NoteCardAgentInventory response: {0}", -// LLSDHelpers.SerialiseLLSDReply(uploadResponse))); - - return LLSDHelpers.SerialiseLLSDReply(uploadResponse); - } - - /// - /// - /// - /// - /// - public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest) - { - //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); - //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); - - if (llsdRequest.asset_type == "texture" || - llsdRequest.asset_type == "animation" || - llsdRequest.asset_type == "sound") - { - IClientAPI client = null; - IScene scene = null; - if (GetClient != null) - { - client = GetClient(m_agentID); - scene = client.Scene; - - IMoneyModule mm = scene.RequestModuleInterface(); - - if (mm != null) - { - if (!mm.UploadCovered(client, mm.UploadCharge)) - { - if (client != null) - client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); - - LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); - errorResponse.uploader = ""; - errorResponse.state = "error"; - return errorResponse; - } - } - } - } - - - string assetName = llsdRequest.name; - string assetDes = llsdRequest.description; - string capsBase = "/CAPS/" + m_capsObjectPath; - UUID newAsset = UUID.Random(); - UUID newInvItem = UUID.Random(); - UUID parentFolder = llsdRequest.folder_id; - string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); - - AssetUploader uploader = - new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, - llsdRequest.asset_type, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile); - m_httpListener.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); - - string protocol = "http://"; - - if (m_httpListener.UseSSL) - protocol = "https://"; - - string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + - uploaderPath; - - LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); - uploadResponse.uploader = uploaderURL; - uploadResponse.state = "upload"; - uploader.OnUpLoad += UploadCompleteHandler; - return uploadResponse; - } - - /// - /// - /// - /// - /// - /// - public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, - UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, - string assetType) - { - sbyte assType = 0; - sbyte inType = 0; - - if (inventoryType == "sound") - { - inType = 1; - assType = 1; - } - else if (inventoryType == "animation") - { - inType = 19; - assType = 20; - } - else if (inventoryType == "wearable") - { - inType = 18; - switch (assetType) - { - case "bodypart": - assType = 13; - break; - case "clothing": - assType = 5; - break; - } - } - - AssetBase asset; - asset = new AssetBase(assetID, assetName, assType, m_agentID.ToString()); - asset.Data = data; - if (AddNewAsset != null) - AddNewAsset(asset); - else if (m_assetCache != null) - m_assetCache.Store(asset); - - InventoryItemBase item = new InventoryItemBase(); - item.Owner = m_agentID; - item.CreatorId = m_agentID.ToString(); - item.CreatorData = String.Empty; - item.ID = inventoryItem; - item.AssetID = asset.FullID; - item.Description = assetDescription; - item.Name = assetName; - item.AssetType = assType; - item.InvType = inType; - item.Folder = parentFolder; - item.CurrentPermissions = (uint)PermissionMask.All; - item.BasePermissions = (uint)PermissionMask.All; - item.EveryOnePermissions = 0; - item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); - item.CreationDate = Util.UnixTimeSinceEpoch(); - - if (AddNewInventoryItem != null) - { - AddNewInventoryItem(m_agentID, item); - } - } - - public void BakedTextureUploaded(UUID assetID, byte[] data) - { -// m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); - - AssetBase asset; - asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString()); - asset.Data = data; - asset.Temporary = true; - asset.Local = ! m_persistBakedTextures; // Local assets aren't persisted, non-local are - m_assetCache.Store(asset); - } - - /// - /// Called when new asset data for an agent inventory item update has been uploaded. - /// - /// Item to update - /// New asset data - /// - public UUID ItemUpdated(UUID itemID, byte[] data) - { - if (ItemUpdatedCall != null) - { - return ItemUpdatedCall(m_agentID, itemID, data); - } - - return UUID.Zero; - } - - /// - /// Called when new asset data for an agent inventory item update has been uploaded. - /// - /// Item to update - /// Prim containing item to update - /// Signals whether the script to update is currently running - /// New asset data - public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors) - { - if (TaskScriptUpdatedCall != null) - { - ArrayList e = TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data); - foreach (Object item in e) - errors.Add(item); - } - } - - public class AssetUploader - { - public event UpLoadedAsset OnUpLoad; - private UpLoadedAsset handlerUpLoad = null; - - private string uploaderPath = String.Empty; - private UUID newAssetID; - private UUID inventoryItemID; - private UUID parentFolder; - private IHttpServer httpListener; - private bool m_dumpAssetsToFile; - private string m_assetName = String.Empty; - private string m_assetDes = String.Empty; - - private string m_invType = String.Empty; - private string m_assetType = String.Empty; - - public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem, - UUID parentFolderID, string invType, string assetType, string path, - IHttpServer httpServer, bool dumpAssetsToFile) - { - m_assetName = assetName; - m_assetDes = description; - newAssetID = assetID; - inventoryItemID = inventoryItem; - uploaderPath = path; - httpListener = httpServer; - parentFolder = parentFolderID; - m_assetType = assetType; - m_invType = invType; - m_dumpAssetsToFile = dumpAssetsToFile; - } - - /// - /// - /// - /// - /// - /// - /// - public string uploaderCaps(byte[] data, string path, string param) - { - UUID inv = inventoryItemID; - string res = String.Empty; - LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); - uploadComplete.new_asset = newAssetID.ToString(); - uploadComplete.new_inventory_item = inv; - uploadComplete.state = "complete"; - - res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); - - httpListener.RemoveStreamHandler("POST", uploaderPath); - - // TODO: probably make this a better set of extensions here - string extension = ".jp2"; - if (m_invType != "image") - { - extension = ".dat"; - } - - if (m_dumpAssetsToFile) - { - SaveAssetToFile(m_assetName + extension, data); - } - handlerUpLoad = OnUpLoad; - if (handlerUpLoad != null) - { - handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType); - } - - return res; - } - ///Left this in and commented in case there are unforseen issues - //private void SaveAssetToFile(string filename, byte[] data) - //{ - // FileStream fs = File.Create(filename); - // BinaryWriter bw = new BinaryWriter(fs); - // bw.Write(data); - // bw.Close(); - // fs.Close(); - //} - private static void SaveAssetToFile(string filename, byte[] data) - { - string assetPath = "UserAssets"; - if (!Directory.Exists(assetPath)) - { - Directory.CreateDirectory(assetPath); - } - FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(filename))); - BinaryWriter bw = new BinaryWriter(fs); - bw.Write(data); - bw.Close(); - fs.Close(); - } - } - - /// - /// This class is a callback invoked when a client sends asset data to - /// an agent inventory notecard update url - /// - public class ItemUpdater - { - public event UpdateItem OnUpLoad; - - private UpdateItem handlerUpdateItem = null; - - private string uploaderPath = String.Empty; - private UUID inventoryItemID; - private IHttpServer httpListener; - private bool m_dumpAssetToFile; - - public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile) - { - m_dumpAssetToFile = dumpAssetToFile; - - inventoryItemID = inventoryItem; - uploaderPath = path; - httpListener = httpServer; - } - - /// - /// - /// - /// - /// - /// - /// - public string uploaderCaps(byte[] data, string path, string param) - { - UUID inv = inventoryItemID; - string res = String.Empty; - LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); - UUID assetID = UUID.Zero; - handlerUpdateItem = OnUpLoad; - if (handlerUpdateItem != null) - { - assetID = handlerUpdateItem(inv, data); - } - - uploadComplete.new_asset = assetID.ToString(); - uploadComplete.new_inventory_item = inv; - uploadComplete.state = "complete"; - - res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); - - httpListener.RemoveStreamHandler("POST", uploaderPath); - - if (m_dumpAssetToFile) - { - SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data); - } - - return res; - } - ///Left this in and commented in case there are unforseen issues - //private void SaveAssetToFile(string filename, byte[] data) - //{ - // FileStream fs = File.Create(filename); - // BinaryWriter bw = new BinaryWriter(fs); - // bw.Write(data); - // bw.Close(); - // fs.Close(); - //} - private static void SaveAssetToFile(string filename, byte[] data) - { - string assetPath = "UserAssets"; - if (!Directory.Exists(assetPath)) - { - Directory.CreateDirectory(assetPath); - } - FileStream fs = File.Create(Path.Combine(assetPath, filename)); - BinaryWriter bw = new BinaryWriter(fs); - bw.Write(data); - bw.Close(); - fs.Close(); - } - } - - /// - /// This class is a callback invoked when a client sends asset data to - /// a task inventory script update url - /// - public class TaskInventoryScriptUpdater - { - public event UpdateTaskScript OnUpLoad; - - private UpdateTaskScript handlerUpdateTaskScript = null; - - private string uploaderPath = String.Empty; - private UUID inventoryItemID; - private UUID primID; - private bool isScriptRunning; - private IHttpServer httpListener; - private bool m_dumpAssetToFile; - - public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning, - string path, IHttpServer httpServer, bool dumpAssetToFile) - { - m_dumpAssetToFile = dumpAssetToFile; - - this.inventoryItemID = inventoryItemID; - this.primID = primID; - - // This comes in over the packet as an integer, but actually appears to be treated as a bool - this.isScriptRunning = (0 == isScriptRunning ? false : true); - - uploaderPath = path; - httpListener = httpServer; - } - - /// - /// - /// - /// - /// - /// - /// - public string uploaderCaps(byte[] data, string path, string param) - { - try - { -// m_log.InfoFormat("[CAPS]: " + -// "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}", -// data, path, param)); - - string res = String.Empty; - LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete(); - - ArrayList errors = new ArrayList(); - handlerUpdateTaskScript = OnUpLoad; - if (handlerUpdateTaskScript != null) - { - handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors); - } - - uploadComplete.new_asset = inventoryItemID; - uploadComplete.compiled = errors.Count > 0 ? false : true; - uploadComplete.state = "complete"; - uploadComplete.errors = new OSDArray(); - uploadComplete.errors.Array = errors; - - res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); - - httpListener.RemoveStreamHandler("POST", uploaderPath); - - if (m_dumpAssetToFile) - { - SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data); - } - -// m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res); - - return res; - } - catch (Exception e) - { - m_log.Error("[CAPS]: " + e.ToString()); - } - - // XXX Maybe this should be some meaningful error packet - return null; - } - ///Left this in and commented in case there are unforseen issues - //private void SaveAssetToFile(string filename, byte[] data) - //{ - // FileStream fs = File.Create(filename); - // BinaryWriter bw = new BinaryWriter(fs); - // bw.Write(data); - // bw.Close(); - // fs.Close(); - //} - private static void SaveAssetToFile(string filename, byte[] data) - { - string assetPath = "UserAssets"; - if (!Directory.Exists(assetPath)) - { - Directory.CreateDirectory(assetPath); - } - FileStream fs = File.Create(Path.Combine(assetPath, filename)); - BinaryWriter bw = new BinaryWriter(fs); - bw.Write(data); - bw.Close(); - fs.Close(); - } - } - - public class BakedTextureUploader - { - public event UploadedBakedTexture OnUpLoad; - private UploadedBakedTexture handlerUpLoad = null; - - private string uploaderPath = String.Empty; - private UUID newAssetID; - private IHttpServer httpListener; - - public BakedTextureUploader(string path, IHttpServer httpServer) - { - newAssetID = UUID.Random(); - uploaderPath = path; - httpListener = httpServer; -// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID); - } - - /// - /// - /// - /// - /// - /// - /// - public string uploaderCaps(byte[] data, string path, string param) - { - handlerUpLoad = OnUpLoad; - if (handlerUpLoad != null) - { - Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); }); - } - - string res = String.Empty; - LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); - uploadComplete.new_asset = newAssetID.ToString(); - uploadComplete.new_inventory_item = UUID.Zero; - uploadComplete.state = "complete"; - - res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); - - httpListener.RemoveStreamHandler("POST", uploaderPath); - -// m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID); - - return res; - } - } - } -} diff --git a/OpenSim/Framework/Capabilities/CapsUtil.cs b/OpenSim/Framework/CapsUtil.cs similarity index 98% rename from OpenSim/Framework/Capabilities/CapsUtil.cs rename to OpenSim/Framework/CapsUtil.cs index faf2708541..4baf505784 100644 --- a/OpenSim/Framework/Capabilities/CapsUtil.cs +++ b/OpenSim/Framework/CapsUtil.cs @@ -27,7 +27,7 @@ using OpenMetaverse; -namespace OpenSim.Framework.Capabilities +namespace OpenSim.Framework { /// /// Capabilities utility methods diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index a626b82302..28fe3ba889 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -462,7 +462,7 @@ namespace OpenSim.Framework } catch (IndexOutOfRangeException e) { - m_log.WarnFormat("[CHILD AGENT DATA]: scrtips list is shorter than object list."); + m_log.WarnFormat("[CHILD AGENT DATA]: scripts list is shorter than object list."); } attObjs.Add(info); diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 9d70f63189..4734fc1f83 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -140,19 +140,19 @@ namespace OpenSim.Framework /// PUT JSON-encoded data to a web service that returns LLSD or /// JSON data /// - public static OSDMap PutToService(string url, OSDMap data) + public static OSDMap PutToService(string url, OSDMap data, int timeout) { - return ServiceOSDRequest(url,data,"PUT",10000); + return ServiceOSDRequest(url,data, "PUT", timeout); } - - public static OSDMap PostToService(string url, OSDMap data) + + public static OSDMap PostToService(string url, OSDMap data, int timeout) { - return ServiceOSDRequest(url,data,"POST",10000); + return ServiceOSDRequest(url, data, "POST", timeout); } - - public static OSDMap GetFromService(string url) + + public static OSDMap GetFromService(string url, int timeout) { - return ServiceOSDRequest(url,null,"GET",10000); + return ServiceOSDRequest(url, null, "GET", timeout); } public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout) @@ -177,9 +177,9 @@ namespace OpenSim.Framework // If there is some input, write it into the request if (data != null) { - string strBuffer = OSDParser.SerializeJsonString(data); + string strBuffer = OSDParser.SerializeJsonString(data); byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); - + request.ContentType = "application/json"; request.ContentLength = buffer.Length; //Count bytes to send using (Stream requestStream = request.GetRequestStream()) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs new file mode 100644 index 0000000000..95713e9b87 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -0,0 +1,938 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Reflection; + +using OpenMetaverse; +using Nini.Config; +using log4net; + +using OpenSim.Framework; +using OpenSim.Framework.Capabilities; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Services.Interfaces; + +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.ClientStack.Linden +{ + public delegate void UpLoadedAsset( + string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder, + byte[] data, string inventoryType, string assetType); + + public delegate void UploadedBakedTexture(UUID assetID, byte[] data); + + public delegate UUID UpdateItem(UUID itemID, byte[] data); + + public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); + + public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); + + public delegate void NewAsset(AssetBase asset); + + public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data); + + public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID, + bool isScriptRunning, byte[] data); + + public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, + bool fetchFolders, bool fetchItems, int sortOrder, out int version); + + /// + /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that + /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want + /// to just pass the whole Scene into CAPS. + /// + public delegate IClientAPI GetClientDelegate(UUID agentID); + + public class BunchOfCaps + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_Scene; + private Caps m_HostCapsObj; + + private static readonly string m_requestPath = "0000/"; + // private static readonly string m_mapLayerPath = "0001/"; + private static readonly string m_newInventory = "0002/"; + //private static readonly string m_requestTexture = "0003/"; + private static readonly string m_notecardUpdatePath = "0004/"; + private static readonly string m_notecardTaskUpdatePath = "0005/"; + // private static readonly string m_fetchInventoryPath = "0006/"; + // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. + private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule. + + + // These are callbacks which will be setup by the scene so that we can update scene data when we + // receive capability calls + public NewInventoryItem AddNewInventoryItem = null; + public NewAsset AddNewAsset = null; + public ItemUpdatedCallback ItemUpdatedCall = null; + public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; + public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null; + public GetClientDelegate GetClient = null; + + private bool m_persistBakedTextures = false; + private IAssetService m_assetService; + private bool m_dumpAssetsToFile; + private string m_regionName; + + public BunchOfCaps(Scene scene, Caps caps) + { + m_Scene = scene; + m_HostCapsObj = caps; + IConfigSource config = m_Scene.Config; + if (config != null) + { + IConfig sconfig = config.Configs["Startup"]; + if (sconfig != null) + m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); + } + + m_assetService = m_Scene.AssetService; + m_regionName = m_Scene.RegionInfo.RegionName; + + RegisterHandlers(); + + AddNewInventoryItem = m_Scene.AddUploadedInventoryItem; + ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset; + TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset; + CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS; + GetClient = m_Scene.SceneContents.GetControllingClient; + + } + + /// + /// Register a bunch of CAPS http service handlers + /// + public void RegisterHandlers() + { + string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; + + RegisterRegionServiceHandlers(capsBase); + RegisterInventoryServiceHandlers(capsBase); + } + + public void RegisterRegionServiceHandlers(string capsBase) + { + try + { + // the root of all evil + m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest)); + m_log.DebugFormat( + "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID); + + //m_capsHandlers["MapLayer"] = + // new LLSDStreamhandler("POST", + // capsBase + m_mapLayerPath, + // GetMapLayer); + IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory); + m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req); + m_HostCapsObj.RegisterHandler("UpdateScriptTask", req); + m_HostCapsObj.RegisterHandler("UploadBakedTexture", new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture)); + + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + } + + public void RegisterInventoryServiceHandlers(string capsBase) + { + try + { + // I don't think this one works... + m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler("POST", + capsBase + m_newInventory, + NewAgentInventoryRequest)); + IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory); + m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); + m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); + m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); + + // As of RC 1.22.9 of the Linden client this is + // supported + + //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); + + // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and + // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires + // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service, + // but when I went on the Linden grid, the + // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead, + // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP + // + // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid + // we will be + // able to get the data we need to implement the necessary part of the protocol to fix the issue above. + // m_capsHandlers["FetchInventoryDescendents"] = + // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest); + + // m_capsHandlers["FetchInventoryDescendents"] = + // new LLSDStreamhandler("POST", + // capsBase + m_fetchInventory, + // FetchInventory)); + // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST", + // capsBase + m_requestTexture, + // RequestTexture); + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + } + + /// + /// Construct a client response detailing all the capabilities this server can provide. + /// + /// + /// + /// + /// HTTP request header object + /// HTTP response header object + /// + public string SeedCapRequest(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); + + if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) + { + m_log.DebugFormat("[CAPS]: Unauthorized CAPS client"); + return string.Empty; + } + + Hashtable caps = m_HostCapsObj.CapsHandlers.CapsDetails; + // Add the external too + foreach (KeyValuePair kvp in m_HostCapsObj.ExternalCapsHandlers) + caps[kvp.Key] = kvp.Value; + + string result = LLSDHelpers.SerialiseLLSDReply(caps); + + //m_log.DebugFormat("[CAPS] CapsRequest {0}", result); + + return result; + } + + /// + /// Called by the script task update handler. Provides a URL to which the client can upload a new asset. + /// + /// + /// + /// + /// HTTP request header object + /// HTTP response header object + /// + public string ScriptTaskInventory(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + try + { + m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName); + //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param); + + Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); + LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate(); + LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest); + + string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + TaskInventoryScriptUpdater uploader = + new TaskInventoryScriptUpdater( + llsdUpdateRequest.item_id, + llsdUpdateRequest.task_id, + llsdUpdateRequest.is_script_running, + capsBase + uploaderPath, + m_HostCapsObj.HttpListener, + m_dumpAssetsToFile); + uploader.OnUpLoad += TaskScriptUpdated; + + m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + + string protocol = "http://"; + + if (m_HostCapsObj.SSLCaps) + protocol = "https://"; + + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + + // m_log.InfoFormat("[CAPS]: " + + // "ScriptTaskInventory response: {0}", + // LLSDHelpers.SerialiseLLSDReply(uploadResponse))); + + return LLSDHelpers.SerialiseLLSDReply(uploadResponse); + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + + return null; + } + + /// + /// Called when new asset data for an agent inventory item update has been uploaded. + /// + /// Item to update + /// Prim containing item to update + /// Signals whether the script to update is currently running + /// New asset data + public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors) + { + if (TaskScriptUpdatedCall != null) + { + ArrayList e = TaskScriptUpdatedCall(m_HostCapsObj.AgentID, itemID, primID, isScriptRunning, data); + foreach (Object item in e) + errors.Add(item); + } + } + + public string UploadBakedTexture(string request, string path, + string param, OSHttpRequest httpRequest, + OSHttpResponse httpResponse) + { + try + { + // m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + + // m_regionName); + + string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + BakedTextureUploader uploader = + new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener); + uploader.OnUpLoad += BakedTextureUploaded; + + m_HostCapsObj.HttpListener.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, + uploader.uploaderCaps)); + + string protocol = "http://"; + + if (m_HostCapsObj.SSLCaps) + protocol = "https://"; + + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + + m_HostCapsObj.Port.ToString() + capsBase + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = + new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + + return LLSDHelpers.SerialiseLLSDReply(uploadResponse); + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + + return null; + } + + public void BakedTextureUploaded(UUID assetID, byte[] data) + { + // m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); + + AssetBase asset; + asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString()); + asset.Data = data; + asset.Temporary = true; + asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are + m_assetService.Store(asset); + } + + /// + /// Called when new asset data for an agent inventory item update has been uploaded. + /// + /// Item to update + /// New asset data + /// + public UUID ItemUpdated(UUID itemID, byte[] data) + { + if (ItemUpdatedCall != null) + { + return ItemUpdatedCall(m_HostCapsObj.AgentID, itemID, data); + } + + return UUID.Zero; + } + + /// + /// + /// + /// + /// + public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest) + { + //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); + //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); + + if (llsdRequest.asset_type == "texture" || + llsdRequest.asset_type == "animation" || + llsdRequest.asset_type == "sound") + { + IClientAPI client = null; + IScene scene = null; + if (GetClient != null) + { + client = GetClient(m_HostCapsObj.AgentID); + scene = client.Scene; + + IMoneyModule mm = scene.RequestModuleInterface(); + + if (mm != null) + { + if (!mm.UploadCovered(client, mm.UploadCharge)) + { + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); + + LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); + errorResponse.uploader = ""; + errorResponse.state = "error"; + return errorResponse; + } + } + } + } + + string assetName = llsdRequest.name; + string assetDes = llsdRequest.description; + string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; + UUID newAsset = UUID.Random(); + UUID newInvItem = UUID.Random(); + UUID parentFolder = llsdRequest.folder_id; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + AssetUploader uploader = + new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, + llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); + m_HostCapsObj.HttpListener.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + + string protocol = "http://"; + + if (m_HostCapsObj.SSLCaps) + protocol = "https://"; + + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + uploader.OnUpLoad += UploadCompleteHandler; + return uploadResponse; + } + + /// + /// + /// + /// + /// + /// + public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, + UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, + string assetType) + { + sbyte assType = 0; + sbyte inType = 0; + + if (inventoryType == "sound") + { + inType = 1; + assType = 1; + } + else if (inventoryType == "animation") + { + inType = 19; + assType = 20; + } + else if (inventoryType == "wearable") + { + inType = 18; + switch (assetType) + { + case "bodypart": + assType = 13; + break; + case "clothing": + assType = 5; + break; + } + } + + AssetBase asset; + asset = new AssetBase(assetID, assetName, assType, m_HostCapsObj.AgentID.ToString()); + asset.Data = data; + if (AddNewAsset != null) + AddNewAsset(asset); + else if (m_assetService != null) + m_assetService.Store(asset); + + InventoryItemBase item = new InventoryItemBase(); + item.Owner = m_HostCapsObj.AgentID; + item.CreatorId = m_HostCapsObj.AgentID.ToString(); + item.CreatorData = String.Empty; + item.ID = inventoryItem; + item.AssetID = asset.FullID; + item.Description = assetDescription; + item.Name = assetName; + item.AssetType = assType; + item.InvType = inType; + item.Folder = parentFolder; + item.CurrentPermissions = (uint)PermissionMask.All; + item.BasePermissions = (uint)PermissionMask.All; + item.EveryOnePermissions = 0; + item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); + item.CreationDate = Util.UnixTimeSinceEpoch(); + + if (AddNewInventoryItem != null) + { + AddNewInventoryItem(m_HostCapsObj.AgentID, item); + } + } + + + + /// + /// + /// + /// + /// + public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) + { + m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName); + LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); + mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); + return mapResponse; + } + + /// + /// + /// + /// + protected static OSDMapLayer GetOSDMapLayerResponse() + { + OSDMapLayer mapLayer = new OSDMapLayer(); + mapLayer.Right = 5000; + mapLayer.Top = 5000; + mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); + + return mapLayer; + } + + /// + /// + /// + /// + /// + /// + /// + public string RequestTexture(string request, string path, string param) + { + m_log.Debug("texture request " + request); + // Needs implementing (added to remove compiler warning) + return String.Empty; + } + + + /// + /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset. + /// + /// + /// + /// + /// + public string NoteCardAgentInventory(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request); + //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request); + + //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request)); + Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); + LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); + LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest); + + string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + ItemUpdater uploader = + new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); + uploader.OnUpLoad += ItemUpdated; + + m_HostCapsObj.HttpListener.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + + string protocol = "http://"; + + if (m_HostCapsObj.SSLCaps) + protocol = "https://"; + + string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + + // m_log.InfoFormat("[CAPS]: " + + // "NoteCardAgentInventory response: {0}", + // LLSDHelpers.SerialiseLLSDReply(uploadResponse))); + + return LLSDHelpers.SerialiseLLSDReply(uploadResponse); + } + } + + public class AssetUploader + { + public event UpLoadedAsset OnUpLoad; + private UpLoadedAsset handlerUpLoad = null; + + private string uploaderPath = String.Empty; + private UUID newAssetID; + private UUID inventoryItemID; + private UUID parentFolder; + private IHttpServer httpListener; + private bool m_dumpAssetsToFile; + private string m_assetName = String.Empty; + private string m_assetDes = String.Empty; + + private string m_invType = String.Empty; + private string m_assetType = String.Empty; + + public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem, + UUID parentFolderID, string invType, string assetType, string path, + IHttpServer httpServer, bool dumpAssetsToFile) + { + m_assetName = assetName; + m_assetDes = description; + newAssetID = assetID; + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + parentFolder = parentFolderID; + m_assetType = assetType; + m_invType = invType; + m_dumpAssetsToFile = dumpAssetsToFile; + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + UUID inv = inventoryItemID; + string res = String.Empty; + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + uploadComplete.new_asset = newAssetID.ToString(); + uploadComplete.new_inventory_item = inv; + uploadComplete.state = "complete"; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + // TODO: probably make this a better set of extensions here + string extension = ".jp2"; + if (m_invType != "image") + { + extension = ".dat"; + } + + if (m_dumpAssetsToFile) + { + SaveAssetToFile(m_assetName + extension, data); + } + handlerUpLoad = OnUpLoad; + if (handlerUpLoad != null) + { + handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType); + } + + return res; + } + ///Left this in and commented in case there are unforseen issues + //private void SaveAssetToFile(string filename, byte[] data) + //{ + // FileStream fs = File.Create(filename); + // BinaryWriter bw = new BinaryWriter(fs); + // bw.Write(data); + // bw.Close(); + // fs.Close(); + //} + private static void SaveAssetToFile(string filename, byte[] data) + { + string assetPath = "UserAssets"; + if (!Directory.Exists(assetPath)) + { + Directory.CreateDirectory(assetPath); + } + FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(filename))); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + } + + /// + /// This class is a callback invoked when a client sends asset data to + /// an agent inventory notecard update url + /// + public class ItemUpdater + { + public event UpdateItem OnUpLoad; + + private UpdateItem handlerUpdateItem = null; + + private string uploaderPath = String.Empty; + private UUID inventoryItemID; + private IHttpServer httpListener; + private bool m_dumpAssetToFile; + + public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile) + { + m_dumpAssetToFile = dumpAssetToFile; + + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + UUID inv = inventoryItemID; + string res = String.Empty; + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + UUID assetID = UUID.Zero; + handlerUpdateItem = OnUpLoad; + if (handlerUpdateItem != null) + { + assetID = handlerUpdateItem(inv, data); + } + + uploadComplete.new_asset = assetID.ToString(); + uploadComplete.new_inventory_item = inv; + uploadComplete.state = "complete"; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + if (m_dumpAssetToFile) + { + SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data); + } + + return res; + } + ///Left this in and commented in case there are unforseen issues + //private void SaveAssetToFile(string filename, byte[] data) + //{ + // FileStream fs = File.Create(filename); + // BinaryWriter bw = new BinaryWriter(fs); + // bw.Write(data); + // bw.Close(); + // fs.Close(); + //} + private static void SaveAssetToFile(string filename, byte[] data) + { + string assetPath = "UserAssets"; + if (!Directory.Exists(assetPath)) + { + Directory.CreateDirectory(assetPath); + } + FileStream fs = File.Create(Path.Combine(assetPath, filename)); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + } + + /// + /// This class is a callback invoked when a client sends asset data to + /// a task inventory script update url + /// + public class TaskInventoryScriptUpdater + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public event UpdateTaskScript OnUpLoad; + + private UpdateTaskScript handlerUpdateTaskScript = null; + + private string uploaderPath = String.Empty; + private UUID inventoryItemID; + private UUID primID; + private bool isScriptRunning; + private IHttpServer httpListener; + private bool m_dumpAssetToFile; + + public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning, + string path, IHttpServer httpServer, bool dumpAssetToFile) + { + m_dumpAssetToFile = dumpAssetToFile; + + this.inventoryItemID = inventoryItemID; + this.primID = primID; + + // This comes in over the packet as an integer, but actually appears to be treated as a bool + this.isScriptRunning = (0 == isScriptRunning ? false : true); + + uploaderPath = path; + httpListener = httpServer; + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + try + { + // m_log.InfoFormat("[CAPS]: " + + // "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}", + // data, path, param)); + + string res = String.Empty; + LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete(); + + ArrayList errors = new ArrayList(); + handlerUpdateTaskScript = OnUpLoad; + if (handlerUpdateTaskScript != null) + { + handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors); + } + + uploadComplete.new_asset = inventoryItemID; + uploadComplete.compiled = errors.Count > 0 ? false : true; + uploadComplete.state = "complete"; + uploadComplete.errors = new OSDArray(); + uploadComplete.errors.Array = errors; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + if (m_dumpAssetToFile) + { + SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data); + } + + // m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res); + + return res; + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + + // XXX Maybe this should be some meaningful error packet + return null; + } + ///Left this in and commented in case there are unforseen issues + //private void SaveAssetToFile(string filename, byte[] data) + //{ + // FileStream fs = File.Create(filename); + // BinaryWriter bw = new BinaryWriter(fs); + // bw.Write(data); + // bw.Close(); + // fs.Close(); + //} + private static void SaveAssetToFile(string filename, byte[] data) + { + string assetPath = "UserAssets"; + if (!Directory.Exists(assetPath)) + { + Directory.CreateDirectory(assetPath); + } + FileStream fs = File.Create(Path.Combine(assetPath, filename)); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + } + + public class BakedTextureUploader + { + public event UploadedBakedTexture OnUpLoad; + private UploadedBakedTexture handlerUpLoad = null; + + private string uploaderPath = String.Empty; + private UUID newAssetID; + private IHttpServer httpListener; + + public BakedTextureUploader(string path, IHttpServer httpServer) + { + newAssetID = UUID.Random(); + uploaderPath = path; + httpListener = httpServer; + // m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID); + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + handlerUpLoad = OnUpLoad; + if (handlerUpLoad != null) + { + Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); }); + } + + string res = String.Empty; + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + uploadComplete.new_asset = newAssetID.ToString(); + uploadComplete.new_inventory_item = UUID.Zero; + uploadComplete.state = "complete"; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + // m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID); + + return res; + } + } + +} diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs new file mode 100644 index 0000000000..14160ae7cd --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs @@ -0,0 +1,91 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; + +using log4net; +using Nini.Config; +using OpenMetaverse; +using Mono.Addins; + +using OpenSim.Framework; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using Caps = OpenSim.Framework.Capabilities.Caps; + +[assembly: Addin("LindenCaps", "0.1")] +[assembly: AddinDependency("OpenSim", "0.5")] +namespace OpenSim.Region.ClientStack.Linden +{ + + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class BunchOfCapsModule : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_Scene; + + #region INonSharedRegionModule + + public string Name { get { return "BunchOfCapsModule"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { + } + + public void Close() { } + + public void AddRegion(Scene scene) + { + m_Scene = scene; + m_Scene.EventManager.OnRegisterCaps += OnRegisterCaps; + } + + public void RemoveRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) + { + } + + public void PostInitialise() { } + #endregion + + private void OnRegisterCaps(UUID agentID, Caps caps) + { + new BunchOfCaps(m_Scene, caps); + } + + } +} diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs similarity index 98% rename from OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs rename to OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 05fe3eee04..139d8b8902 100644 --- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -33,6 +33,7 @@ using System.Reflection; using System.Threading; using log4net; using Nini.Config; +using Mono.Addins; using OpenMetaverse; using OpenMetaverse.Messages.Linden; using OpenMetaverse.Packets; @@ -45,7 +46,7 @@ using OpenSim.Region.Framework.Scenes; using BlockingLLSDQueue = OpenSim.Framework.BlockingQueue; using Caps=OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Framework.EventQueue +namespace OpenSim.Region.ClientStack.Linden { public struct QueueItem { @@ -53,6 +54,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue public OSDMap body; } + //[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class EventQueueGetModule : IEventQueue, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -270,9 +272,9 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue public void OnRegisterCaps(UUID agentID, Caps caps) { // Register an event queue for the client - + //m_log.DebugFormat( - // "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", + // "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", // agentID, caps, m_scene.RegionInfo.RegionName); // Let's instantiate a Queue for this agent right now @@ -315,7 +317,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue { return ProcessQueue(m_dhttpMethod, agentID, caps); })); - + // This will persist this beyond the expiry of the caps handlers MainServer.Instance.AddPollServiceHTTPHandler( capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); @@ -520,7 +522,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue } if (AvatarID != UUID.Zero) { - return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsHandlerForUser(AvatarID)); + return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID)); } else { @@ -715,5 +717,15 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue OSD item = EventQueueHelper.PlacesQuery(groupUpdate); Enqueue(item, avatarID); } + + public OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono) + { + return EventQueueHelper.ScriptRunningReplyEvent(objectID, itemID, running, mono); + } + + public OSD BuildEvent(string eventName, OSD eventBody) + { + return EventQueueHelper.BuildEvent(eventName, eventBody); + } } } diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs similarity index 97% rename from OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs rename to OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs index 0d7d16a2ba..3f49abaf56 100644 --- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs @@ -32,7 +32,7 @@ using OpenMetaverse.Packets; using OpenMetaverse.StructuredData; using OpenMetaverse.Messages.Linden; -namespace OpenSim.Region.CoreModules.Framework.EventQueue +namespace OpenSim.Region.ClientStack.Linden { public class EventQueueHelper { @@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue // return result; // } - public static OSD buildEvent(string eventName, OSD eventBody) + public static OSD BuildEvent(string eventName, OSD eventBody) { OSDMap llsdEvent = new OSDMap(2); llsdEvent.Add("message", new OSDString(eventName)); @@ -84,7 +84,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue OSDMap llsdBody = new OSDMap(1); llsdBody.Add("SimulatorInfo", arr); - return buildEvent("EnableSimulator", llsdBody); + return BuildEvent("EnableSimulator", llsdBody); } public static OSD DisableSimulator(ulong handle) @@ -99,7 +99,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue OSDMap llsdBody = new OSDMap(0); //llsdBody.Add("SimulatorInfo", arr); - return buildEvent("DisableSimulator", llsdBody); + return BuildEvent("DisableSimulator", llsdBody); } public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, @@ -144,7 +144,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue llsdBody.Add("AgentData", agentDataArr); llsdBody.Add("RegionData", regionDataArr); - return buildEvent("CrossedRegion", llsdBody); + return BuildEvent("CrossedRegion", llsdBody); } public static OSD TeleportFinishEvent( @@ -167,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue OSDMap body = new OSDMap(); body.Add("Info", infoArr); - return buildEvent("TeleportFinish", body); + return BuildEvent("TeleportFinish", body); } public static OSD ScriptRunningReplyEvent(UUID objectID, UUID itemID, bool running, bool mono) @@ -184,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue OSDMap body = new OSDMap(); body.Add("Script", scriptArr); - return buildEvent("ScriptRunningReply", body); + return BuildEvent("ScriptRunningReply", body); } public static OSD EstablishAgentCommunication(UUID agentID, string simIpAndPort, string seedcap) @@ -194,12 +194,12 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue body.Add("sim-ip-and-port", new OSDString(simIpAndPort)); body.Add("seed-capability", new OSDString(seedcap)); - return buildEvent("EstablishAgentCommunication", body); + return BuildEvent("EstablishAgentCommunication", body); } public static OSD KeepAliveEvent() { - return buildEvent("FAKEEVENT", new OSDMap()); + return BuildEvent("FAKEEVENT", new OSDMap()); } public static OSD AgentParams(UUID agentID, bool checkEstate, int godLevel, bool limitedToEstate) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs new file mode 100644 index 0000000000..e0807eea98 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -0,0 +1,139 @@ +/* + * 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.Specialized; +using System.Reflection; +using System.IO; +using System.Web; +using Mono.Addins; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Capabilities.Handlers; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.ClientStack.Linden +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class GetMeshModule : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + private IAssetService m_AssetService; + private bool m_Enabled = true; + private string m_URL; + + #region IRegionModuleBase Members + + public Type ReplaceableInterface + { + get { return null; } + } + + public void Initialise(IConfigSource source) + { + IConfig config = source.Configs["ClientStack.LindenCaps"]; + if (config == null) + return; + + m_URL = config.GetString("Cap_GetMesh", string.Empty); + // Cap doesn't exist + if (m_URL != string.Empty) + m_Enabled = true; + } + + public void AddRegion(Scene pScene) + { + if (!m_Enabled) + return; + + m_scene = pScene; + } + + public void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + m_scene.EventManager.OnRegisterCaps -= RegisterCaps; + m_scene = null; + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + m_AssetService = m_scene.RequestModuleInterface(); + m_scene.EventManager.OnRegisterCaps += RegisterCaps; + } + + + public void Close() { } + + public string Name { get { return "GetMeshModule"; } } + + #endregion + + + public void RegisterCaps(UUID agentID, Caps caps) + { + UUID capID = UUID.Random(); + + //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); + if (m_URL == "localhost") + { + m_log.InfoFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); + GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); + IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), + delegate(Hashtable m_dhttpMethod) + { + return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null); + }); + + caps.RegisterHandler("GetMesh", reqHandler); + } + else + { + m_log.InfoFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); + caps.RegisterHandler("GetMesh", m_URL); + } + } + + } +} diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs new file mode 100644 index 0000000000..35eedb48ab --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -0,0 +1,142 @@ +/* + * 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.Specialized; +using System.Drawing; +using System.Drawing.Imaging; +using System.Reflection; +using System.IO; +using System.Web; +using log4net; +using Nini.Config; +using Mono.Addins; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenMetaverse.Imaging; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; +using OpenSim.Capabilities.Handlers; + +namespace OpenSim.Region.ClientStack.Linden +{ + + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class GetTextureModule : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Scene m_scene; + private IAssetService m_assetService; + + private bool m_Enabled = false; + + // TODO: Change this to a config option + const string REDIRECT_URL = null; + + private string m_URL; + + #region ISharedRegionModule Members + + public void Initialise(IConfigSource source) + { + IConfig config = source.Configs["ClientStack.LindenCaps"]; + if (config == null) + return; + + m_URL = config.GetString("Cap_GetTexture", string.Empty); + // Cap doesn't exist + if (m_URL != string.Empty) + m_Enabled = true; + } + + public void AddRegion(Scene s) + { + if (!m_Enabled) + return; + + m_scene = s; + } + + public void RemoveRegion(Scene s) + { + if (!m_Enabled) + return; + + m_scene.EventManager.OnRegisterCaps -= RegisterCaps; + m_scene = null; + } + + public void RegionLoaded(Scene s) + { + if (!m_Enabled) + return; + + m_assetService = m_scene.RequestModuleInterface(); + m_scene.EventManager.OnRegisterCaps += RegisterCaps; + } + + public void PostInitialise() + { + } + + public void Close() { } + + public string Name { get { return "GetTextureModule"; } } + + public Type ReplaceableInterface + { + get { return null; } + } + + #endregion + + public void RegisterCaps(UUID agentID, Caps caps) + { + UUID capID = UUID.Random(); + + //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); + if (m_URL == "localhost") + { + m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); + caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); + } + else + { + m_log.InfoFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); + caps.RegisterHandler("GetTexture", m_URL); + } + } + + } +} diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs similarity index 97% rename from OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs rename to OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs index 3d4c7b7527..b7e79cc698 100644 --- a/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs @@ -45,7 +45,7 @@ using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; using OpenSim.Framework.Capabilities; -namespace OpenSim.Region.CoreModules.Avatar.Assets +namespace OpenSim.Region.ClientStack.Linden { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule @@ -171,8 +171,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Assets UUID parentFolder = llsdRequest.folder_id; string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/"; - Caps.AssetUploader uploader = - new Caps.AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, + AssetUploader uploader = + new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile); MainServer.Instance.AddStreamHandler( new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); diff --git a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs similarity index 99% rename from OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs rename to OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs index a0d72ede22..15139a3500 100644 --- a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs @@ -39,7 +39,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps=OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps +namespace OpenSim.Region.ClientStack.Linden { public class ObjectAdd : IRegionModule { diff --git a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs similarity index 99% rename from OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs rename to OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs index 3114d7ff59..3809f84380 100644 --- a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -49,7 +49,7 @@ using OSDMap = OpenMetaverse.StructuredData.OSDMap; using OpenSim.Framework.Capabilities; using ExtraParamType = OpenMetaverse.ExtraParamType; -namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps +namespace OpenSim.Region.ClientStack.Linden { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class UploadObjectAssetModule : INonSharedRegionModule diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs new file mode 100644 index 0000000000..94629a2ee9 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -0,0 +1,134 @@ +/* + * 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.Reflection; +using log4net; +using Nini.Config; +using Mono.Addins; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; +using OpenSim.Capabilities.Handlers; + +namespace OpenSim.Region.ClientStack.Linden +{ + + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class WebFetchInvDescModule : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Scene m_scene; + + private IInventoryService m_InventoryService; + private ILibraryService m_LibraryService; + private bool m_Enabled = false; + private string m_URL; + + #region ISharedRegionModule Members + + public void Initialise(IConfigSource source) + { + IConfig config = source.Configs["ClientStack.LindenCaps"]; + if (config == null) + return; + + m_URL = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty); + // Cap doesn't exist + if (m_URL != string.Empty) + m_Enabled = true; + } + + public void AddRegion(Scene s) + { + if (!m_Enabled) + return; + + m_scene = s; + } + + public void RemoveRegion(Scene s) + { + if (!m_Enabled) + return; + + m_scene.EventManager.OnRegisterCaps -= RegisterCaps; + m_scene = null; + } + + public void RegionLoaded(Scene s) + { + if (!m_Enabled) + return; + + m_InventoryService = m_scene.InventoryService; ; + m_LibraryService = m_scene.LibraryService; + m_scene.EventManager.OnRegisterCaps += RegisterCaps; + } + + public void PostInitialise() + { + } + + public void Close() { } + + public string Name { get { return "WebFetchInvDescModule"; } } + + public Type ReplaceableInterface + { + get { return null; } + } + + #endregion + + public void RegisterCaps(UUID agentID, Caps caps) + { + UUID capID = UUID.Random(); + + //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); + if (m_URL == "localhost") + { + m_log.InfoFormat("[WEBFETCHINVENTORYDESCENDANTS]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); + WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); + IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), webFetchHandler.FetchInventoryDescendentsRequest); + caps.RegisterHandler("WebFetchInventoryDescendents", reqHandler); + } + else + { + m_log.InfoFormat("[WEBFETCHINVENTORYDESCENDANTS]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); + caps.RegisterHandler("WebFetchInventoryDescendents", m_URL); + } + } + + } +} diff --git a/OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs rename to OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/IncomingPacketHistoryCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketHistoryCollection.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/IncomingPacketHistoryCollection.cs rename to OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketHistoryCollection.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs rename to OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs rename to OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs rename to OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs rename to OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs rename to OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs rename to OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/OutgoingPacket.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs rename to OpenSim/Region/ClientStack/Linden/UDP/OutgoingPacket.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/Tests/BasicCircuitTests.cs rename to OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/Tests/MockScene.cs rename to OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs rename to OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLPacketServer.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs rename to OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLPacketServer.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLUDPServer.cs rename to OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs rename to OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs rename to OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs similarity index 100% rename from OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs rename to OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs diff --git a/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs similarity index 81% rename from OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs rename to OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index 1d8e70ed54..111d80859c 100644 --- a/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Reflection; using log4net; using Nini.Config; +using Mono.Addins; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Console; @@ -38,8 +39,9 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps=OpenSim.Framework.Capabilities.Caps; -namespace OpenSim.Region.CoreModules.Agent.Capabilities +namespace OpenSim.Region.CoreModules.Framework { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -49,7 +51,7 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities /// /// Each agent has its own capabilities handler. /// - protected Dictionary m_capsHandlers = new Dictionary(); + protected Dictionary m_capsObjects = new Dictionary(); protected Dictionary capsPaths = new Dictionary(); protected Dictionary> childrenSeeds @@ -93,19 +95,19 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities get { return null; } } - public void AddCapsHandler(UUID agentId) + public void CreateCaps(UUID agentId) { if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId)) return; String capsObjectPath = GetCapsPath(agentId); - if (m_capsHandlers.ContainsKey(agentId)) + if (m_capsObjects.ContainsKey(agentId)) { - Caps oldCaps = m_capsHandlers[agentId]; + Caps oldCaps = m_capsObjects[agentId]; m_log.DebugFormat( - "[CAPS]: Reregistering caps for agent {0}. Old caps path {1}, new caps path {2}. ", + "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", agentId, oldCaps.CapsObjectPath, capsObjectPath); // This should not happen. The caller code is confused. We need to fix that. // CAPs can never be reregistered, or the client will be confused. @@ -113,39 +115,29 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities //return; } - Caps caps - = new Caps(m_scene, - m_scene.AssetService, MainServer.Instance, m_scene.RegionInfo.ExternalHostName, + Caps caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, (MainServer.Instance == null) ? 0: MainServer.Instance.Port, - capsObjectPath, agentId, m_scene.DumpAssetsToFile, m_scene.RegionInfo.RegionName); + capsObjectPath, agentId, m_scene.RegionInfo.RegionName); - caps.RegisterHandlers(); + m_capsObjects[agentId] = caps; m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); - - caps.AddNewInventoryItem = m_scene.AddUploadedInventoryItem; - caps.ItemUpdatedCall = m_scene.CapsUpdateInventoryItemAsset; - caps.TaskScriptUpdatedCall = m_scene.CapsUpdateTaskInventoryScriptAsset; - caps.CAPSFetchInventoryDescendents = m_scene.HandleFetchInventoryDescendentsCAPS; - caps.GetClient = m_scene.SceneContents.GetControllingClient; - - m_capsHandlers[agentId] = caps; } - public void RemoveCapsHandler(UUID agentId) + public void RemoveCaps(UUID agentId) { if (childrenSeeds.ContainsKey(agentId)) { childrenSeeds.Remove(agentId); } - lock (m_capsHandlers) + lock (m_capsObjects) { - if (m_capsHandlers.ContainsKey(agentId)) + if (m_capsObjects.ContainsKey(agentId)) { - m_capsHandlers[agentId].DeregisterHandlers(); - m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsHandlers[agentId]); - m_capsHandlers.Remove(agentId); + m_capsObjects[agentId].DeregisterHandlers(); + m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]); + m_capsObjects.Remove(agentId); } else { @@ -156,20 +148,20 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities } } - public Caps GetCapsHandlerForUser(UUID agentId) + public Caps GetCapsForUser(UUID agentId) { - lock (m_capsHandlers) + lock (m_capsObjects) { - if (m_capsHandlers.ContainsKey(agentId)) + if (m_capsObjects.ContainsKey(agentId)) { - return m_capsHandlers[agentId]; + return m_capsObjects[agentId]; } } return null; } - public void NewUserConnection(AgentCircuitData agent) + public void SetAgentCapsSeeds(AgentCircuitData agent) { capsPaths[agent.AgentID] = agent.CapsPath; childrenSeeds[agent.AgentID] @@ -239,7 +231,7 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities System.Text.StringBuilder caps = new System.Text.StringBuilder(); caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); - foreach (KeyValuePair kvp in m_capsHandlers) + foreach (KeyValuePair kvp in m_capsObjects) { caps.AppendFormat("** User {0}:\n", kvp.Key); for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.CapsDetails.GetEnumerator(); kvp2.MoveNext(); ) @@ -247,6 +239,8 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities Uri uri = new Uri(kvp2.Value.ToString()); caps.AppendFormat(" {0} = {1}\n", kvp2.Key, uri.PathAndQuery); } + foreach (KeyValuePair kvp3 in kvp.Value.ExternalCapsHandlers) + caps.AppendFormat(" {0} = {1}\n", kvp3.Key, kvp3.Value); } MainConsole.Instance.Output(caps.ToString()); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 10547857f7..e38006752a 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -479,7 +479,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Fail. Reset it back sp.IsChildAgent = false; - + ReInstantiateScripts(sp); ResetFromTransit(sp.UUID); EnableChildAgents(sp); @@ -930,6 +930,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!WaitForCallback(agent.UUID)) { m_log.Debug("[ENTITY TRANSFER MODULE]: Callback never came in crossing agent"); + ReInstantiateScripts(agent); ResetFromTransit(agent.UUID); // Yikes! We should just have a ref to scene here. @@ -1756,7 +1757,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return false; } + protected void ReInstantiateScripts(ScenePresence sp) + { + int i = 0; + sp.Attachments.ForEach(delegate(SceneObjectGroup sog) + { + sog.SetState(sp.InTransitScriptStates[i++], sp.Scene); + sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0); + sog.ResumeScripts(); + }); + sp.InTransitScriptStates.Clear(); + } #endregion } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 6b3df9ddd6..1370b1fe8e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -371,7 +371,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } // This is a hook to do some per-asset post-processing for subclasses that need that - ExportAsset(remoteClient.AgentId, assetID); + if (remoteClient != null) + ExportAsset(remoteClient.AgentId, assetID); return assetID; } diff --git a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs index 2dd7767d76..07999d16c1 100644 --- a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs +++ b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs @@ -575,7 +575,7 @@ namespace OpenSim.Region.CoreModules.InterGrid string derezAvatarPath = "/agent/" + AvatarRezCapUUID + "/rez_avatar/derez"; // Get a reference to the user's cap so we can pull out the Caps Object Path Caps userCap - = homeScene.CapsModule.GetCapsHandlerForUser(agentData.AgentID); + = homeScene.CapsModule.GetCapsForUser(agentData.AgentID); string rezHttpProtocol = "http://"; string regionCapsHttpProtocol = "http://"; @@ -700,7 +700,7 @@ namespace OpenSim.Region.CoreModules.InterGrid { // Get a referenceokay - to their Cap object so we can pull out the capobjectroot Caps userCap - = homeScene.CapsModule.GetCapsHandlerForUser(userData.AgentID); + = homeScene.CapsModule.GetCapsForUser(userData.AgentID); //Update the circuit data in the region so this user is authorized homeScene.UpdateCircuitData(userData); diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index a9d247a2b8..8a6735f378 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml @@ -17,7 +17,6 @@ - diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 7858f2afd3..f8cea71b43 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -179,7 +179,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return true; // else do the remote thing - if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) + if (!m_localBackend.IsLocalRegion(destination.RegionID)) { return m_remoteConnector.CreateAgent(destination, aCircuit, teleportFlags, out reason); } @@ -241,7 +241,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return true; // else do the remote thing - if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) + if (!m_localBackend.IsLocalRegion(destination.RegionID)) return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason); return false; diff --git a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs index 964e4b9d28..a505999608 100644 --- a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs +++ b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs @@ -36,7 +36,7 @@ using OpenSim.Framework.Capabilities; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Scenes; -using Caps=OpenSim.Framework.Capabilities.Caps; +using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.DataSnapshot { diff --git a/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs b/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs index 73bffa02f1..522c82d40f 100644 --- a/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs @@ -34,31 +34,27 @@ namespace OpenSim.Region.Framework.Interfaces { public interface ICapabilitiesModule { - void NewUserConnection(AgentCircuitData agent); - /// /// Add a caps handler for the given agent. If the CAPS handler already exists for this agent, /// then it is replaced by a new CAPS handler. - /// - /// FIXME: On login this is called twice, once for the login and once when the connection is made. - /// This is somewhat innefficient and should be fixed. The initial login creation is necessary - /// since the client asks for capabilities immediately after being informed of the seed. /// /// /// - void AddCapsHandler(UUID agentId); + void CreateCaps(UUID agentId); /// /// Remove the caps handler for a given agent. /// /// - void RemoveCapsHandler(UUID agentId); + void RemoveCaps(UUID agentId); /// /// Will return null if the agent doesn't have a caps handler registered /// /// - Caps GetCapsHandlerForUser(UUID agentId); + Caps GetCapsForUser(UUID agentId); + + void SetAgentCapsSeeds(AgentCircuitData agent); Dictionary GetChildrenSeeds(UUID agentID); diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs index 81e4952afe..bfa5d1717d 100644 --- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs +++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs @@ -57,5 +57,7 @@ namespace OpenSim.Region.Framework.Interfaces bool isModerator, bool textMute); void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID); + OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono); + OSD BuildEvent(string eventName, OSD eventBody); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 696c6ee453..b537381a0b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1229,7 +1229,6 @@ namespace OpenSim.Region.Framework.Scenes // Increment the frame counter ++Frame; - try { // Check if any objects have reached their targets @@ -2336,9 +2335,29 @@ namespace OpenSim.Region.Framework.Scenes return false; } - newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); - - newObject.ResumeScripts(); + // For attachments, we need to wait until the agent is root + // before we restart the scripts, or else some functions won't work. + if (!newObject.IsAttachment) + { + newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); + newObject.ResumeScripts(); + } + else + { + ScenePresence sp; + if (TryGetScenePresence(newObject.OwnerID, out sp)) + { + // If the scene presence is here and already a root + // agent, we came from a ;egacy region. Start the scripts + // here as they used to start. + // TODO: Remove in 0.7.3 + if (!sp.IsChildAgent) + { + newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); + newObject.ResumeScripts(); + } + } + } // Do this as late as possible so that listeners have full access to the incoming object EventManager.TriggerOnIncomingSceneObject(newObject); @@ -2455,17 +2474,8 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence sp = GetScenePresence(sog.OwnerID); if (sp != null) - { - AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(sp.UUID); + return sp.GetStateSource(); - if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default)) - { - // This will get your attention - //m_log.Error("[XXX] Triggering CHANGED_TELEPORT"); - - return 5; // StateSource.Teleporting - } - } return 2; // StateSource.PrimCrossing } @@ -3023,7 +3033,7 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGraph.removeUserCount(!childagentYN); if (CapsModule != null) - CapsModule.RemoveCapsHandler(agentID); + CapsModule.RemoveCaps(agentID); // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever // this method is doing is HORRIBLE!!! @@ -3280,8 +3290,8 @@ namespace OpenSim.Region.Framework.Scenes if (CapsModule != null) { - CapsModule.NewUserConnection(agent); - CapsModule.AddCapsHandler(agent.AgentID); + CapsModule.SetAgentCapsSeeds(agent); + CapsModule.CreateCaps(agent.AgentID); } } else @@ -3299,7 +3309,7 @@ namespace OpenSim.Region.Framework.Scenes sp.AdjustKnownSeeds(); if (CapsModule != null) - CapsModule.NewUserConnection(agent); + CapsModule.SetAgentCapsSeeds(agent); } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index fe4a7d1fa7..631c91b29e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -231,6 +231,16 @@ namespace OpenSim.Region.Framework.Scenes // holds the seed cap for the child agent in that region private Dictionary m_knownChildRegions = new Dictionary(); + /// + /// Copy of the script states while the agent is in transit. This state may + /// need to be placed back in case of transfer fail. + /// + public List InTransitScriptStates + { + get { return m_InTransitScriptStates; } + } + private List m_InTransitScriptStates = new List(); + /// /// Implemented Control Flags /// @@ -840,6 +850,9 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); + bool wasChild = m_isChildAgent; + m_isChildAgent = false; + IGroupsModule gm = m_scene.RequestModuleInterface(); if (gm != null) m_grouptitle = gm.GetGroupTitle(m_uuid); @@ -929,14 +942,21 @@ namespace OpenSim.Region.Framework.Scenes // Animator.SendAnimPack(); m_scene.SwapRootAgentCount(false); - - //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); - //if (userInfo != null) - // userInfo.FetchInventory(); - //else - // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); - - m_isChildAgent = false; + + // The initial login scene presence is already root when it gets here + // and it has already rezzed the attachments and started their scripts. + // We do the following only for non-login agents, because their scripts + // haven't started yet. + if (wasChild && Attachments != null && Attachments.Count > 0) + { + m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); + // Resume scripts + Attachments.ForEach(delegate(SceneObjectGroup sog) + { + sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); + sog.ResumeScripts(); + }); + } // send the animations of the other presences to me m_scene.ForEachScenePresence(delegate(ScenePresence presence) @@ -948,6 +968,20 @@ namespace OpenSim.Region.Framework.Scenes m_scene.EventManager.TriggerOnMakeRootAgent(this); } + public int GetStateSource() + { + AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID); + + if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default)) + { + // This will get your attention + //m_log.Error("[XXX] Triggering CHANGED_TELEPORT"); + + return 5; // StateSource.Teleporting + } + return 2; // StateSource.PrimCrossing + } + /// /// This turns a root agent into a child agent /// when an agent departs this region for a neighbor, this gets called. @@ -1139,7 +1173,6 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = pos; } - m_isChildAgent = false; bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); MakeRootAgent(AbsolutePosition, m_flying); @@ -2372,6 +2405,7 @@ namespace OpenSim.Region.Framework.Scenes // vars to support reduced update frequency when velocity is unchanged private Vector3 lastVelocitySentToAllClients = Vector3.Zero; + private Vector3 lastPositionSentToAllClients = Vector3.Zero; private int lastTerseUpdateToAllClientsTick = Util.EnvironmentTickCount(); /// @@ -2381,14 +2415,29 @@ namespace OpenSim.Region.Framework.Scenes { int currentTick = Util.EnvironmentTickCount(); - // decrease update frequency when avatar is moving but velocity is not changing - if (m_velocity.Length() < 0.01f - || Vector3.Distance(lastVelocitySentToAllClients, m_velocity) > 0.01f - || currentTick - lastTerseUpdateToAllClientsTick > 1500) + // Decrease update frequency when avatar is moving but velocity is + // not changing. + // If there is a mismatch between distance travelled and expected + // distance based on last velocity sent and velocity hasnt changed, + // then send a new terse update + + float timeSinceLastUpdate = (currentTick - lastTerseUpdateToAllClientsTick) * 0.001f; + + Vector3 expectedPosition = lastPositionSentToAllClients + lastVelocitySentToAllClients * timeSinceLastUpdate; + + float distanceError = Vector3.Distance(OffsetPosition, expectedPosition); + + float speed = Velocity.Length(); + float velocidyDiff = Vector3.Distance(lastVelocitySentToAllClients, Velocity); + + if (speed < 0.01f // allow rotation updates if avatar position is unchanged + || Math.Abs(distanceError) > 0.25f // arbitrary distance error threshold + || velocidyDiff > 0.01f) // did velocity change from last update? { m_perfMonMS = currentTick; - lastVelocitySentToAllClients = m_velocity; + lastVelocitySentToAllClients = Velocity; lastTerseUpdateToAllClientsTick = currentTick; + lastPositionSentToAllClients = OffsetPosition; m_scene.ForEachClient(SendTerseUpdateToClient); @@ -3103,6 +3152,7 @@ namespace OpenSim.Region.Framework.Scenes cAgent.AttachmentObjects = new List(); cAgent.AttachmentObjectStates = new List(); IScriptModule se = m_scene.RequestModuleInterface(); + m_InTransitScriptStates.Clear(); foreach (SceneObjectGroup sog in m_attachments) { // We need to make a copy and pass that copy @@ -3112,7 +3162,11 @@ namespace OpenSim.Region.Framework.Scenes ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; ((SceneObjectGroup)clone).RootPart.IsAttachment = false; cAgent.AttachmentObjects.Add(clone); - cAgent.AttachmentObjectStates.Add(sog.GetStateSnapshot()); + string state = sog.GetStateSnapshot(); + cAgent.AttachmentObjectStates.Add(state); + m_InTransitScriptStates.Add(state); + // Let's remove the scripts of the original object here + sog.RemoveScriptInstances(true); } } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 8c01d75b8f..2bf8489df8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -34,12 +34,9 @@ using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using Caps = OpenSim.Framework.Capabilities.Caps; - namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] @@ -472,7 +469,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); + queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index a8dec63def..1c791b9d36 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -39,13 +39,11 @@ using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Communications; -using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; -using Caps = OpenSim.Framework.Capabilities.Caps; using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; @@ -1154,7 +1152,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); + queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); } } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 86296740ef..97ab411dd2 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -41,7 +41,6 @@ using log4net; using Nini.Config; using Amib.Threading; using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.ScriptEngine.Shared; @@ -1283,7 +1282,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine } else { - eq.Enqueue(EventQueueHelper.ScriptRunningReplyEvent(objectID, itemID, GetScriptState(itemID), true), + eq.Enqueue(eq.ScriptRunningEvent(objectID, itemID, GetScriptState(itemID), true), controllingClient.AgentId); } } diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index a03cc4cf50..3139b8ade1 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -44,7 +44,6 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Mono.Data.SqliteClient; - using Caps = OpenSim.Framework.Capabilities.Caps; using OSD = OpenMetaverse.StructuredData.OSD; diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs index 8ab323ad41..0430ef60d7 100644 --- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs @@ -314,7 +314,7 @@ namespace OpenSim.Services.Connectors.Hypergrid args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); args["teleport_flags"] = OSD.FromString(flags.ToString()); - OSDMap result = WebUtil.PostToService(uri,args); + OSDMap result = WebUtil.PostToService(uri, args, 20000); if (result["Success"].AsBoolean()) { OSDMap unpacked = (OSDMap)result["_Result"]; diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 7545db8200..cef6473b78 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -102,7 +102,7 @@ namespace OpenSim.Services.Connectors.Simulation args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); args["teleport_flags"] = OSD.FromString(flags.ToString()); - OSDMap result = WebUtil.PostToService(uri,args); + OSDMap result = WebUtil.PostToService(uri, args, 20000); if (result["Success"].AsBoolean()) return true; @@ -126,7 +126,7 @@ namespace OpenSim.Services.Connectors.Simulation /// public bool UpdateAgent(GridRegion destination, AgentData data) { - return UpdateAgent(destination, (IAgentData)data); + return UpdateAgent(destination, (IAgentData)data, 200000); // yes, 200 seconds } /// @@ -181,7 +181,7 @@ namespace OpenSim.Services.Connectors.Simulation } } - UpdateAgent(destination,(IAgentData)pos); + UpdateAgent(destination, (IAgentData)pos, 10000); } // unreachable @@ -191,7 +191,7 @@ namespace OpenSim.Services.Connectors.Simulation /// /// This is the worker function to send AgentData to a neighbor region /// - private bool UpdateAgent(GridRegion destination, IAgentData cAgentData) + private bool UpdateAgent(GridRegion destination, IAgentData cAgentData, int timeout) { // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: UpdateAgent start"); @@ -207,7 +207,7 @@ namespace OpenSim.Services.Connectors.Simulation args["destination_name"] = OSD.FromString(destination.RegionName); args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); - OSDMap result = WebUtil.PutToService(uri,args); + OSDMap result = WebUtil.PutToService(uri, args, timeout); return result["Success"].AsBoolean(); } catch (Exception e) @@ -233,7 +233,7 @@ namespace OpenSim.Services.Connectors.Simulation try { - OSDMap result = WebUtil.GetFromService(uri); + OSDMap result = WebUtil.GetFromService(uri, 10000); if (result["Success"].AsBoolean()) { // OSDMap args = Util.GetOSDMap(result["_RawResult"].AsString()); @@ -275,27 +275,30 @@ namespace OpenSim.Services.Connectors.Simulation try { OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 10000); - OSDMap data = (OSDMap)result["_Result"]; - bool success = result["success"].AsBoolean(); - reason = data["reason"].AsString(); - if (data["version"] != null && data["version"].AsString() != string.Empty) - version = data["version"].AsString(); + if (result.ContainsKey("_Result")) + { + OSDMap data = (OSDMap)result["_Result"]; - m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1} version {2} ({3})", uri, success, version, data["version"].AsString()); + reason = data["reason"].AsString(); + if (data["version"] != null && data["version"].AsString() != string.Empty) + version = data["version"].AsString(); + + m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1} version {2} ({3})", uri, success, version, data["version"].AsString()); + } if (!success) { - if (data.ContainsKey("Message")) + if (result.ContainsKey("Message")) { - string message = data["Message"].AsString(); + string message = result["Message"].AsString(); if (message == "Service request failed: [MethodNotAllowed] MethodNotAllowed") // Old style region { m_log.Info("[REMOTE SIMULATION CONNECTOR]: The above web util error was caused by a TP to a sim that doesn't support QUERYACCESS and can be ignored"); return true; } - reason = data["Message"]; + reason = result["Message"]; } else { @@ -389,7 +392,7 @@ namespace OpenSim.Services.Connectors.Simulation args["destination_name"] = OSD.FromString(destination.RegionName); args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); - WebUtil.PostToService(uri, args); + WebUtil.PostToService(uri, args, 40000); } catch (Exception e) { diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index ebd6f7c1cf..ddc8855145 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -32,7 +32,6 @@ using System.Net; using System.Reflection; using OpenSim.Framework; -using OpenSim.Framework.Capabilities; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 9bcc3dd225..2ca2d1566c 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -38,7 +38,6 @@ using Nini.Config; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Framework.Capabilities; using OpenSim.Framework.Console; using OpenSim.Server.Base; using OpenSim.Services.Interfaces; diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index 99517d2b19..d1224099e2 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs @@ -39,7 +39,6 @@ using OpenSim.Region.Physics.Manager; using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.CoreModules.Agent.Capabilities; using OpenSim.Region.CoreModules.Avatar.Gods; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication; diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 5389b4455a..13dc9a67ab 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -292,6 +292,20 @@ ;; building's lights to possibly not be rendered. ; DisableFacelights = "false" +[ClientStack.LindenCaps] + ;; For the long list of capabilities, see OpenSimDefaults.ini + ;; Here are the few ones you may want to change. Possible values + ;; are: + ;; "" -- empty, capability disabled + ;; "localhost" -- capability enabled and served by the simulator + ;; "" -- capability enabled and served by some other server + ;; + ; These are enabled by default to localhost. Change if you see fit. + Cap_GetTexture = "localhost" + Cap_GetMesh = "localhost" + ; This is disabled by default. Change if you see fit. Note that + ; serving this cap from the simulators may lead to poor performace. + Cap_WebFetchInventoryDescendents = "" [Chat] ;# {whisper_distance} {} {Distance at which a whisper is heard, in meters?} {} 10 diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 35e8079cf5..6d2d54daca 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -408,6 +408,74 @@ ; ;DisableFacelights = "false" +[ClientStack.LindenCaps] + ;; Long list of capabilities taken from + ;; http://wiki.secondlife.com/wiki/Current_Sim_Capabilities + ;; Not all are supported by OpenSim. The ones supported are + ;; set to localhost. These defaults can be overwritten + ;; in OpenSim.ini + ;; + Cap_AttachmentResources = "" + Cap_AvatarPickerSearch = "" + Cap_ChatSessionRequest = "" + Cap_CopyInventoryFromNotecard = "" + Cap_DispatchRegionInfo = "" + Cap_EstateChangeInfo = "" + Cap_EventQueueGet = "localhost" + Cap_FetchInventory = "" + Cap_ObjectMedia = "localhost" + Cap_ObjectMediaNavigate = "localhost" + Cap_FetchLib = "" + Cap_FetchLibDescendents = "" + Cap_GetDisplayNames = "" + Cap_GetTexture = "localhost" + Cap_GetMesh = "localhost" + Cap_GetObjectCost = "" + Cap_GetObjectPhysicsData = "" + Cap_GroupProposalBallot = "" + Cap_HomeLocation = "" + Cap_LandResources = "" + Cap_MapLayer = "localhost" + Cap_MapLayerGod = "localhost" + Cap_NewFileAgentInventory = "localhost" + Cap_NewFileAgentInventoryVariablePrice = "localhost" + Cap_ObjectAdd = "localhost" + Cap_ParcelPropertiesUpdate = "localhost" + Cap_ParcelMediaURLFilterList = "" + Cap_ParcelNavigateMedia = "" + Cap_ParcelVoiceInfoRequest = "" + Cap_ProductInfoRequest = "" + Cap_ProvisionVoiceAccountRequest = "" + Cap_RemoteParcelRequest = "localhost" + Cap_RequestTextureDownload = "" + Cap_SearchStatRequest = "" + Cap_SearchStatTracking = "" + Cap_SendPostcard = "" + Cap_SendUserReport = "" + Cap_SendUserReportWithScreenshot = "" + Cap_ServerReleaseNotes = "" + Cap_SimConsole = "" + Cap_SimulatorFeatures = "" + Cap_SetDisplayName = "" + Cap_StartGroupProposal = "" + Cap_TextureStats = "" + Cap_UntrustedSimulatorMessage = "" + Cap_UpdateAgentInformation = "" + Cap_UpdateAgentLanguage = "" + Cap_UpdateGestureAgentInventory = "" + Cap_UpdateNotecardAgentInventory = "localhost" + Cap_UpdateScriptAgent = "localhost" + Cap_UpdateGestureTaskInventory = "" + Cap_UpdateNotecardTaskInventory = "localhost" + Cap_UpdateScriptTask = "localhost" + Cap_UploadBakedTexture = "localhost" + Cap_UploadObjectAsset = "localhost" + Cap_ViewerStartAuction = "" + Cap_ViewerStats = "" + ; This last one is supported by OpenSim, but may + ; lead to poor sim performance if served by the simulators, + ; so it is disabled by default. + Cap_WebFetchInventoryDescendents = "" [Chat] ; Controls whether the chat module is enabled. Default is true. diff --git a/prebuild.xml b/prebuild.xml index 1102c11c09..a07ad14154 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -660,19 +660,19 @@ - + - ../../../bin/ + ../../bin/ - ../../../bin/ + ../../bin/ - ../../../bin/ + ../../bin/ @@ -681,20 +681,20 @@ - - - - - + + + + - + + @@ -714,7 +714,6 @@ - @@ -760,7 +759,7 @@ - + @@ -1185,7 +1184,6 @@ - @@ -1217,7 +1215,6 @@ - @@ -1271,7 +1268,6 @@ - @@ -1310,6 +1306,47 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1402,8 +1439,8 @@ + - @@ -1513,43 +1550,89 @@ - + - ../../../../bin/ + ../../../../../bin/ - ../../../../bin/ + ../../../../../bin/ - ../../../../bin/ + ../../../../../bin/ + - - - + + + + + - - - - - - + + + + + - + + + + + + + + + + ../../../../../bin/ + + + + + ../../../../../bin/ + + + + ../../../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1574,16 +1657,16 @@ + - - + @@ -1914,8 +1997,8 @@ + - @@ -2346,13 +2429,13 @@ + -