From c062138dad42ef7e52bbcb27c346ddecab94c5af Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 12:23:40 -0700 Subject: Moved several cap-based-service-providing modules from where they were into a newly created CoreModules/Caps. Not all. --- .../Agent/Capabilities/CapabilitiesModule.cs | 255 ------------- .../CoreModules/Avatar/Assets/GetMeshModule.cs | 211 ----------- .../CoreModules/Avatar/Assets/GetTextureModule.cs | 402 --------------------- .../NewFileAgentInventoryVariablePriceModule.cs | 275 -------------- .../CoreModules/Avatar/ObjectCaps/ObjectAdd.cs | 370 ------------------- .../Avatar/ObjectCaps/UploadObjectAssetModule.cs | 374 ------------------- .../Region/CoreModules/Caps/CapabilitiesModule.cs | 255 +++++++++++++ OpenSim/Region/CoreModules/Caps/GetMeshModule.cs | 211 +++++++++++ .../Region/CoreModules/Caps/GetTextureModule.cs | 402 +++++++++++++++++++++ .../NewFileAgentInventoryVariablePriceModule.cs | 275 ++++++++++++++ .../CoreModules/Caps/ObjectCaps/ObjectAdd.cs | 370 +++++++++++++++++++ .../Caps/ObjectCaps/UploadObjectAssetModule.cs | 374 +++++++++++++++++++ 12 files changed, 1887 insertions(+), 1887 deletions(-) delete mode 100644 OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs delete mode 100644 OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs delete mode 100644 OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs delete mode 100644 OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs delete mode 100644 OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs delete mode 100644 OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs create mode 100644 OpenSim/Region/CoreModules/Caps/CapabilitiesModule.cs create mode 100644 OpenSim/Region/CoreModules/Caps/GetMeshModule.cs create mode 100644 OpenSim/Region/CoreModules/Caps/GetTextureModule.cs create mode 100644 OpenSim/Region/CoreModules/Caps/NewFileAgentInventoryVariablePriceModule.cs create mode 100644 OpenSim/Region/CoreModules/Caps/ObjectCaps/ObjectAdd.cs create mode 100644 OpenSim/Region/CoreModules/Caps/ObjectCaps/UploadObjectAssetModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs deleted file mode 100644 index 1d8e70e..0000000 --- a/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs +++ /dev/null @@ -1,255 +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 copyrightD - * 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 OpenSim.Framework; -using OpenSim.Framework.Console; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using Caps=OpenSim.Framework.Capabilities.Caps; - -namespace OpenSim.Region.CoreModules.Agent.Capabilities -{ - public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - protected Scene m_scene; - - /// - /// Each agent has its own capabilities handler. - /// - protected Dictionary m_capsHandlers = new Dictionary(); - - protected Dictionary capsPaths = new Dictionary(); - protected Dictionary> childrenSeeds - = new Dictionary>(); - - public void Initialise(IConfigSource source) - { - } - - public void AddRegion(Scene scene) - { - m_scene = scene; - m_scene.RegisterModuleInterface(this); - MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps", - "show capabilities", - "Shows all registered capabilities", CapabilitiesCommand); - } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - m_scene.UnregisterModuleInterface(this); - } - - public void PostInitialise() - { - } - - public void Close() {} - - public string Name - { - get { return "Capabilities Module"; } - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddCapsHandler(UUID agentId) - { - if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId)) - return; - - String capsObjectPath = GetCapsPath(agentId); - - if (m_capsHandlers.ContainsKey(agentId)) - { - Caps oldCaps = m_capsHandlers[agentId]; - - m_log.DebugFormat( - "[CAPS]: Reregistering 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. - // Hence this return here. - //return; - } - - Caps caps - = new Caps(m_scene, - m_scene.AssetService, MainServer.Instance, m_scene.RegionInfo.ExternalHostName, - (MainServer.Instance == null) ? 0: MainServer.Instance.Port, - capsObjectPath, agentId, m_scene.DumpAssetsToFile, m_scene.RegionInfo.RegionName); - - caps.RegisterHandlers(); - - 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) - { - if (childrenSeeds.ContainsKey(agentId)) - { - childrenSeeds.Remove(agentId); - } - - lock (m_capsHandlers) - { - if (m_capsHandlers.ContainsKey(agentId)) - { - m_capsHandlers[agentId].DeregisterHandlers(); - m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsHandlers[agentId]); - m_capsHandlers.Remove(agentId); - } - else - { - m_log.WarnFormat( - "[CAPS]: Received request to remove CAPS handler for root agent {0} in {1}, but no such CAPS handler found!", - agentId, m_scene.RegionInfo.RegionName); - } - } - } - - public Caps GetCapsHandlerForUser(UUID agentId) - { - lock (m_capsHandlers) - { - if (m_capsHandlers.ContainsKey(agentId)) - { - return m_capsHandlers[agentId]; - } - } - - return null; - } - - public void NewUserConnection(AgentCircuitData agent) - { - capsPaths[agent.AgentID] = agent.CapsPath; - childrenSeeds[agent.AgentID] - = ((agent.ChildrenCapSeeds == null) ? new Dictionary() : agent.ChildrenCapSeeds); - } - - public string GetCapsPath(UUID agentId) - { - if (capsPaths.ContainsKey(agentId)) - { - return capsPaths[agentId]; - } - - return null; - } - - public Dictionary GetChildrenSeeds(UUID agentID) - { - Dictionary seeds = null; - if (childrenSeeds.TryGetValue(agentID, out seeds)) - return seeds; - return new Dictionary(); - } - - public void DropChildSeed(UUID agentID, ulong handle) - { - Dictionary seeds; - if (childrenSeeds.TryGetValue(agentID, out seeds)) - { - seeds.Remove(handle); - } - } - - public string GetChildSeed(UUID agentID, ulong handle) - { - Dictionary seeds; - string returnval; - if (childrenSeeds.TryGetValue(agentID, out seeds)) - { - if (seeds.TryGetValue(handle, out returnval)) - return returnval; - } - return null; - } - - public void SetChildrenSeed(UUID agentID, Dictionary seeds) - { - //m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count); - childrenSeeds[agentID] = seeds; - } - - public void DumpChildrenSeeds(UUID agentID) - { - m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================"); - foreach (KeyValuePair kvp in childrenSeeds[agentID]) - { - uint x, y; - Utils.LongToUInts(kvp.Key, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - m_log.Info(" >> "+x+", "+y+": "+kvp.Value); - } - } - - private void CapabilitiesCommand(string module, string[] cmdparams) - { - System.Text.StringBuilder caps = new System.Text.StringBuilder(); - caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); - - foreach (KeyValuePair kvp in m_capsHandlers) - { - caps.AppendFormat("** User {0}:\n", kvp.Key); - for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.CapsDetails.GetEnumerator(); kvp2.MoveNext(); ) - { - Uri uri = new Uri(kvp2.Value.ToString()); - caps.AppendFormat(" {0} = {1}\n", kvp2.Key, uri.PathAndQuery); - } - } - - MainConsole.Instance.Output(caps.ToString()); - } - } -} diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs deleted file mode 100644 index fc1ddef..0000000 --- a/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs +++ /dev/null @@ -1,211 +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.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.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 -{ - [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; - - #region IRegionModuleBase Members - - - public Type ReplaceableInterface - { - get { return null; } - } - - 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) - { - - Hashtable responsedata = new Hashtable(); - responsedata["int_response_code"] = 400; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "Request wasn't what was expected"; - - string meshStr = string.Empty; - - if (request.ContainsKey("mesh_id")) - meshStr = request["mesh_id"].ToString(); - - - UUID meshID = UUID.Zero; - if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID)) - { - if (m_assetService == null) - { - responsedata["int_response_code"] = 404; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; - return responsedata; - } - - AssetBase mesh; - // Only try to fetch locally cached textures. Misses are redirected - mesh = m_assetService.GetCached(meshID.ToString()); - if (mesh != null) - { - if (mesh.Type == (SByte)AssetType.Mesh) - { - responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); - responsedata["content_type"] = "application/vnd.ll.mesh"; - responsedata["int_response_code"] = 200; - } - // Optionally add additional mesh types here - else - { - responsedata["int_response_code"] = 404; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; - return responsedata; - } - } - else - { - mesh = m_assetService.Get(meshID.ToString()); - if (mesh != null) - { - if (mesh.Type == (SByte)AssetType.Mesh) - { - responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); - responsedata["content_type"] = "application/vnd.ll.mesh"; - responsedata["int_response_code"] = 200; - } - // Optionally add additional mesh types here - else - { - responsedata["int_response_code"] = 404; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; - return responsedata; - } - } - - else - { - responsedata["int_response_code"] = 404; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; - return responsedata; - } - } - - } - - return responsedata; - } - } -} diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs deleted file mode 100644 index df4d561..0000000 --- a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs +++ /dev/null @@ -1,402 +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.Specialized; -using System.Drawing; -using System.Drawing.Imaging; -using System.Reflection; -using System.IO; -using System.Web; -using log4net; -using Nini.Config; -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; - -namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps -{ - #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 - { - 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"; - - // TODO: Change this to a config option - const string REDIRECT_URL = null; - - - #region IRegionModule Members - - public void Initialise(Scene pScene, IConfigSource pSource) - { - m_scene = pScene; - } - - public void PostInitialise() - { - 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"); - - if (m_assetService == null) - { - m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return null; - } - - UUID textureID; - if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID)) - { - string[] formats; - if (format != null && format != string.Empty) - { - formats = new string[1] { format.ToLower() }; - } - else - { - formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept")); - if (formats.Length == 0) - formats = new string[1] { DefaultFormat }; // default - - } - // OK, we have an array with preferred formats, possibly with only one entry - - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - foreach (string f in formats) - { - if (FetchTexture(httpRequest, httpResponse, textureID, f)) - break; - } - - } - else - { - m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); - } - - httpResponse.Send(); - return null; - } - - /// - /// - /// - /// - /// - /// - /// - /// False for "caller try another codec"; true otherwise - private bool FetchTexture(OSHttpRequest httpRequest, OSHttpResponse httpResponse, UUID textureID, string format) - { -// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); - AssetBase texture; - - string fullID = textureID.ToString(); - if (format != DefaultFormat) - fullID = fullID + "-" + format; - - if (!String.IsNullOrEmpty(REDIRECT_URL)) - { - // Only try to fetch locally cached textures. Misses are redirected - texture = m_assetService.GetCached(fullID); - - if (texture != null) - { - if (texture.Type != (sbyte)AssetType.Texture) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - WriteTextureData(httpRequest, httpResponse, texture, format); - } - else - { - string textureUrl = REDIRECT_URL + textureID.ToString(); - m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); - httpResponse.RedirectLocation = textureUrl; - return true; - } - } - else // no redirect - { - // try the cache - texture = m_assetService.GetCached(fullID); - - if (texture == null) - { - //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); - - // Fetch locally or remotely. Misses return a 404 - texture = m_assetService.Get(textureID.ToString()); - - if (texture != null) - { - if (texture.Type != (sbyte)AssetType.Texture) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - if (format == DefaultFormat) - { - WriteTextureData(httpRequest, httpResponse, texture, format); - return true; - } - else - { - AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); - newTexture.Data = ConvertTextureData(texture, format); - if (newTexture.Data.Length == 0) - return false; // !!! Caller try another codec, please! - - newTexture.Flags = AssetFlags.Collectable; - newTexture.Temporary = true; - m_assetService.Store(newTexture); - WriteTextureData(httpRequest, httpResponse, newTexture, format); - return true; - } - } - } - else // it was on the cache - { - //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); - WriteTextureData(httpRequest, httpResponse, texture, format); - return true; - } - } - - // not found -// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - - private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format) - { - string range = request.Headers.GetOne("Range"); - //m_log.DebugFormat("[GETTEXTURE]: Range {0}", range); - if (!String.IsNullOrEmpty(range)) // JP2's only - { - // Range request - int start, end; - if (TryParseRange(range, out start, out end)) - { - // Before clamping start make sure we can satisfy it in order to avoid - // sending back the last byte instead of an error status - if (start >= texture.Data.Length) - { - response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; - return; - } - - end = Utils.Clamp(end, 0, texture.Data.Length - 1); - start = Utils.Clamp(start, 0, end); - int len = end - start + 1; - - //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); - - if (len < texture.Data.Length) - response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; - - response.ContentLength = len; - response.ContentType = texture.Metadata.ContentType; - response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); - - response.Body.Write(texture.Data, start, len); - } - else - { - m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range); - response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; - } - } - else // JP2's or other formats - { - // Full content request - response.StatusCode = (int)System.Net.HttpStatusCode.OK; - response.ContentLength = texture.Data.Length; - if (format == DefaultFormat) - response.ContentType = texture.Metadata.ContentType; - else - response.ContentType = "image/" + format; - response.Body.Write(texture.Data, 0, texture.Data.Length); - } - } - - private bool TryParseRange(string header, out int start, out int end) - { - if (header.StartsWith("bytes=")) - { - string[] rangeValues = header.Substring(6).Split('-'); - if (rangeValues.Length == 2) - { - if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end)) - return true; - } - } - - start = end = 0; - return false; - } - - - private byte[] ConvertTextureData(AssetBase texture, string format) - { - m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format); - byte[] data = new byte[0]; - - MemoryStream imgstream = new MemoryStream(); - Bitmap mTexture = new Bitmap(1, 1); - ManagedImage managedImage; - Image image = (Image)mTexture; - - try - { - // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data - - imgstream = new MemoryStream(); - - // Decode image to System.Drawing.Image - if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image)) - { - // Save to bitmap - mTexture = new Bitmap(image); - - EncoderParameters myEncoderParameters = new EncoderParameters(); - myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L); - - // Save bitmap to stream - ImageCodecInfo codec = GetEncoderInfo("image/" + format); - if (codec != null) - { - mTexture.Save(imgstream, codec, myEncoderParameters); - // Write the stream to a byte array for output - data = imgstream.ToArray(); - } - else - m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format); - - } - } - catch (Exception e) - { - m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message); - } - finally - { - // Reclaim memory, these are unmanaged resources - // If we encountered an exception, one or more of these will be null - if (mTexture != null) - mTexture.Dispose(); - - if (image != null) - image.Dispose(); - - if (imgstream != null) - { - imgstream.Close(); - imgstream.Dispose(); - } - } - - return data; - } - - // From msdn - private static ImageCodecInfo GetEncoderInfo(String mimeType) - { - ImageCodecInfo[] encoders; - encoders = ImageCodecInfo.GetImageEncoders(); - for (int j = 0; j < encoders.Length; ++j) - { - if (encoders[j].MimeType == mimeType) - return encoders[j]; - } - return null; - } - - - } -} diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs deleted file mode 100644 index 3d4c7b7..0000000 --- a/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs +++ /dev/null @@ -1,275 +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.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.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.Framework.Capabilities; - -namespace OpenSim.Region.CoreModules.Avatar.Assets -{ - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule - { -// private static readonly ILog m_log = -// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private Scene m_scene; -// private IAssetService m_assetService; - private bool m_dumpAssetsToFile = false; - private bool m_enabled = true; - - #region IRegionModuleBase Members - - - public Type ReplaceableInterface - { - get { return null; } - } - - 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 "NewFileAgentInventoryVariablePriceModule"; } } - - - public void RegisterCaps(UUID agentID, Caps caps) - { - if(!m_enabled) - return; - - UUID capID = UUID.Random(); - -// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID); - caps.RegisterHandler("NewFileAgentInventoryVariablePrice", - - new LLSDStreamhandler("POST", - "/CAPS/" + capID.ToString(), - delegate(LLSDAssetUploadRequest req) - { - return NewAgentInventoryRequest(req,agentID); - })); - - } - - #endregion - - public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID) - { - - //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit - // You need to be aware of this and - - - //if (llsdRequest.asset_type == "texture" || - // llsdRequest.asset_type == "animation" || - // llsdRequest.asset_type == "sound") - // { - IClientAPI client = null; - - - IMoneyModule mm = m_scene.RequestModuleInterface(); - - if (mm != null) - { - if (m_scene.TryGetClient(agentID, out client)) - { - if (!mm.UploadCovered(client, mm.UploadCharge)) - { - if (client != null) - client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); - - LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); - errorResponse.rsvp = ""; - errorResponse.state = "error"; - return errorResponse; - } - } - } - // } - - - - string assetName = llsdRequest.name; - string assetDes = llsdRequest.description; - string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/"; - UUID newAsset = UUID.Random(); - UUID newInvItem = UUID.Random(); - 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, - llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile); - MainServer.Instance.AddStreamHandler( - new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); - - string protocol = "http://"; - - if (MainServer.Instance.UseSSL) - protocol = "https://"; - - string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase + - uploaderPath; - - - LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); - - - uploadResponse.rsvp = uploaderURL; - uploadResponse.state = "upload"; - uploadResponse.resource_cost = 0; - uploadResponse.upload_price = 0; - - uploader.OnUpLoad += //UploadCompleteHandler; - - delegate( - string passetName, string passetDescription, UUID passetID, - UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType, - string passetType) - { - UploadCompleteHandler(passetName, passetDescription, passetID, - pinventoryItem, pparentFolder, pdata, pinventoryType, - passetType,agentID); - }; - return uploadResponse; - } - - - public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, - UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, - string assetType,UUID AgentID) - { - - 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; - } - } - else if (inventoryType == "mesh") - { - inType = (sbyte)InventoryType.Mesh; - assType = (sbyte)AssetType.Mesh; - } - - AssetBase asset; - asset = new AssetBase(assetID, assetName, assType, AgentID.ToString()); - asset.Data = data; - - if (m_scene.AssetService != null) - m_scene.AssetService.Store(asset); - - InventoryItemBase item = new InventoryItemBase(); - item.Owner = AgentID; - item.CreatorId = AgentID.ToString(); - 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(); - m_scene.AddInventoryItem(item); - - } - } -} diff --git a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs deleted file mode 100644 index a0d72ed..0000000 --- a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs +++ /dev/null @@ -1,370 +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.Reflection; -using log4net; -using Nini.Config; -using OpenMetaverse; -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 Caps=OpenSim.Framework.Capabilities.Caps; - -namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps -{ - public class ObjectAdd : IRegionModule - { -// private static readonly ILog m_log = -// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private Scene m_scene; - #region IRegionModule Members - - public void Initialise(Scene pScene, IConfigSource pSource) - { - m_scene = pScene; - m_scene.EventManager.OnRegisterCaps += RegisterCaps; - } - - public void PostInitialise() - { - - } - - public void RegisterCaps(UUID agentID, Caps caps) - { - UUID capuuid = UUID.Random(); - -// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/"); - - caps.RegisterHandler("ObjectAdd", - new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/", - delegate(Hashtable m_dhttpMethod) - { - return ProcessAdd(m_dhttpMethod, agentID, caps); - })); - } - - public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap) - { - Hashtable responsedata = new Hashtable(); - responsedata["int_response_code"] = 400; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "Request wasn't what was expected"; - ScenePresence avatar; - - if (!m_scene.TryGetScenePresence(AgentId, out avatar)) - return responsedata; - - - OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]); - //UUID session_id = UUID.Zero; - bool bypass_raycast = false; - uint everyone_mask = 0; - uint group_mask = 0; - uint next_owner_mask = 0; - uint flags = 0; - UUID group_id = UUID.Zero; - int hollow = 0; - int material = 0; - int p_code = 0; - int path_begin = 0; - int path_curve = 0; - int path_end = 0; - int path_radius_offset = 0; - int path_revolutions = 0; - int path_scale_x = 0; - int path_scale_y = 0; - int path_shear_x = 0; - int path_shear_y = 0; - int path_skew = 0; - int path_taper_x = 0; - int path_taper_y = 0; - int path_twist = 0; - int path_twist_begin = 0; - int profile_begin = 0; - int profile_curve = 0; - int profile_end = 0; - Vector3 ray_end = Vector3.Zero; - bool ray_end_is_intersection = false; - Vector3 ray_start = Vector3.Zero; - UUID ray_target_id = UUID.Zero; - Quaternion rotation = Quaternion.Identity; - Vector3 scale = Vector3.Zero; - int state = 0; - - if (r.Type != OSDType.Map) // not a proper req - return responsedata; - - OSDMap rm = (OSDMap)r; - - if (rm.ContainsKey("ObjectData")) //v2 - { - if (rm["ObjectData"].Type != OSDType.Map) - { - responsedata["str_response_string"] = "Has ObjectData key, but data not in expected format"; - return responsedata; - } - - OSDMap ObjMap = (OSDMap) rm["ObjectData"]; - - bypass_raycast = ObjMap["BypassRaycast"].AsBoolean(); - everyone_mask = readuintval(ObjMap["EveryoneMask"]); - flags = readuintval(ObjMap["Flags"]); - group_mask = readuintval(ObjMap["GroupMask"]); - material = ObjMap["Material"].AsInteger(); - next_owner_mask = readuintval(ObjMap["NextOwnerMask"]); - p_code = ObjMap["PCode"].AsInteger(); - - if (ObjMap.ContainsKey("Path")) - { - if (ObjMap["Path"].Type != OSDType.Map) - { - responsedata["str_response_string"] = "Has Path key, but data not in expected format"; - return responsedata; - } - - OSDMap PathMap = (OSDMap)ObjMap["Path"]; - path_begin = PathMap["Begin"].AsInteger(); - path_curve = PathMap["Curve"].AsInteger(); - path_end = PathMap["End"].AsInteger(); - path_radius_offset = PathMap["RadiusOffset"].AsInteger(); - path_revolutions = PathMap["Revolutions"].AsInteger(); - path_scale_x = PathMap["ScaleX"].AsInteger(); - path_scale_y = PathMap["ScaleY"].AsInteger(); - path_shear_x = PathMap["ShearX"].AsInteger(); - path_shear_y = PathMap["ShearY"].AsInteger(); - path_skew = PathMap["Skew"].AsInteger(); - path_taper_x = PathMap["TaperX"].AsInteger(); - path_taper_y = PathMap["TaperY"].AsInteger(); - path_twist = PathMap["Twist"].AsInteger(); - path_twist_begin = PathMap["TwistBegin"].AsInteger(); - - } - - if (ObjMap.ContainsKey("Profile")) - { - if (ObjMap["Profile"].Type != OSDType.Map) - { - responsedata["str_response_string"] = "Has Profile key, but data not in expected format"; - return responsedata; - } - - OSDMap ProfileMap = (OSDMap)ObjMap["Profile"]; - - profile_begin = ProfileMap["Begin"].AsInteger(); - profile_curve = ProfileMap["Curve"].AsInteger(); - profile_end = ProfileMap["End"].AsInteger(); - hollow = ProfileMap["Hollow"].AsInteger(); - } - ray_end_is_intersection = ObjMap["RayEndIsIntersection"].AsBoolean(); - - ray_target_id = ObjMap["RayTargetId"].AsUUID(); - state = ObjMap["State"].AsInteger(); - try - { - ray_end = ((OSDArray) ObjMap["RayEnd"]).AsVector3(); - ray_start = ((OSDArray) ObjMap["RayStart"]).AsVector3(); - scale = ((OSDArray) ObjMap["Scale"]).AsVector3(); - rotation = ((OSDArray)ObjMap["Rotation"]).AsQuaternion(); - } - catch (Exception) - { - responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format"; - return responsedata; - } - - if (rm.ContainsKey("AgentData")) - { - if (rm["AgentData"].Type != OSDType.Map) - { - responsedata["str_response_string"] = "Has AgentData key, but data not in expected format"; - return responsedata; - } - - OSDMap AgentDataMap = (OSDMap) rm["AgentData"]; - - //session_id = AgentDataMap["SessionId"].AsUUID(); - group_id = AgentDataMap["GroupId"].AsUUID(); - } - - } - else - { //v1 - bypass_raycast = rm["bypass_raycast"].AsBoolean(); - - everyone_mask = readuintval(rm["everyone_mask"]); - flags = readuintval(rm["flags"]); - group_id = rm["group_id"].AsUUID(); - group_mask = readuintval(rm["group_mask"]); - hollow = rm["hollow"].AsInteger(); - material = rm["material"].AsInteger(); - next_owner_mask = readuintval(rm["next_owner_mask"]); - hollow = rm["hollow"].AsInteger(); - p_code = rm["p_code"].AsInteger(); - path_begin = rm["path_begin"].AsInteger(); - path_curve = rm["path_curve"].AsInteger(); - path_end = rm["path_end"].AsInteger(); - path_radius_offset = rm["path_radius_offset"].AsInteger(); - path_revolutions = rm["path_revolutions"].AsInteger(); - path_scale_x = rm["path_scale_x"].AsInteger(); - path_scale_y = rm["path_scale_y"].AsInteger(); - path_shear_x = rm["path_shear_x"].AsInteger(); - path_shear_y = rm["path_shear_y"].AsInteger(); - path_skew = rm["path_skew"].AsInteger(); - path_taper_x = rm["path_taper_x"].AsInteger(); - path_taper_y = rm["path_taper_y"].AsInteger(); - path_twist = rm["path_twist"].AsInteger(); - path_twist_begin = rm["path_twist_begin"].AsInteger(); - profile_begin = rm["profile_begin"].AsInteger(); - profile_curve = rm["profile_curve"].AsInteger(); - profile_end = rm["profile_end"].AsInteger(); - - ray_end_is_intersection = rm["ray_end_is_intersection"].AsBoolean(); - - ray_target_id = rm["ray_target_id"].AsUUID(); - - - //session_id = rm["session_id"].AsUUID(); - state = rm["state"].AsInteger(); - try - { - ray_end = ((OSDArray)rm["ray_end"]).AsVector3(); - ray_start = ((OSDArray)rm["ray_start"]).AsVector3(); - rotation = ((OSDArray)rm["rotation"]).AsQuaternion(); - scale = ((OSDArray)rm["scale"]).AsVector3(); - } - catch (Exception) - { - responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format"; - return responsedata; - } - } - - - - Vector3 pos = m_scene.GetNewRezLocation(ray_start, ray_end, ray_target_id, rotation, (bypass_raycast) ? (byte)1 : (byte)0, (ray_end_is_intersection) ? (byte)1 : (byte)0, true, scale, false); - - PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); - - pbs.PathBegin = (ushort)path_begin; - pbs.PathCurve = (byte)path_curve; - pbs.PathEnd = (ushort)path_end; - pbs.PathRadiusOffset = (sbyte)path_radius_offset; - pbs.PathRevolutions = (byte)path_revolutions; - pbs.PathScaleX = (byte)path_scale_x; - pbs.PathScaleY = (byte)path_scale_y; - pbs.PathShearX = (byte) path_shear_x; - pbs.PathShearY = (byte)path_shear_y; - pbs.PathSkew = (sbyte)path_skew; - pbs.PathTaperX = (sbyte)path_taper_x; - pbs.PathTaperY = (sbyte)path_taper_y; - pbs.PathTwist = (sbyte)path_twist; - pbs.PathTwistBegin = (sbyte)path_twist_begin; - pbs.HollowShape = (HollowShape) hollow; - pbs.PCode = (byte)p_code; - pbs.ProfileBegin = (ushort) profile_begin; - pbs.ProfileCurve = (byte) profile_curve; - pbs.ProfileEnd = (ushort)profile_end; - pbs.Scale = scale; - pbs.State = (byte)state; - - SceneObjectGroup obj = null; ; - - if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos)) - { - // rez ON the ground, not IN the ground - // pos.Z += 0.25F; - - obj = m_scene.AddNewPrim(avatar.UUID, group_id, pos, rotation, pbs); - } - - - if (obj == null) - return responsedata; - - SceneObjectPart rootpart = obj.RootPart; - rootpart.Shape = pbs; - rootpart.Flags |= (PrimFlags)flags; - rootpart.EveryoneMask = everyone_mask; - rootpart.GroupID = group_id; - rootpart.GroupMask = group_mask; - rootpart.NextOwnerMask = next_owner_mask; - rootpart.Material = (byte)material; - - - - m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); - - responsedata["int_response_code"] = 200; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = String.Format("local_id{0}",ConvertUintToBytes(obj.LocalId)); - - return responsedata; - } - - private uint readuintval(OSD obj) - { - byte[] tmp = obj.AsBinary(); - if (BitConverter.IsLittleEndian) - Array.Reverse(tmp); - return Utils.BytesToUInt(tmp); - - } - private string ConvertUintToBytes(uint val) - { - byte[] resultbytes = Utils.UIntToBytes(val); - if (BitConverter.IsLittleEndian) - Array.Reverse(resultbytes); - return String.Format("{0}",Convert.ToBase64String(resultbytes)); - } - - public void Close() - { - - } - - public string Name - { - get { return "ObjectAddModule"; } - } - - public bool IsSharedModule - { - get { return false; } - } - - #endregion - } -} diff --git a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs deleted file mode 100644 index 3114d7f..0000000 --- a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs +++ /dev/null @@ -1,374 +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.Specialized; -using System.Reflection; -using System.IO; -using System.Web; -using Mono.Addins; -using log4net; -using Nini.Config; -using OpenMetaverse; -using OpenMetaverse.StructuredData; -using OpenMetaverse.Messages.Linden; -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 OSD = OpenMetaverse.StructuredData.OSD; -using OSDMap = OpenMetaverse.StructuredData.OSDMap; -using OpenSim.Framework.Capabilities; -using ExtraParamType = OpenMetaverse.ExtraParamType; - -namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps -{ - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class UploadObjectAssetModule : INonSharedRegionModule - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Scene m_scene; - - #region IRegionModuleBase Members - - - public Type ReplaceableInterface - { - get { return null; } - } - - public void Initialise(IConfigSource source) - { - - } - - 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_scene.EventManager.OnRegisterCaps += RegisterCaps; - } - - #endregion - - - #region IRegionModule Members - - - - public void Close() { } - - public string Name { get { return "UploadObjectAssetModuleModule"; } } - - - public void RegisterCaps(UUID agentID, Caps caps) - { - UUID capID = UUID.Random(); - -// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID); - caps.RegisterHandler("UploadObjectAsset", - new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/", - delegate(Hashtable m_dhttpMethod) - { - return ProcessAdd(m_dhttpMethod, agentID, caps); - })); - /* - caps.RegisterHandler("NewFileAgentInventoryVariablePrice", - - new LLSDStreamhandler("POST", - "/CAPS/" + capID.ToString(), - delegate(LLSDAssetUploadRequest req) - { - return NewAgentInventoryRequest(req,agentID); - })); - */ - - } - - #endregion - - - /// - /// Parses ad request - /// - /// - /// - /// - /// - public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap) - { - Hashtable responsedata = new Hashtable(); - responsedata["int_response_code"] = 400; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = "Request wasn't what was expected"; - ScenePresence avatar; - - if (!m_scene.TryGetScenePresence(AgentId, out avatar)) - return responsedata; - - OSDMap r = (OSDMap)OSDParser.Deserialize((string)request["requestbody"]); - UploadObjectAssetMessage message = new UploadObjectAssetMessage(); - try - { - message.Deserialize(r); - - } - catch (Exception ex) - { - m_log.Error("[UPLOAD OBJECT ASSET MODULE]: Error deserializing message " + ex.ToString()); - message = null; - } - - if (message == null) - { - responsedata["int_response_code"] = 400; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = - "errorError parsing Object"; - - return responsedata; - } - - Vector3 pos = avatar.AbsolutePosition + (Vector3.UnitX * avatar.Rotation); - Quaternion rot = Quaternion.Identity; - Vector3 rootpos = Vector3.Zero; -// Quaternion rootrot = Quaternion.Identity; - - SceneObjectGroup rootGroup = null; - SceneObjectGroup[] allparts = new SceneObjectGroup[message.Objects.Length]; - for (int i = 0; i < message.Objects.Length; i++) - { - UploadObjectAssetMessage.Object obj = message.Objects[i]; - PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); - - if (i == 0) - { - rootpos = obj.Position; -// rootrot = obj.Rotation; - } - - // Combine the extraparams data into it's ugly blob again.... - //int bytelength = 0; - //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) - //{ - // bytelength += obj.ExtraParams[extparams].ExtraParamData.Length; - //} - //byte[] extraparams = new byte[bytelength]; - //int position = 0; - - - - //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) - //{ - // Buffer.BlockCopy(obj.ExtraParams[extparams].ExtraParamData, 0, extraparams, position, - // obj.ExtraParams[extparams].ExtraParamData.Length); - // - // position += obj.ExtraParams[extparams].ExtraParamData.Length; - // } - - //pbs.ExtraParams = extraparams; - for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) - { - UploadObjectAssetMessage.Object.ExtraParam extraParam = obj.ExtraParams[extparams]; - switch ((ushort)extraParam.Type) - { - case (ushort)ExtraParamType.Sculpt: - Primitive.SculptData sculpt = new Primitive.SculptData(extraParam.ExtraParamData, 0); - - pbs.SculptEntry = true; - - pbs.SculptTexture = obj.SculptID; - pbs.SculptType = (byte)sculpt.Type; - - break; - case (ushort)ExtraParamType.Flexible: - Primitive.FlexibleData flex = new Primitive.FlexibleData(extraParam.ExtraParamData, 0); - pbs.FlexiEntry = true; - pbs.FlexiDrag = flex.Drag; - pbs.FlexiForceX = flex.Force.X; - pbs.FlexiForceY = flex.Force.Y; - pbs.FlexiForceZ = flex.Force.Z; - pbs.FlexiGravity = flex.Gravity; - pbs.FlexiSoftness = flex.Softness; - pbs.FlexiTension = flex.Tension; - pbs.FlexiWind = flex.Wind; - break; - case (ushort)ExtraParamType.Light: - Primitive.LightData light = new Primitive.LightData(extraParam.ExtraParamData, 0); - pbs.LightColorA = light.Color.A; - pbs.LightColorB = light.Color.B; - pbs.LightColorG = light.Color.G; - pbs.LightColorR = light.Color.R; - pbs.LightCutoff = light.Cutoff; - pbs.LightEntry = true; - pbs.LightFalloff = light.Falloff; - pbs.LightIntensity = light.Intensity; - pbs.LightRadius = light.Radius; - break; - case 0x40: - pbs.ReadProjectionData(extraParam.ExtraParamData, 0); - break; - - } - - - } - pbs.PathBegin = (ushort) obj.PathBegin; - pbs.PathCurve = (byte) obj.PathCurve; - pbs.PathEnd = (ushort) obj.PathEnd; - pbs.PathRadiusOffset = (sbyte) obj.RadiusOffset; - pbs.PathRevolutions = (byte) obj.Revolutions; - pbs.PathScaleX = (byte) obj.ScaleX; - pbs.PathScaleY = (byte) obj.ScaleY; - pbs.PathShearX = (byte) obj.ShearX; - pbs.PathShearY = (byte) obj.ShearY; - pbs.PathSkew = (sbyte) obj.Skew; - pbs.PathTaperX = (sbyte) obj.TaperX; - pbs.PathTaperY = (sbyte) obj.TaperY; - pbs.PathTwist = (sbyte) obj.Twist; - pbs.PathTwistBegin = (sbyte) obj.TwistBegin; - pbs.HollowShape = (HollowShape) obj.ProfileHollow; - pbs.PCode = (byte) PCode.Prim; - pbs.ProfileBegin = (ushort) obj.ProfileBegin; - pbs.ProfileCurve = (byte) obj.ProfileCurve; - pbs.ProfileEnd = (ushort) obj.ProfileEnd; - pbs.Scale = obj.Scale; - pbs.State = (byte) 0; - SceneObjectPart prim = new SceneObjectPart(); - prim.UUID = UUID.Random(); - prim.CreatorID = AgentId; - prim.OwnerID = AgentId; - prim.GroupID = obj.GroupID; - prim.LastOwnerID = prim.OwnerID; - prim.CreationDate = Util.UnixTimeSinceEpoch(); - prim.Name = obj.Name; - prim.Description = ""; - - prim.PayPrice[0] = -2; - prim.PayPrice[1] = -2; - prim.PayPrice[2] = -2; - prim.PayPrice[3] = -2; - prim.PayPrice[4] = -2; - Primitive.TextureEntry tmp = - new Primitive.TextureEntry(UUID.Parse("89556747-24cb-43ed-920b-47caed15465f")); - - for (int j = 0; j < obj.Faces.Length; j++) - { - UploadObjectAssetMessage.Object.Face face = obj.Faces[j]; - - Primitive.TextureEntryFace primFace = tmp.CreateFace((uint) j); - - primFace.Bump = face.Bump; - primFace.RGBA = face.Color; - primFace.Fullbright = face.Fullbright; - primFace.Glow = face.Glow; - primFace.TextureID = face.ImageID; - primFace.Rotation = face.ImageRot; - primFace.MediaFlags = ((face.MediaFlags & 1) != 0); - - primFace.OffsetU = face.OffsetS; - primFace.OffsetV = face.OffsetT; - primFace.RepeatU = face.ScaleS; - primFace.RepeatV = face.ScaleT; - primFace.TexMapType = (MappingType) (face.MediaFlags & 6); - } - pbs.TextureEntry = tmp.GetBytes(); - prim.Shape = pbs; - prim.Scale = obj.Scale; - - - SceneObjectGroup grp = new SceneObjectGroup(); - - grp.SetRootPart(prim); - prim.ParentID = 0; - if (i == 0) - { - rootGroup = grp; - - } - grp.AttachToScene(m_scene); - grp.AbsolutePosition = obj.Position; - prim.RotationOffset = obj.Rotation; - - grp.RootPart.IsAttachment = false; - // Required for linking - grp.RootPart.UpdateFlag = 0; - - if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos)) - { - m_scene.AddSceneObject(grp); - grp.AbsolutePosition = obj.Position; - } - allparts[i] = grp; - - } - - for (int j = 1; j < allparts.Length; j++) - { - rootGroup.RootPart.UpdateFlag = 0; - allparts[j].RootPart.UpdateFlag = 0; - rootGroup.LinkToGroup(allparts[j]); - } - - rootGroup.ScheduleGroupForFullUpdate(); - pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false); - - responsedata["int_response_code"] = 200; //501; //410; //404; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = String.Format("local_id{0}", ConvertUintToBytes(allparts[0].LocalId)); - - return responsedata; - } - - private string ConvertUintToBytes(uint val) - { - byte[] resultbytes = Utils.UIntToBytes(val); - if (BitConverter.IsLittleEndian) - Array.Reverse(resultbytes); - return String.Format("{0}", Convert.ToBase64String(resultbytes)); - } - } -} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Caps/CapabilitiesModule.cs new file mode 100644 index 0000000..ab388b9 --- /dev/null +++ b/OpenSim/Region/CoreModules/Caps/CapabilitiesModule.cs @@ -0,0 +1,255 @@ +/* + * 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 copyrightD + * 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 OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using Caps=OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.CoreModules.Capabilities +{ + public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + protected Scene m_scene; + + /// + /// Each agent has its own capabilities handler. + /// + protected Dictionary m_capsHandlers = new Dictionary(); + + protected Dictionary capsPaths = new Dictionary(); + protected Dictionary> childrenSeeds + = new Dictionary>(); + + public void Initialise(IConfigSource source) + { + } + + public void AddRegion(Scene scene) + { + m_scene = scene; + m_scene.RegisterModuleInterface(this); + MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps", + "show capabilities", + "Shows all registered capabilities", CapabilitiesCommand); + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + m_scene.UnregisterModuleInterface(this); + } + + public void PostInitialise() + { + } + + public void Close() {} + + public string Name + { + get { return "Capabilities Module"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddCapsHandler(UUID agentId) + { + if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId)) + return; + + String capsObjectPath = GetCapsPath(agentId); + + if (m_capsHandlers.ContainsKey(agentId)) + { + Caps oldCaps = m_capsHandlers[agentId]; + + m_log.DebugFormat( + "[CAPS]: Reregistering 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. + // Hence this return here. + //return; + } + + Caps caps + = new Caps(m_scene, + m_scene.AssetService, MainServer.Instance, m_scene.RegionInfo.ExternalHostName, + (MainServer.Instance == null) ? 0: MainServer.Instance.Port, + capsObjectPath, agentId, m_scene.DumpAssetsToFile, m_scene.RegionInfo.RegionName); + + caps.RegisterHandlers(); + + 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) + { + if (childrenSeeds.ContainsKey(agentId)) + { + childrenSeeds.Remove(agentId); + } + + lock (m_capsHandlers) + { + if (m_capsHandlers.ContainsKey(agentId)) + { + m_capsHandlers[agentId].DeregisterHandlers(); + m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsHandlers[agentId]); + m_capsHandlers.Remove(agentId); + } + else + { + m_log.WarnFormat( + "[CAPS]: Received request to remove CAPS handler for root agent {0} in {1}, but no such CAPS handler found!", + agentId, m_scene.RegionInfo.RegionName); + } + } + } + + public Caps GetCapsHandlerForUser(UUID agentId) + { + lock (m_capsHandlers) + { + if (m_capsHandlers.ContainsKey(agentId)) + { + return m_capsHandlers[agentId]; + } + } + + return null; + } + + public void NewUserConnection(AgentCircuitData agent) + { + capsPaths[agent.AgentID] = agent.CapsPath; + childrenSeeds[agent.AgentID] + = ((agent.ChildrenCapSeeds == null) ? new Dictionary() : agent.ChildrenCapSeeds); + } + + public string GetCapsPath(UUID agentId) + { + if (capsPaths.ContainsKey(agentId)) + { + return capsPaths[agentId]; + } + + return null; + } + + public Dictionary GetChildrenSeeds(UUID agentID) + { + Dictionary seeds = null; + if (childrenSeeds.TryGetValue(agentID, out seeds)) + return seeds; + return new Dictionary(); + } + + public void DropChildSeed(UUID agentID, ulong handle) + { + Dictionary seeds; + if (childrenSeeds.TryGetValue(agentID, out seeds)) + { + seeds.Remove(handle); + } + } + + public string GetChildSeed(UUID agentID, ulong handle) + { + Dictionary seeds; + string returnval; + if (childrenSeeds.TryGetValue(agentID, out seeds)) + { + if (seeds.TryGetValue(handle, out returnval)) + return returnval; + } + return null; + } + + public void SetChildrenSeed(UUID agentID, Dictionary seeds) + { + //m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count); + childrenSeeds[agentID] = seeds; + } + + public void DumpChildrenSeeds(UUID agentID) + { + m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================"); + foreach (KeyValuePair kvp in childrenSeeds[agentID]) + { + uint x, y; + Utils.LongToUInts(kvp.Key, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + m_log.Info(" >> "+x+", "+y+": "+kvp.Value); + } + } + + private void CapabilitiesCommand(string module, string[] cmdparams) + { + System.Text.StringBuilder caps = new System.Text.StringBuilder(); + caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); + + foreach (KeyValuePair kvp in m_capsHandlers) + { + caps.AppendFormat("** User {0}:\n", kvp.Key); + for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.CapsDetails.GetEnumerator(); kvp2.MoveNext(); ) + { + Uri uri = new Uri(kvp2.Value.ToString()); + caps.AppendFormat(" {0} = {1}\n", kvp2.Key, uri.PathAndQuery); + } + } + + MainConsole.Instance.Output(caps.ToString()); + } + } +} diff --git a/OpenSim/Region/CoreModules/Caps/GetMeshModule.cs b/OpenSim/Region/CoreModules/Caps/GetMeshModule.cs new file mode 100644 index 0000000..46b2378 --- /dev/null +++ b/OpenSim/Region/CoreModules/Caps/GetMeshModule.cs @@ -0,0 +1,211 @@ +/* + * 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.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.Capabilities +{ + [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; + + #region IRegionModuleBase Members + + + public Type ReplaceableInterface + { + get { return null; } + } + + 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) + { + + Hashtable responsedata = new Hashtable(); + responsedata["int_response_code"] = 400; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Request wasn't what was expected"; + + string meshStr = string.Empty; + + if (request.ContainsKey("mesh_id")) + meshStr = request["mesh_id"].ToString(); + + + UUID meshID = UUID.Zero; + if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID)) + { + if (m_assetService == null) + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; + return responsedata; + } + + AssetBase mesh; + // Only try to fetch locally cached textures. Misses are redirected + mesh = m_assetService.GetCached(meshID.ToString()); + if (mesh != null) + { + if (mesh.Type == (SByte)AssetType.Mesh) + { + responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); + responsedata["content_type"] = "application/vnd.ll.mesh"; + responsedata["int_response_code"] = 200; + } + // Optionally add additional mesh types here + else + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; + return responsedata; + } + } + else + { + mesh = m_assetService.Get(meshID.ToString()); + if (mesh != null) + { + if (mesh.Type == (SByte)AssetType.Mesh) + { + responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); + responsedata["content_type"] = "application/vnd.ll.mesh"; + responsedata["int_response_code"] = 200; + } + // Optionally add additional mesh types here + else + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; + return responsedata; + } + } + + else + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; + return responsedata; + } + } + + } + + return responsedata; + } + } +} diff --git a/OpenSim/Region/CoreModules/Caps/GetTextureModule.cs b/OpenSim/Region/CoreModules/Caps/GetTextureModule.cs new file mode 100644 index 0000000..34095a2 --- /dev/null +++ b/OpenSim/Region/CoreModules/Caps/GetTextureModule.cs @@ -0,0 +1,402 @@ +/* + * 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 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; + +namespace OpenSim.Region.CoreModules.Capabilities +{ + #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 + { + 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"; + + // TODO: Change this to a config option + const string REDIRECT_URL = null; + + + #region IRegionModule Members + + public void Initialise(Scene pScene, IConfigSource pSource) + { + m_scene = pScene; + } + + public void PostInitialise() + { + 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"); + + if (m_assetService == null) + { + m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return null; + } + + UUID textureID; + if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID)) + { + string[] formats; + if (format != null && format != string.Empty) + { + formats = new string[1] { format.ToLower() }; + } + else + { + formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept")); + if (formats.Length == 0) + formats = new string[1] { DefaultFormat }; // default + + } + // OK, we have an array with preferred formats, possibly with only one entry + + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + foreach (string f in formats) + { + if (FetchTexture(httpRequest, httpResponse, textureID, f)) + break; + } + + } + else + { + m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); + } + + httpResponse.Send(); + return null; + } + + /// + /// + /// + /// + /// + /// + /// + /// False for "caller try another codec"; true otherwise + private bool FetchTexture(OSHttpRequest httpRequest, OSHttpResponse httpResponse, UUID textureID, string format) + { +// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); + AssetBase texture; + + string fullID = textureID.ToString(); + if (format != DefaultFormat) + fullID = fullID + "-" + format; + + if (!String.IsNullOrEmpty(REDIRECT_URL)) + { + // Only try to fetch locally cached textures. Misses are redirected + texture = m_assetService.GetCached(fullID); + + if (texture != null) + { + if (texture.Type != (sbyte)AssetType.Texture) + { + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return true; + } + WriteTextureData(httpRequest, httpResponse, texture, format); + } + else + { + string textureUrl = REDIRECT_URL + textureID.ToString(); + m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); + httpResponse.RedirectLocation = textureUrl; + return true; + } + } + else // no redirect + { + // try the cache + texture = m_assetService.GetCached(fullID); + + if (texture == null) + { + //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); + + // Fetch locally or remotely. Misses return a 404 + texture = m_assetService.Get(textureID.ToString()); + + if (texture != null) + { + if (texture.Type != (sbyte)AssetType.Texture) + { + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return true; + } + if (format == DefaultFormat) + { + WriteTextureData(httpRequest, httpResponse, texture, format); + return true; + } + else + { + AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); + newTexture.Data = ConvertTextureData(texture, format); + if (newTexture.Data.Length == 0) + return false; // !!! Caller try another codec, please! + + newTexture.Flags = AssetFlags.Collectable; + newTexture.Temporary = true; + m_assetService.Store(newTexture); + WriteTextureData(httpRequest, httpResponse, newTexture, format); + return true; + } + } + } + else // it was on the cache + { + //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); + WriteTextureData(httpRequest, httpResponse, texture, format); + return true; + } + } + + // not found +// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return true; + } + + private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format) + { + string range = request.Headers.GetOne("Range"); + //m_log.DebugFormat("[GETTEXTURE]: Range {0}", range); + if (!String.IsNullOrEmpty(range)) // JP2's only + { + // Range request + int start, end; + if (TryParseRange(range, out start, out end)) + { + // Before clamping start make sure we can satisfy it in order to avoid + // sending back the last byte instead of an error status + if (start >= texture.Data.Length) + { + response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; + return; + } + + end = Utils.Clamp(end, 0, texture.Data.Length - 1); + start = Utils.Clamp(start, 0, end); + int len = end - start + 1; + + //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); + + if (len < texture.Data.Length) + response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; + + response.ContentLength = len; + response.ContentType = texture.Metadata.ContentType; + response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); + + response.Body.Write(texture.Data, start, len); + } + else + { + m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range); + response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; + } + } + else // JP2's or other formats + { + // Full content request + response.StatusCode = (int)System.Net.HttpStatusCode.OK; + response.ContentLength = texture.Data.Length; + if (format == DefaultFormat) + response.ContentType = texture.Metadata.ContentType; + else + response.ContentType = "image/" + format; + response.Body.Write(texture.Data, 0, texture.Data.Length); + } + } + + private bool TryParseRange(string header, out int start, out int end) + { + if (header.StartsWith("bytes=")) + { + string[] rangeValues = header.Substring(6).Split('-'); + if (rangeValues.Length == 2) + { + if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end)) + return true; + } + } + + start = end = 0; + return false; + } + + + private byte[] ConvertTextureData(AssetBase texture, string format) + { + m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format); + byte[] data = new byte[0]; + + MemoryStream imgstream = new MemoryStream(); + Bitmap mTexture = new Bitmap(1, 1); + ManagedImage managedImage; + Image image = (Image)mTexture; + + try + { + // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data + + imgstream = new MemoryStream(); + + // Decode image to System.Drawing.Image + if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image)) + { + // Save to bitmap + mTexture = new Bitmap(image); + + EncoderParameters myEncoderParameters = new EncoderParameters(); + myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L); + + // Save bitmap to stream + ImageCodecInfo codec = GetEncoderInfo("image/" + format); + if (codec != null) + { + mTexture.Save(imgstream, codec, myEncoderParameters); + // Write the stream to a byte array for output + data = imgstream.ToArray(); + } + else + m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format); + + } + } + catch (Exception e) + { + m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message); + } + finally + { + // Reclaim memory, these are unmanaged resources + // If we encountered an exception, one or more of these will be null + if (mTexture != null) + mTexture.Dispose(); + + if (image != null) + image.Dispose(); + + if (imgstream != null) + { + imgstream.Close(); + imgstream.Dispose(); + } + } + + return data; + } + + // From msdn + private static ImageCodecInfo GetEncoderInfo(String mimeType) + { + ImageCodecInfo[] encoders; + encoders = ImageCodecInfo.GetImageEncoders(); + for (int j = 0; j < encoders.Length; ++j) + { + if (encoders[j].MimeType == mimeType) + return encoders[j]; + } + return null; + } + + + } +} diff --git a/OpenSim/Region/CoreModules/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/CoreModules/Caps/NewFileAgentInventoryVariablePriceModule.cs new file mode 100644 index 0000000..3ebaf1f --- /dev/null +++ b/OpenSim/Region/CoreModules/Caps/NewFileAgentInventoryVariablePriceModule.cs @@ -0,0 +1,275 @@ +/* + * 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.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.Framework.Capabilities; + +namespace OpenSim.Region.CoreModules.Capabilities +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule + { +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; +// private IAssetService m_assetService; + private bool m_dumpAssetsToFile = false; + private bool m_enabled = true; + + #region IRegionModuleBase Members + + + public Type ReplaceableInterface + { + get { return null; } + } + + 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 "NewFileAgentInventoryVariablePriceModule"; } } + + + public void RegisterCaps(UUID agentID, Caps caps) + { + if(!m_enabled) + return; + + UUID capID = UUID.Random(); + +// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID); + caps.RegisterHandler("NewFileAgentInventoryVariablePrice", + + new LLSDStreamhandler("POST", + "/CAPS/" + capID.ToString(), + delegate(LLSDAssetUploadRequest req) + { + return NewAgentInventoryRequest(req,agentID); + })); + + } + + #endregion + + public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID) + { + + //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit + // You need to be aware of this and + + + //if (llsdRequest.asset_type == "texture" || + // llsdRequest.asset_type == "animation" || + // llsdRequest.asset_type == "sound") + // { + IClientAPI client = null; + + + IMoneyModule mm = m_scene.RequestModuleInterface(); + + if (mm != null) + { + if (m_scene.TryGetClient(agentID, out client)) + { + if (!mm.UploadCovered(client, mm.UploadCharge)) + { + if (client != null) + client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); + + LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); + errorResponse.rsvp = ""; + errorResponse.state = "error"; + return errorResponse; + } + } + } + // } + + + + string assetName = llsdRequest.name; + string assetDes = llsdRequest.description; + string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/"; + UUID newAsset = UUID.Random(); + UUID newInvItem = UUID.Random(); + 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, + llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile); + MainServer.Instance.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + + string protocol = "http://"; + + if (MainServer.Instance.UseSSL) + protocol = "https://"; + + string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase + + uploaderPath; + + + LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); + + + uploadResponse.rsvp = uploaderURL; + uploadResponse.state = "upload"; + uploadResponse.resource_cost = 0; + uploadResponse.upload_price = 0; + + uploader.OnUpLoad += //UploadCompleteHandler; + + delegate( + string passetName, string passetDescription, UUID passetID, + UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType, + string passetType) + { + UploadCompleteHandler(passetName, passetDescription, passetID, + pinventoryItem, pparentFolder, pdata, pinventoryType, + passetType,agentID); + }; + return uploadResponse; + } + + + public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, + UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, + string assetType,UUID AgentID) + { + + 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; + } + } + else if (inventoryType == "mesh") + { + inType = (sbyte)InventoryType.Mesh; + assType = (sbyte)AssetType.Mesh; + } + + AssetBase asset; + asset = new AssetBase(assetID, assetName, assType, AgentID.ToString()); + asset.Data = data; + + if (m_scene.AssetService != null) + m_scene.AssetService.Store(asset); + + InventoryItemBase item = new InventoryItemBase(); + item.Owner = AgentID; + item.CreatorId = AgentID.ToString(); + 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(); + m_scene.AddInventoryItem(item); + + } + } +} diff --git a/OpenSim/Region/CoreModules/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/CoreModules/Caps/ObjectCaps/ObjectAdd.cs new file mode 100644 index 0000000..5cd0fe7 --- /dev/null +++ b/OpenSim/Region/CoreModules/Caps/ObjectCaps/ObjectAdd.cs @@ -0,0 +1,370 @@ +/* + * 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 OpenMetaverse; +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 Caps=OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.CoreModules.Capabilities +{ + public class ObjectAdd : IRegionModule + { +// private static readonly ILog m_log = +// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + #region IRegionModule Members + + public void Initialise(Scene pScene, IConfigSource pSource) + { + m_scene = pScene; + m_scene.EventManager.OnRegisterCaps += RegisterCaps; + } + + public void PostInitialise() + { + + } + + public void RegisterCaps(UUID agentID, Caps caps) + { + UUID capuuid = UUID.Random(); + +// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/"); + + caps.RegisterHandler("ObjectAdd", + new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/", + delegate(Hashtable m_dhttpMethod) + { + return ProcessAdd(m_dhttpMethod, agentID, caps); + })); + } + + public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap) + { + Hashtable responsedata = new Hashtable(); + responsedata["int_response_code"] = 400; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Request wasn't what was expected"; + ScenePresence avatar; + + if (!m_scene.TryGetScenePresence(AgentId, out avatar)) + return responsedata; + + + OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]); + //UUID session_id = UUID.Zero; + bool bypass_raycast = false; + uint everyone_mask = 0; + uint group_mask = 0; + uint next_owner_mask = 0; + uint flags = 0; + UUID group_id = UUID.Zero; + int hollow = 0; + int material = 0; + int p_code = 0; + int path_begin = 0; + int path_curve = 0; + int path_end = 0; + int path_radius_offset = 0; + int path_revolutions = 0; + int path_scale_x = 0; + int path_scale_y = 0; + int path_shear_x = 0; + int path_shear_y = 0; + int path_skew = 0; + int path_taper_x = 0; + int path_taper_y = 0; + int path_twist = 0; + int path_twist_begin = 0; + int profile_begin = 0; + int profile_curve = 0; + int profile_end = 0; + Vector3 ray_end = Vector3.Zero; + bool ray_end_is_intersection = false; + Vector3 ray_start = Vector3.Zero; + UUID ray_target_id = UUID.Zero; + Quaternion rotation = Quaternion.Identity; + Vector3 scale = Vector3.Zero; + int state = 0; + + if (r.Type != OSDType.Map) // not a proper req + return responsedata; + + OSDMap rm = (OSDMap)r; + + if (rm.ContainsKey("ObjectData")) //v2 + { + if (rm["ObjectData"].Type != OSDType.Map) + { + responsedata["str_response_string"] = "Has ObjectData key, but data not in expected format"; + return responsedata; + } + + OSDMap ObjMap = (OSDMap) rm["ObjectData"]; + + bypass_raycast = ObjMap["BypassRaycast"].AsBoolean(); + everyone_mask = readuintval(ObjMap["EveryoneMask"]); + flags = readuintval(ObjMap["Flags"]); + group_mask = readuintval(ObjMap["GroupMask"]); + material = ObjMap["Material"].AsInteger(); + next_owner_mask = readuintval(ObjMap["NextOwnerMask"]); + p_code = ObjMap["PCode"].AsInteger(); + + if (ObjMap.ContainsKey("Path")) + { + if (ObjMap["Path"].Type != OSDType.Map) + { + responsedata["str_response_string"] = "Has Path key, but data not in expected format"; + return responsedata; + } + + OSDMap PathMap = (OSDMap)ObjMap["Path"]; + path_begin = PathMap["Begin"].AsInteger(); + path_curve = PathMap["Curve"].AsInteger(); + path_end = PathMap["End"].AsInteger(); + path_radius_offset = PathMap["RadiusOffset"].AsInteger(); + path_revolutions = PathMap["Revolutions"].AsInteger(); + path_scale_x = PathMap["ScaleX"].AsInteger(); + path_scale_y = PathMap["ScaleY"].AsInteger(); + path_shear_x = PathMap["ShearX"].AsInteger(); + path_shear_y = PathMap["ShearY"].AsInteger(); + path_skew = PathMap["Skew"].AsInteger(); + path_taper_x = PathMap["TaperX"].AsInteger(); + path_taper_y = PathMap["TaperY"].AsInteger(); + path_twist = PathMap["Twist"].AsInteger(); + path_twist_begin = PathMap["TwistBegin"].AsInteger(); + + } + + if (ObjMap.ContainsKey("Profile")) + { + if (ObjMap["Profile"].Type != OSDType.Map) + { + responsedata["str_response_string"] = "Has Profile key, but data not in expected format"; + return responsedata; + } + + OSDMap ProfileMap = (OSDMap)ObjMap["Profile"]; + + profile_begin = ProfileMap["Begin"].AsInteger(); + profile_curve = ProfileMap["Curve"].AsInteger(); + profile_end = ProfileMap["End"].AsInteger(); + hollow = ProfileMap["Hollow"].AsInteger(); + } + ray_end_is_intersection = ObjMap["RayEndIsIntersection"].AsBoolean(); + + ray_target_id = ObjMap["RayTargetId"].AsUUID(); + state = ObjMap["State"].AsInteger(); + try + { + ray_end = ((OSDArray) ObjMap["RayEnd"]).AsVector3(); + ray_start = ((OSDArray) ObjMap["RayStart"]).AsVector3(); + scale = ((OSDArray) ObjMap["Scale"]).AsVector3(); + rotation = ((OSDArray)ObjMap["Rotation"]).AsQuaternion(); + } + catch (Exception) + { + responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format"; + return responsedata; + } + + if (rm.ContainsKey("AgentData")) + { + if (rm["AgentData"].Type != OSDType.Map) + { + responsedata["str_response_string"] = "Has AgentData key, but data not in expected format"; + return responsedata; + } + + OSDMap AgentDataMap = (OSDMap) rm["AgentData"]; + + //session_id = AgentDataMap["SessionId"].AsUUID(); + group_id = AgentDataMap["GroupId"].AsUUID(); + } + + } + else + { //v1 + bypass_raycast = rm["bypass_raycast"].AsBoolean(); + + everyone_mask = readuintval(rm["everyone_mask"]); + flags = readuintval(rm["flags"]); + group_id = rm["group_id"].AsUUID(); + group_mask = readuintval(rm["group_mask"]); + hollow = rm["hollow"].AsInteger(); + material = rm["material"].AsInteger(); + next_owner_mask = readuintval(rm["next_owner_mask"]); + hollow = rm["hollow"].AsInteger(); + p_code = rm["p_code"].AsInteger(); + path_begin = rm["path_begin"].AsInteger(); + path_curve = rm["path_curve"].AsInteger(); + path_end = rm["path_end"].AsInteger(); + path_radius_offset = rm["path_radius_offset"].AsInteger(); + path_revolutions = rm["path_revolutions"].AsInteger(); + path_scale_x = rm["path_scale_x"].AsInteger(); + path_scale_y = rm["path_scale_y"].AsInteger(); + path_shear_x = rm["path_shear_x"].AsInteger(); + path_shear_y = rm["path_shear_y"].AsInteger(); + path_skew = rm["path_skew"].AsInteger(); + path_taper_x = rm["path_taper_x"].AsInteger(); + path_taper_y = rm["path_taper_y"].AsInteger(); + path_twist = rm["path_twist"].AsInteger(); + path_twist_begin = rm["path_twist_begin"].AsInteger(); + profile_begin = rm["profile_begin"].AsInteger(); + profile_curve = rm["profile_curve"].AsInteger(); + profile_end = rm["profile_end"].AsInteger(); + + ray_end_is_intersection = rm["ray_end_is_intersection"].AsBoolean(); + + ray_target_id = rm["ray_target_id"].AsUUID(); + + + //session_id = rm["session_id"].AsUUID(); + state = rm["state"].AsInteger(); + try + { + ray_end = ((OSDArray)rm["ray_end"]).AsVector3(); + ray_start = ((OSDArray)rm["ray_start"]).AsVector3(); + rotation = ((OSDArray)rm["rotation"]).AsQuaternion(); + scale = ((OSDArray)rm["scale"]).AsVector3(); + } + catch (Exception) + { + responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format"; + return responsedata; + } + } + + + + Vector3 pos = m_scene.GetNewRezLocation(ray_start, ray_end, ray_target_id, rotation, (bypass_raycast) ? (byte)1 : (byte)0, (ray_end_is_intersection) ? (byte)1 : (byte)0, true, scale, false); + + PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); + + pbs.PathBegin = (ushort)path_begin; + pbs.PathCurve = (byte)path_curve; + pbs.PathEnd = (ushort)path_end; + pbs.PathRadiusOffset = (sbyte)path_radius_offset; + pbs.PathRevolutions = (byte)path_revolutions; + pbs.PathScaleX = (byte)path_scale_x; + pbs.PathScaleY = (byte)path_scale_y; + pbs.PathShearX = (byte) path_shear_x; + pbs.PathShearY = (byte)path_shear_y; + pbs.PathSkew = (sbyte)path_skew; + pbs.PathTaperX = (sbyte)path_taper_x; + pbs.PathTaperY = (sbyte)path_taper_y; + pbs.PathTwist = (sbyte)path_twist; + pbs.PathTwistBegin = (sbyte)path_twist_begin; + pbs.HollowShape = (HollowShape) hollow; + pbs.PCode = (byte)p_code; + pbs.ProfileBegin = (ushort) profile_begin; + pbs.ProfileCurve = (byte) profile_curve; + pbs.ProfileEnd = (ushort)profile_end; + pbs.Scale = scale; + pbs.State = (byte)state; + + SceneObjectGroup obj = null; ; + + if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos)) + { + // rez ON the ground, not IN the ground + // pos.Z += 0.25F; + + obj = m_scene.AddNewPrim(avatar.UUID, group_id, pos, rotation, pbs); + } + + + if (obj == null) + return responsedata; + + SceneObjectPart rootpart = obj.RootPart; + rootpart.Shape = pbs; + rootpart.Flags |= (PrimFlags)flags; + rootpart.EveryoneMask = everyone_mask; + rootpart.GroupID = group_id; + rootpart.GroupMask = group_mask; + rootpart.NextOwnerMask = next_owner_mask; + rootpart.Material = (byte)material; + + + + m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); + + responsedata["int_response_code"] = 200; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = String.Format("local_id{0}",ConvertUintToBytes(obj.LocalId)); + + return responsedata; + } + + private uint readuintval(OSD obj) + { + byte[] tmp = obj.AsBinary(); + if (BitConverter.IsLittleEndian) + Array.Reverse(tmp); + return Utils.BytesToUInt(tmp); + + } + private string ConvertUintToBytes(uint val) + { + byte[] resultbytes = Utils.UIntToBytes(val); + if (BitConverter.IsLittleEndian) + Array.Reverse(resultbytes); + return String.Format("{0}",Convert.ToBase64String(resultbytes)); + } + + public void Close() + { + + } + + public string Name + { + get { return "ObjectAddModule"; } + } + + public bool IsSharedModule + { + get { return false; } + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/CoreModules/Caps/ObjectCaps/UploadObjectAssetModule.cs new file mode 100644 index 0000000..33bffeb --- /dev/null +++ b/OpenSim/Region/CoreModules/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -0,0 +1,374 @@ +/* + * 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 OpenMetaverse.Messages.Linden; +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 OSD = OpenMetaverse.StructuredData.OSD; +using OSDMap = OpenMetaverse.StructuredData.OSDMap; +using OpenSim.Framework.Capabilities; +using ExtraParamType = OpenMetaverse.ExtraParamType; + +namespace OpenSim.Region.CoreModules.Capabilities +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class UploadObjectAssetModule : INonSharedRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Scene m_scene; + + #region IRegionModuleBase Members + + + public Type ReplaceableInterface + { + get { return null; } + } + + public void Initialise(IConfigSource source) + { + + } + + 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_scene.EventManager.OnRegisterCaps += RegisterCaps; + } + + #endregion + + + #region IRegionModule Members + + + + public void Close() { } + + public string Name { get { return "UploadObjectAssetModuleModule"; } } + + + public void RegisterCaps(UUID agentID, Caps caps) + { + UUID capID = UUID.Random(); + +// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID); + caps.RegisterHandler("UploadObjectAsset", + new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/", + delegate(Hashtable m_dhttpMethod) + { + return ProcessAdd(m_dhttpMethod, agentID, caps); + })); + /* + caps.RegisterHandler("NewFileAgentInventoryVariablePrice", + + new LLSDStreamhandler("POST", + "/CAPS/" + capID.ToString(), + delegate(LLSDAssetUploadRequest req) + { + return NewAgentInventoryRequest(req,agentID); + })); + */ + + } + + #endregion + + + /// + /// Parses ad request + /// + /// + /// + /// + /// + public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap) + { + Hashtable responsedata = new Hashtable(); + responsedata["int_response_code"] = 400; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "Request wasn't what was expected"; + ScenePresence avatar; + + if (!m_scene.TryGetScenePresence(AgentId, out avatar)) + return responsedata; + + OSDMap r = (OSDMap)OSDParser.Deserialize((string)request["requestbody"]); + UploadObjectAssetMessage message = new UploadObjectAssetMessage(); + try + { + message.Deserialize(r); + + } + catch (Exception ex) + { + m_log.Error("[UPLOAD OBJECT ASSET MODULE]: Error deserializing message " + ex.ToString()); + message = null; + } + + if (message == null) + { + responsedata["int_response_code"] = 400; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = + "errorError parsing Object"; + + return responsedata; + } + + Vector3 pos = avatar.AbsolutePosition + (Vector3.UnitX * avatar.Rotation); + Quaternion rot = Quaternion.Identity; + Vector3 rootpos = Vector3.Zero; +// Quaternion rootrot = Quaternion.Identity; + + SceneObjectGroup rootGroup = null; + SceneObjectGroup[] allparts = new SceneObjectGroup[message.Objects.Length]; + for (int i = 0; i < message.Objects.Length; i++) + { + UploadObjectAssetMessage.Object obj = message.Objects[i]; + PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); + + if (i == 0) + { + rootpos = obj.Position; +// rootrot = obj.Rotation; + } + + // Combine the extraparams data into it's ugly blob again.... + //int bytelength = 0; + //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) + //{ + // bytelength += obj.ExtraParams[extparams].ExtraParamData.Length; + //} + //byte[] extraparams = new byte[bytelength]; + //int position = 0; + + + + //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) + //{ + // Buffer.BlockCopy(obj.ExtraParams[extparams].ExtraParamData, 0, extraparams, position, + // obj.ExtraParams[extparams].ExtraParamData.Length); + // + // position += obj.ExtraParams[extparams].ExtraParamData.Length; + // } + + //pbs.ExtraParams = extraparams; + for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) + { + UploadObjectAssetMessage.Object.ExtraParam extraParam = obj.ExtraParams[extparams]; + switch ((ushort)extraParam.Type) + { + case (ushort)ExtraParamType.Sculpt: + Primitive.SculptData sculpt = new Primitive.SculptData(extraParam.ExtraParamData, 0); + + pbs.SculptEntry = true; + + pbs.SculptTexture = obj.SculptID; + pbs.SculptType = (byte)sculpt.Type; + + break; + case (ushort)ExtraParamType.Flexible: + Primitive.FlexibleData flex = new Primitive.FlexibleData(extraParam.ExtraParamData, 0); + pbs.FlexiEntry = true; + pbs.FlexiDrag = flex.Drag; + pbs.FlexiForceX = flex.Force.X; + pbs.FlexiForceY = flex.Force.Y; + pbs.FlexiForceZ = flex.Force.Z; + pbs.FlexiGravity = flex.Gravity; + pbs.FlexiSoftness = flex.Softness; + pbs.FlexiTension = flex.Tension; + pbs.FlexiWind = flex.Wind; + break; + case (ushort)ExtraParamType.Light: + Primitive.LightData light = new Primitive.LightData(extraParam.ExtraParamData, 0); + pbs.LightColorA = light.Color.A; + pbs.LightColorB = light.Color.B; + pbs.LightColorG = light.Color.G; + pbs.LightColorR = light.Color.R; + pbs.LightCutoff = light.Cutoff; + pbs.LightEntry = true; + pbs.LightFalloff = light.Falloff; + pbs.LightIntensity = light.Intensity; + pbs.LightRadius = light.Radius; + break; + case 0x40: + pbs.ReadProjectionData(extraParam.ExtraParamData, 0); + break; + + } + + + } + pbs.PathBegin = (ushort) obj.PathBegin; + pbs.PathCurve = (byte) obj.PathCurve; + pbs.PathEnd = (ushort) obj.PathEnd; + pbs.PathRadiusOffset = (sbyte) obj.RadiusOffset; + pbs.PathRevolutions = (byte) obj.Revolutions; + pbs.PathScaleX = (byte) obj.ScaleX; + pbs.PathScaleY = (byte) obj.ScaleY; + pbs.PathShearX = (byte) obj.ShearX; + pbs.PathShearY = (byte) obj.ShearY; + pbs.PathSkew = (sbyte) obj.Skew; + pbs.PathTaperX = (sbyte) obj.TaperX; + pbs.PathTaperY = (sbyte) obj.TaperY; + pbs.PathTwist = (sbyte) obj.Twist; + pbs.PathTwistBegin = (sbyte) obj.TwistBegin; + pbs.HollowShape = (HollowShape) obj.ProfileHollow; + pbs.PCode = (byte) PCode.Prim; + pbs.ProfileBegin = (ushort) obj.ProfileBegin; + pbs.ProfileCurve = (byte) obj.ProfileCurve; + pbs.ProfileEnd = (ushort) obj.ProfileEnd; + pbs.Scale = obj.Scale; + pbs.State = (byte) 0; + SceneObjectPart prim = new SceneObjectPart(); + prim.UUID = UUID.Random(); + prim.CreatorID = AgentId; + prim.OwnerID = AgentId; + prim.GroupID = obj.GroupID; + prim.LastOwnerID = prim.OwnerID; + prim.CreationDate = Util.UnixTimeSinceEpoch(); + prim.Name = obj.Name; + prim.Description = ""; + + prim.PayPrice[0] = -2; + prim.PayPrice[1] = -2; + prim.PayPrice[2] = -2; + prim.PayPrice[3] = -2; + prim.PayPrice[4] = -2; + Primitive.TextureEntry tmp = + new Primitive.TextureEntry(UUID.Parse("89556747-24cb-43ed-920b-47caed15465f")); + + for (int j = 0; j < obj.Faces.Length; j++) + { + UploadObjectAssetMessage.Object.Face face = obj.Faces[j]; + + Primitive.TextureEntryFace primFace = tmp.CreateFace((uint) j); + + primFace.Bump = face.Bump; + primFace.RGBA = face.Color; + primFace.Fullbright = face.Fullbright; + primFace.Glow = face.Glow; + primFace.TextureID = face.ImageID; + primFace.Rotation = face.ImageRot; + primFace.MediaFlags = ((face.MediaFlags & 1) != 0); + + primFace.OffsetU = face.OffsetS; + primFace.OffsetV = face.OffsetT; + primFace.RepeatU = face.ScaleS; + primFace.RepeatV = face.ScaleT; + primFace.TexMapType = (MappingType) (face.MediaFlags & 6); + } + pbs.TextureEntry = tmp.GetBytes(); + prim.Shape = pbs; + prim.Scale = obj.Scale; + + + SceneObjectGroup grp = new SceneObjectGroup(); + + grp.SetRootPart(prim); + prim.ParentID = 0; + if (i == 0) + { + rootGroup = grp; + + } + grp.AttachToScene(m_scene); + grp.AbsolutePosition = obj.Position; + prim.RotationOffset = obj.Rotation; + + grp.RootPart.IsAttachment = false; + // Required for linking + grp.RootPart.UpdateFlag = 0; + + if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos)) + { + m_scene.AddSceneObject(grp); + grp.AbsolutePosition = obj.Position; + } + allparts[i] = grp; + + } + + for (int j = 1; j < allparts.Length; j++) + { + rootGroup.RootPart.UpdateFlag = 0; + allparts[j].RootPart.UpdateFlag = 0; + rootGroup.LinkToGroup(allparts[j]); + } + + rootGroup.ScheduleGroupForFullUpdate(); + pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false); + + responsedata["int_response_code"] = 200; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = String.Format("local_id{0}", ConvertUintToBytes(allparts[0].LocalId)); + + return responsedata; + } + + private string ConvertUintToBytes(uint val) + { + byte[] resultbytes = Utils.UIntToBytes(val); + if (BitConverter.IsLittleEndian) + Array.Reverse(resultbytes); + return String.Format("{0}", Convert.ToBase64String(resultbytes)); + } + } +} \ No newline at end of file -- cgit v1.1