From e3c27d852720ad8b743952ab4aac3b2648468a11 Mon Sep 17 00:00:00 2001
From: Diva Canto
Date: Sat, 30 Apr 2011 13:24:25 -0700
Subject: Nope, that didn't feel right. Moving all those modules to Linden
space.
---
.../ClientStack/Linden/Caps/CapabilitiesModule.cs | 257 +++++++++++++
.../Linden/Caps/EventQueue/EventQueueGetModule.cs | 2 +
.../ClientStack/Linden/Caps/GetMeshModule.cs | 211 +++++++++++
.../ClientStack/Linden/Caps/GetTextureModule.cs | 404 +++++++++++++++++++++
.../NewFileAgentInventoryVariablePriceModule.cs | 275 ++++++++++++++
.../Linden/Caps/ObjectCaps/ObjectAdd.cs | 370 +++++++++++++++++++
.../Caps/ObjectCaps/UploadObjectAssetModule.cs | 374 +++++++++++++++++++
7 files changed, 1893 insertions(+)
create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs
create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
create mode 100644 OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs
new file mode 100644
index 0000000..b136555
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs
@@ -0,0 +1,257 @@
+/*
+ * 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 Mono.Addins;
+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.ClientStack.Linden
+{
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
+ 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/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index fe97bf2..4827baa 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -33,6 +33,7 @@ using System.Reflection;
using System.Threading;
using log4net;
using Nini.Config;
+using Mono.Addins;
using OpenMetaverse;
using OpenMetaverse.Messages.Linden;
using OpenMetaverse.Packets;
@@ -53,6 +54,7 @@ namespace OpenSim.Region.ClientStack.Linden
public OSDMap body;
}
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class EventQueueGetModule : IEventQueue, IRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
new file mode 100644
index 0000000..1d57143
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/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.ClientStack.Linden
+{
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
+ public class GetMeshModule : INonSharedRegionModule
+ {
+// private static readonly ILog m_log =
+// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private Scene m_scene;
+ private IAssetService m_assetService;
+ private bool m_enabled = true;
+
+ #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/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
new file mode 100644
index 0000000..58dbc14
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Reflection;
+using System.IO;
+using System.Web;
+using log4net;
+using Nini.Config;
+using Mono.Addins;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using OpenMetaverse.Imaging;
+using OpenSim.Framework;
+using OpenSim.Framework.Servers;
+using OpenSim.Framework.Servers.HttpServer;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Services.Interfaces;
+using Caps = OpenSim.Framework.Capabilities.Caps;
+
+namespace OpenSim.Region.ClientStack.Linden
+{
+ #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
+
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
+ 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/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
new file mode 100644
index 0000000..eddc288
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/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.ClientStack.Linden
+{
+ [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/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
new file mode 100644
index 0000000..15139a3
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/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.ClientStack.Linden
+{
+ 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("",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/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
new file mode 100644
index 0000000..3809f84
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/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.ClientStack.Linden
+{
+ [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"] =
+ "";
+
+ 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("", 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