aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/CapabilitiesModule.cs257
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs211
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs404
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs275
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs370
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs374
7 files changed, 1893 insertions, 0 deletions
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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using Mono.Addins;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Framework.Console;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using Caps=OpenSim.Framework.Capabilities.Caps;
41
42namespace OpenSim.Region.ClientStack.Linden
43{
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
45 public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule
46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 protected Scene m_scene;
50
51 /// <summary>
52 /// Each agent has its own capabilities handler.
53 /// </summary>
54 protected Dictionary<UUID, Caps> m_capsHandlers = new Dictionary<UUID, Caps>();
55
56 protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>();
57 protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds
58 = new Dictionary<UUID, Dictionary<ulong, string>>();
59
60 public void Initialise(IConfigSource source)
61 {
62 }
63
64 public void AddRegion(Scene scene)
65 {
66 m_scene = scene;
67 m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
68 MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
69 "show capabilities",
70 "Shows all registered capabilities", CapabilitiesCommand);
71 }
72
73 public void RegionLoaded(Scene scene)
74 {
75 }
76
77 public void RemoveRegion(Scene scene)
78 {
79 m_scene.UnregisterModuleInterface<ICapabilitiesModule>(this);
80 }
81
82 public void PostInitialise()
83 {
84 }
85
86 public void Close() {}
87
88 public string Name
89 {
90 get { return "Capabilities Module"; }
91 }
92
93 public Type ReplaceableInterface
94 {
95 get { return null; }
96 }
97
98 public void AddCapsHandler(UUID agentId)
99 {
100 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId))
101 return;
102
103 String capsObjectPath = GetCapsPath(agentId);
104
105 if (m_capsHandlers.ContainsKey(agentId))
106 {
107 Caps oldCaps = m_capsHandlers[agentId];
108
109 m_log.DebugFormat(
110 "[CAPS]: Reregistering caps for agent {0}. Old caps path {1}, new caps path {2}. ",
111 agentId, oldCaps.CapsObjectPath, capsObjectPath);
112 // This should not happen. The caller code is confused. We need to fix that.
113 // CAPs can never be reregistered, or the client will be confused.
114 // Hence this return here.
115 //return;
116 }
117
118 Caps caps
119 = new Caps(m_scene,
120 m_scene.AssetService, MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
121 (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
122 capsObjectPath, agentId, m_scene.DumpAssetsToFile, m_scene.RegionInfo.RegionName);
123
124 caps.RegisterHandlers();
125
126 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
127
128 caps.AddNewInventoryItem = m_scene.AddUploadedInventoryItem;
129 caps.ItemUpdatedCall = m_scene.CapsUpdateInventoryItemAsset;
130 caps.TaskScriptUpdatedCall = m_scene.CapsUpdateTaskInventoryScriptAsset;
131 caps.CAPSFetchInventoryDescendents = m_scene.HandleFetchInventoryDescendentsCAPS;
132 caps.GetClient = m_scene.SceneContents.GetControllingClient;
133
134 m_capsHandlers[agentId] = caps;
135 }
136
137 public void RemoveCapsHandler(UUID agentId)
138 {
139 if (childrenSeeds.ContainsKey(agentId))
140 {
141 childrenSeeds.Remove(agentId);
142 }
143
144 lock (m_capsHandlers)
145 {
146 if (m_capsHandlers.ContainsKey(agentId))
147 {
148 m_capsHandlers[agentId].DeregisterHandlers();
149 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsHandlers[agentId]);
150 m_capsHandlers.Remove(agentId);
151 }
152 else
153 {
154 m_log.WarnFormat(
155 "[CAPS]: Received request to remove CAPS handler for root agent {0} in {1}, but no such CAPS handler found!",
156 agentId, m_scene.RegionInfo.RegionName);
157 }
158 }
159 }
160
161 public Caps GetCapsHandlerForUser(UUID agentId)
162 {
163 lock (m_capsHandlers)
164 {
165 if (m_capsHandlers.ContainsKey(agentId))
166 {
167 return m_capsHandlers[agentId];
168 }
169 }
170
171 return null;
172 }
173
174 public void NewUserConnection(AgentCircuitData agent)
175 {
176 capsPaths[agent.AgentID] = agent.CapsPath;
177 childrenSeeds[agent.AgentID]
178 = ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds);
179 }
180
181 public string GetCapsPath(UUID agentId)
182 {
183 if (capsPaths.ContainsKey(agentId))
184 {
185 return capsPaths[agentId];
186 }
187
188 return null;
189 }
190
191 public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID)
192 {
193 Dictionary<ulong, string> seeds = null;
194 if (childrenSeeds.TryGetValue(agentID, out seeds))
195 return seeds;
196 return new Dictionary<ulong, string>();
197 }
198
199 public void DropChildSeed(UUID agentID, ulong handle)
200 {
201 Dictionary<ulong, string> seeds;
202 if (childrenSeeds.TryGetValue(agentID, out seeds))
203 {
204 seeds.Remove(handle);
205 }
206 }
207
208 public string GetChildSeed(UUID agentID, ulong handle)
209 {
210 Dictionary<ulong, string> seeds;
211 string returnval;
212 if (childrenSeeds.TryGetValue(agentID, out seeds))
213 {
214 if (seeds.TryGetValue(handle, out returnval))
215 return returnval;
216 }
217 return null;
218 }
219
220 public void SetChildrenSeed(UUID agentID, Dictionary<ulong, string> seeds)
221 {
222 //m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count);
223 childrenSeeds[agentID] = seeds;
224 }
225
226 public void DumpChildrenSeeds(UUID agentID)
227 {
228 m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================");
229 foreach (KeyValuePair<ulong, string> kvp in childrenSeeds[agentID])
230 {
231 uint x, y;
232 Utils.LongToUInts(kvp.Key, out x, out y);
233 x = x / Constants.RegionSize;
234 y = y / Constants.RegionSize;
235 m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
236 }
237 }
238
239 private void CapabilitiesCommand(string module, string[] cmdparams)
240 {
241 System.Text.StringBuilder caps = new System.Text.StringBuilder();
242 caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
243
244 foreach (KeyValuePair<UUID, Caps> kvp in m_capsHandlers)
245 {
246 caps.AppendFormat("** User {0}:\n", kvp.Key);
247 for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.CapsDetails.GetEnumerator(); kvp2.MoveNext(); )
248 {
249 Uri uri = new Uri(kvp2.Value.ToString());
250 caps.AppendFormat(" {0} = {1}\n", kvp2.Key, uri.PathAndQuery);
251 }
252 }
253
254 MainConsole.Instance.Output(caps.ToString());
255 }
256 }
257}
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;
33using System.Threading; 33using System.Threading;
34using log4net; 34using log4net;
35using Nini.Config; 35using Nini.Config;
36using Mono.Addins;
36using OpenMetaverse; 37using OpenMetaverse;
37using OpenMetaverse.Messages.Linden; 38using OpenMetaverse.Messages.Linden;
38using OpenMetaverse.Packets; 39using OpenMetaverse.Packets;
@@ -53,6 +54,7 @@ namespace OpenSim.Region.ClientStack.Linden
53 public OSDMap body; 54 public OSDMap body;
54 } 55 }
55 56
57 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
56 public class EventQueueGetModule : IEventQueue, IRegionModule 58 public class EventQueueGetModule : IEventQueue, IRegionModule
57 { 59 {
58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 60 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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Specialized;
31using System.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Services.Interfaces;
45using Caps = OpenSim.Framework.Capabilities.Caps;
46
47namespace OpenSim.Region.ClientStack.Linden
48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
50 public class GetMeshModule : INonSharedRegionModule
51 {
52// private static readonly ILog m_log =
53// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private Scene m_scene;
56 private IAssetService m_assetService;
57 private bool m_enabled = true;
58
59 #region IRegionModuleBase Members
60
61
62 public Type ReplaceableInterface
63 {
64 get { return null; }
65 }
66
67 public void Initialise(IConfigSource source)
68 {
69 IConfig meshConfig = source.Configs["Mesh"];
70 if (meshConfig == null)
71 return;
72
73 m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
74 }
75
76 public void AddRegion(Scene pScene)
77 {
78 m_scene = pScene;
79 }
80
81 public void RemoveRegion(Scene scene)
82 {
83
84 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
85 m_scene = null;
86 }
87
88 public void RegionLoaded(Scene scene)
89 {
90
91 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
92 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
93 }
94
95 #endregion
96
97
98 #region IRegionModule Members
99
100
101
102 public void Close() { }
103
104 public string Name { get { return "GetMeshModule"; } }
105
106
107 public void RegisterCaps(UUID agentID, Caps caps)
108 {
109 if(!m_enabled)
110 return;
111
112 UUID capID = UUID.Random();
113
114// m_log.Info("[GETMESH]: /CAPS/" + capID);
115
116 caps.RegisterHandler("GetMesh",
117 new RestHTTPHandler("GET", "/CAPS/" + capID,
118 delegate(Hashtable m_dhttpMethod)
119 {
120 return ProcessGetMesh(m_dhttpMethod, agentID, caps);
121 }));
122 }
123
124 #endregion
125
126 public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
127 {
128
129 Hashtable responsedata = new Hashtable();
130 responsedata["int_response_code"] = 400; //501; //410; //404;
131 responsedata["content_type"] = "text/plain";
132 responsedata["keepalive"] = false;
133 responsedata["str_response_string"] = "Request wasn't what was expected";
134
135 string meshStr = string.Empty;
136
137 if (request.ContainsKey("mesh_id"))
138 meshStr = request["mesh_id"].ToString();
139
140
141 UUID meshID = UUID.Zero;
142 if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
143 {
144 if (m_assetService == null)
145 {
146 responsedata["int_response_code"] = 404; //501; //410; //404;
147 responsedata["content_type"] = "text/plain";
148 responsedata["keepalive"] = false;
149 responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh.";
150 return responsedata;
151 }
152
153 AssetBase mesh;
154 // Only try to fetch locally cached textures. Misses are redirected
155 mesh = m_assetService.GetCached(meshID.ToString());
156 if (mesh != null)
157 {
158 if (mesh.Type == (SByte)AssetType.Mesh)
159 {
160 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
161 responsedata["content_type"] = "application/vnd.ll.mesh";
162 responsedata["int_response_code"] = 200;
163 }
164 // Optionally add additional mesh types here
165 else
166 {
167 responsedata["int_response_code"] = 404; //501; //410; //404;
168 responsedata["content_type"] = "text/plain";
169 responsedata["keepalive"] = false;
170 responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
171 return responsedata;
172 }
173 }
174 else
175 {
176 mesh = m_assetService.Get(meshID.ToString());
177 if (mesh != null)
178 {
179 if (mesh.Type == (SByte)AssetType.Mesh)
180 {
181 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
182 responsedata["content_type"] = "application/vnd.ll.mesh";
183 responsedata["int_response_code"] = 200;
184 }
185 // Optionally add additional mesh types here
186 else
187 {
188 responsedata["int_response_code"] = 404; //501; //410; //404;
189 responsedata["content_type"] = "text/plain";
190 responsedata["keepalive"] = false;
191 responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
192 return responsedata;
193 }
194 }
195
196 else
197 {
198 responsedata["int_response_code"] = 404; //501; //410; //404;
199 responsedata["content_type"] = "text/plain";
200 responsedata["keepalive"] = false;
201 responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
202 return responsedata;
203 }
204 }
205
206 }
207
208 return responsedata;
209 }
210 }
211}
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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Specialized;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection;
34using System.IO;
35using System.Web;
36using log4net;
37using Nini.Config;
38using Mono.Addins;
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenMetaverse.Imaging;
42using OpenSim.Framework;
43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Services.Interfaces;
48using Caps = OpenSim.Framework.Capabilities.Caps;
49
50namespace OpenSim.Region.ClientStack.Linden
51{
52 #region Stream Handler
53
54 public delegate byte[] StreamHandlerCallback(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse);
55
56 public class StreamHandler : BaseStreamHandler
57 {
58 StreamHandlerCallback m_callback;
59
60 public StreamHandler(string httpMethod, string path, StreamHandlerCallback callback)
61 : base(httpMethod, path)
62 {
63 m_callback = callback;
64 }
65
66 public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
67 {
68 return m_callback(path, request, httpRequest, httpResponse);
69 }
70 }
71
72 #endregion Stream Handler
73
74 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
75 public class GetTextureModule : IRegionModule
76 {
77 private static readonly ILog m_log =
78 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
79 private Scene m_scene;
80 private IAssetService m_assetService;
81
82 public const string DefaultFormat = "x-j2c";
83
84 // TODO: Change this to a config option
85 const string REDIRECT_URL = null;
86
87
88 #region IRegionModule Members
89
90 public void Initialise(Scene pScene, IConfigSource pSource)
91 {
92 m_scene = pScene;
93 }
94
95 public void PostInitialise()
96 {
97 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
98 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
99 }
100
101 public void Close() { }
102
103 public string Name { get { return "GetTextureModule"; } }
104 public bool IsSharedModule { get { return false; } }
105
106 public void RegisterCaps(UUID agentID, Caps caps)
107 {
108 UUID capID = UUID.Random();
109
110// m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
111 caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
112 }
113
114 #endregion
115
116 private byte[] ProcessGetTexture(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
117 {
118 //m_log.DebugFormat("[GETTEXTURE]: called in {0}", m_scene.RegionInfo.RegionName);
119
120 // Try to parse the texture ID from the request URL
121 NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
122 string textureStr = query.GetOne("texture_id");
123 string format = query.GetOne("format");
124
125 if (m_assetService == null)
126 {
127 m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
128 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
129 return null;
130 }
131
132 UUID textureID;
133 if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
134 {
135 string[] formats;
136 if (format != null && format != string.Empty)
137 {
138 formats = new string[1] { format.ToLower() };
139 }
140 else
141 {
142 formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
143 if (formats.Length == 0)
144 formats = new string[1] { DefaultFormat }; // default
145
146 }
147 // OK, we have an array with preferred formats, possibly with only one entry
148
149 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
150 foreach (string f in formats)
151 {
152 if (FetchTexture(httpRequest, httpResponse, textureID, f))
153 break;
154 }
155
156 }
157 else
158 {
159 m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
160 }
161
162 httpResponse.Send();
163 return null;
164 }
165
166 /// <summary>
167 ///
168 /// </summary>
169 /// <param name="httpRequest"></param>
170 /// <param name="httpResponse"></param>
171 /// <param name="textureID"></param>
172 /// <param name="format"></param>
173 /// <returns>False for "caller try another codec"; true otherwise</returns>
174 private bool FetchTexture(OSHttpRequest httpRequest, OSHttpResponse httpResponse, UUID textureID, string format)
175 {
176// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
177 AssetBase texture;
178
179 string fullID = textureID.ToString();
180 if (format != DefaultFormat)
181 fullID = fullID + "-" + format;
182
183 if (!String.IsNullOrEmpty(REDIRECT_URL))
184 {
185 // Only try to fetch locally cached textures. Misses are redirected
186 texture = m_assetService.GetCached(fullID);
187
188 if (texture != null)
189 {
190 if (texture.Type != (sbyte)AssetType.Texture)
191 {
192 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
193 return true;
194 }
195 WriteTextureData(httpRequest, httpResponse, texture, format);
196 }
197 else
198 {
199 string textureUrl = REDIRECT_URL + textureID.ToString();
200 m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
201 httpResponse.RedirectLocation = textureUrl;
202 return true;
203 }
204 }
205 else // no redirect
206 {
207 // try the cache
208 texture = m_assetService.GetCached(fullID);
209
210 if (texture == null)
211 {
212 //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
213
214 // Fetch locally or remotely. Misses return a 404
215 texture = m_assetService.Get(textureID.ToString());
216
217 if (texture != null)
218 {
219 if (texture.Type != (sbyte)AssetType.Texture)
220 {
221 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
222 return true;
223 }
224 if (format == DefaultFormat)
225 {
226 WriteTextureData(httpRequest, httpResponse, texture, format);
227 return true;
228 }
229 else
230 {
231 AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
232 newTexture.Data = ConvertTextureData(texture, format);
233 if (newTexture.Data.Length == 0)
234 return false; // !!! Caller try another codec, please!
235
236 newTexture.Flags = AssetFlags.Collectable;
237 newTexture.Temporary = true;
238 m_assetService.Store(newTexture);
239 WriteTextureData(httpRequest, httpResponse, newTexture, format);
240 return true;
241 }
242 }
243 }
244 else // it was on the cache
245 {
246 //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
247 WriteTextureData(httpRequest, httpResponse, texture, format);
248 return true;
249 }
250 }
251
252 // not found
253// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
254 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
255 return true;
256 }
257
258 private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)
259 {
260 string range = request.Headers.GetOne("Range");
261 //m_log.DebugFormat("[GETTEXTURE]: Range {0}", range);
262 if (!String.IsNullOrEmpty(range)) // JP2's only
263 {
264 // Range request
265 int start, end;
266 if (TryParseRange(range, out start, out end))
267 {
268 // Before clamping start make sure we can satisfy it in order to avoid
269 // sending back the last byte instead of an error status
270 if (start >= texture.Data.Length)
271 {
272 response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
273 return;
274 }
275
276 end = Utils.Clamp(end, 0, texture.Data.Length - 1);
277 start = Utils.Clamp(start, 0, end);
278 int len = end - start + 1;
279
280 //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
281
282 if (len < texture.Data.Length)
283 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
284
285 response.ContentLength = len;
286 response.ContentType = texture.Metadata.ContentType;
287 response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
288
289 response.Body.Write(texture.Data, start, len);
290 }
291 else
292 {
293 m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
294 response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
295 }
296 }
297 else // JP2's or other formats
298 {
299 // Full content request
300 response.StatusCode = (int)System.Net.HttpStatusCode.OK;
301 response.ContentLength = texture.Data.Length;
302 if (format == DefaultFormat)
303 response.ContentType = texture.Metadata.ContentType;
304 else
305 response.ContentType = "image/" + format;
306 response.Body.Write(texture.Data, 0, texture.Data.Length);
307 }
308 }
309
310 private bool TryParseRange(string header, out int start, out int end)
311 {
312 if (header.StartsWith("bytes="))
313 {
314 string[] rangeValues = header.Substring(6).Split('-');
315 if (rangeValues.Length == 2)
316 {
317 if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end))
318 return true;
319 }
320 }
321
322 start = end = 0;
323 return false;
324 }
325
326
327 private byte[] ConvertTextureData(AssetBase texture, string format)
328 {
329 m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
330 byte[] data = new byte[0];
331
332 MemoryStream imgstream = new MemoryStream();
333 Bitmap mTexture = new Bitmap(1, 1);
334 ManagedImage managedImage;
335 Image image = (Image)mTexture;
336
337 try
338 {
339 // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
340
341 imgstream = new MemoryStream();
342
343 // Decode image to System.Drawing.Image
344 if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image))
345 {
346 // Save to bitmap
347 mTexture = new Bitmap(image);
348
349 EncoderParameters myEncoderParameters = new EncoderParameters();
350 myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L);
351
352 // Save bitmap to stream
353 ImageCodecInfo codec = GetEncoderInfo("image/" + format);
354 if (codec != null)
355 {
356 mTexture.Save(imgstream, codec, myEncoderParameters);
357 // Write the stream to a byte array for output
358 data = imgstream.ToArray();
359 }
360 else
361 m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
362
363 }
364 }
365 catch (Exception e)
366 {
367 m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message);
368 }
369 finally
370 {
371 // Reclaim memory, these are unmanaged resources
372 // If we encountered an exception, one or more of these will be null
373 if (mTexture != null)
374 mTexture.Dispose();
375
376 if (image != null)
377 image.Dispose();
378
379 if (imgstream != null)
380 {
381 imgstream.Close();
382 imgstream.Dispose();
383 }
384 }
385
386 return data;
387 }
388
389 // From msdn
390 private static ImageCodecInfo GetEncoderInfo(String mimeType)
391 {
392 ImageCodecInfo[] encoders;
393 encoders = ImageCodecInfo.GetImageEncoders();
394 for (int j = 0; j < encoders.Length; ++j)
395 {
396 if (encoders[j].MimeType == mimeType)
397 return encoders[j];
398 }
399 return null;
400 }
401
402
403 }
404}
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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Specialized;
31using System.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Services.Interfaces;
45using Caps = OpenSim.Framework.Capabilities.Caps;
46using OpenSim.Framework.Capabilities;
47
48namespace OpenSim.Region.ClientStack.Linden
49{
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
51 public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
52 {
53// private static readonly ILog m_log =
54// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Scene m_scene;
57// private IAssetService m_assetService;
58 private bool m_dumpAssetsToFile = false;
59 private bool m_enabled = true;
60
61 #region IRegionModuleBase Members
62
63
64 public Type ReplaceableInterface
65 {
66 get { return null; }
67 }
68
69 public void Initialise(IConfigSource source)
70 {
71 IConfig meshConfig = source.Configs["Mesh"];
72 if (meshConfig == null)
73 return;
74
75 m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
76 }
77
78 public void AddRegion(Scene pScene)
79 {
80 m_scene = pScene;
81 }
82
83 public void RemoveRegion(Scene scene)
84 {
85
86 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
87 m_scene = null;
88 }
89
90 public void RegionLoaded(Scene scene)
91 {
92
93// m_assetService = m_scene.RequestModuleInterface<IAssetService>();
94 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
95 }
96
97 #endregion
98
99
100 #region IRegionModule Members
101
102
103
104 public void Close() { }
105
106 public string Name { get { return "NewFileAgentInventoryVariablePriceModule"; } }
107
108
109 public void RegisterCaps(UUID agentID, Caps caps)
110 {
111 if(!m_enabled)
112 return;
113
114 UUID capID = UUID.Random();
115
116// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
117 caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
118
119 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
120 "/CAPS/" + capID.ToString(),
121 delegate(LLSDAssetUploadRequest req)
122 {
123 return NewAgentInventoryRequest(req,agentID);
124 }));
125
126 }
127
128 #endregion
129
130 public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
131 {
132
133 //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
134 // You need to be aware of this and
135
136
137 //if (llsdRequest.asset_type == "texture" ||
138 // llsdRequest.asset_type == "animation" ||
139 // llsdRequest.asset_type == "sound")
140 // {
141 IClientAPI client = null;
142
143
144 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
145
146 if (mm != null)
147 {
148 if (m_scene.TryGetClient(agentID, out client))
149 {
150 if (!mm.UploadCovered(client, mm.UploadCharge))
151 {
152 if (client != null)
153 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
154
155 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
156 errorResponse.rsvp = "";
157 errorResponse.state = "error";
158 return errorResponse;
159 }
160 }
161 }
162 // }
163
164
165
166 string assetName = llsdRequest.name;
167 string assetDes = llsdRequest.description;
168 string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/";
169 UUID newAsset = UUID.Random();
170 UUID newInvItem = UUID.Random();
171 UUID parentFolder = llsdRequest.folder_id;
172 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/";
173
174 Caps.AssetUploader uploader =
175 new Caps.AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
176 llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
177 MainServer.Instance.AddStreamHandler(
178 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
179
180 string protocol = "http://";
181
182 if (MainServer.Instance.UseSSL)
183 protocol = "https://";
184
185 string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
186 uploaderPath;
187
188
189 LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
190
191
192 uploadResponse.rsvp = uploaderURL;
193 uploadResponse.state = "upload";
194 uploadResponse.resource_cost = 0;
195 uploadResponse.upload_price = 0;
196
197 uploader.OnUpLoad += //UploadCompleteHandler;
198
199 delegate(
200 string passetName, string passetDescription, UUID passetID,
201 UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType,
202 string passetType)
203 {
204 UploadCompleteHandler(passetName, passetDescription, passetID,
205 pinventoryItem, pparentFolder, pdata, pinventoryType,
206 passetType,agentID);
207 };
208 return uploadResponse;
209 }
210
211
212 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
213 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
214 string assetType,UUID AgentID)
215 {
216
217 sbyte assType = 0;
218 sbyte inType = 0;
219
220 if (inventoryType == "sound")
221 {
222 inType = 1;
223 assType = 1;
224 }
225 else if (inventoryType == "animation")
226 {
227 inType = 19;
228 assType = 20;
229 }
230 else if (inventoryType == "wearable")
231 {
232 inType = 18;
233 switch (assetType)
234 {
235 case "bodypart":
236 assType = 13;
237 break;
238 case "clothing":
239 assType = 5;
240 break;
241 }
242 }
243 else if (inventoryType == "mesh")
244 {
245 inType = (sbyte)InventoryType.Mesh;
246 assType = (sbyte)AssetType.Mesh;
247 }
248
249 AssetBase asset;
250 asset = new AssetBase(assetID, assetName, assType, AgentID.ToString());
251 asset.Data = data;
252
253 if (m_scene.AssetService != null)
254 m_scene.AssetService.Store(asset);
255
256 InventoryItemBase item = new InventoryItemBase();
257 item.Owner = AgentID;
258 item.CreatorId = AgentID.ToString();
259 item.ID = inventoryItem;
260 item.AssetID = asset.FullID;
261 item.Description = assetDescription;
262 item.Name = assetName;
263 item.AssetType = assType;
264 item.InvType = inType;
265 item.Folder = parentFolder;
266 item.CurrentPermissions = (uint)PermissionMask.All;
267 item.BasePermissions = (uint)PermissionMask.All;
268 item.EveryOnePermissions = 0;
269 item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
270 item.CreationDate = Util.UnixTimeSinceEpoch();
271 m_scene.AddInventoryItem(item);
272
273 }
274 }
275}
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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using OpenMetaverse.StructuredData;
35using OpenSim.Framework;
36using OpenSim.Framework.Servers;
37using OpenSim.Framework.Servers.HttpServer;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using Caps=OpenSim.Framework.Capabilities.Caps;
41
42namespace OpenSim.Region.ClientStack.Linden
43{
44 public class ObjectAdd : IRegionModule
45 {
46// private static readonly ILog m_log =
47// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private Scene m_scene;
50 #region IRegionModule Members
51
52 public void Initialise(Scene pScene, IConfigSource pSource)
53 {
54 m_scene = pScene;
55 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
56 }
57
58 public void PostInitialise()
59 {
60
61 }
62
63 public void RegisterCaps(UUID agentID, Caps caps)
64 {
65 UUID capuuid = UUID.Random();
66
67// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
68
69 caps.RegisterHandler("ObjectAdd",
70 new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/",
71 delegate(Hashtable m_dhttpMethod)
72 {
73 return ProcessAdd(m_dhttpMethod, agentID, caps);
74 }));
75 }
76
77 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
78 {
79 Hashtable responsedata = new Hashtable();
80 responsedata["int_response_code"] = 400; //501; //410; //404;
81 responsedata["content_type"] = "text/plain";
82 responsedata["keepalive"] = false;
83 responsedata["str_response_string"] = "Request wasn't what was expected";
84 ScenePresence avatar;
85
86 if (!m_scene.TryGetScenePresence(AgentId, out avatar))
87 return responsedata;
88
89
90 OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]);
91 //UUID session_id = UUID.Zero;
92 bool bypass_raycast = false;
93 uint everyone_mask = 0;
94 uint group_mask = 0;
95 uint next_owner_mask = 0;
96 uint flags = 0;
97 UUID group_id = UUID.Zero;
98 int hollow = 0;
99 int material = 0;
100 int p_code = 0;
101 int path_begin = 0;
102 int path_curve = 0;
103 int path_end = 0;
104 int path_radius_offset = 0;
105 int path_revolutions = 0;
106 int path_scale_x = 0;
107 int path_scale_y = 0;
108 int path_shear_x = 0;
109 int path_shear_y = 0;
110 int path_skew = 0;
111 int path_taper_x = 0;
112 int path_taper_y = 0;
113 int path_twist = 0;
114 int path_twist_begin = 0;
115 int profile_begin = 0;
116 int profile_curve = 0;
117 int profile_end = 0;
118 Vector3 ray_end = Vector3.Zero;
119 bool ray_end_is_intersection = false;
120 Vector3 ray_start = Vector3.Zero;
121 UUID ray_target_id = UUID.Zero;
122 Quaternion rotation = Quaternion.Identity;
123 Vector3 scale = Vector3.Zero;
124 int state = 0;
125
126 if (r.Type != OSDType.Map) // not a proper req
127 return responsedata;
128
129 OSDMap rm = (OSDMap)r;
130
131 if (rm.ContainsKey("ObjectData")) //v2
132 {
133 if (rm["ObjectData"].Type != OSDType.Map)
134 {
135 responsedata["str_response_string"] = "Has ObjectData key, but data not in expected format";
136 return responsedata;
137 }
138
139 OSDMap ObjMap = (OSDMap) rm["ObjectData"];
140
141 bypass_raycast = ObjMap["BypassRaycast"].AsBoolean();
142 everyone_mask = readuintval(ObjMap["EveryoneMask"]);
143 flags = readuintval(ObjMap["Flags"]);
144 group_mask = readuintval(ObjMap["GroupMask"]);
145 material = ObjMap["Material"].AsInteger();
146 next_owner_mask = readuintval(ObjMap["NextOwnerMask"]);
147 p_code = ObjMap["PCode"].AsInteger();
148
149 if (ObjMap.ContainsKey("Path"))
150 {
151 if (ObjMap["Path"].Type != OSDType.Map)
152 {
153 responsedata["str_response_string"] = "Has Path key, but data not in expected format";
154 return responsedata;
155 }
156
157 OSDMap PathMap = (OSDMap)ObjMap["Path"];
158 path_begin = PathMap["Begin"].AsInteger();
159 path_curve = PathMap["Curve"].AsInteger();
160 path_end = PathMap["End"].AsInteger();
161 path_radius_offset = PathMap["RadiusOffset"].AsInteger();
162 path_revolutions = PathMap["Revolutions"].AsInteger();
163 path_scale_x = PathMap["ScaleX"].AsInteger();
164 path_scale_y = PathMap["ScaleY"].AsInteger();
165 path_shear_x = PathMap["ShearX"].AsInteger();
166 path_shear_y = PathMap["ShearY"].AsInteger();
167 path_skew = PathMap["Skew"].AsInteger();
168 path_taper_x = PathMap["TaperX"].AsInteger();
169 path_taper_y = PathMap["TaperY"].AsInteger();
170 path_twist = PathMap["Twist"].AsInteger();
171 path_twist_begin = PathMap["TwistBegin"].AsInteger();
172
173 }
174
175 if (ObjMap.ContainsKey("Profile"))
176 {
177 if (ObjMap["Profile"].Type != OSDType.Map)
178 {
179 responsedata["str_response_string"] = "Has Profile key, but data not in expected format";
180 return responsedata;
181 }
182
183 OSDMap ProfileMap = (OSDMap)ObjMap["Profile"];
184
185 profile_begin = ProfileMap["Begin"].AsInteger();
186 profile_curve = ProfileMap["Curve"].AsInteger();
187 profile_end = ProfileMap["End"].AsInteger();
188 hollow = ProfileMap["Hollow"].AsInteger();
189 }
190 ray_end_is_intersection = ObjMap["RayEndIsIntersection"].AsBoolean();
191
192 ray_target_id = ObjMap["RayTargetId"].AsUUID();
193 state = ObjMap["State"].AsInteger();
194 try
195 {
196 ray_end = ((OSDArray) ObjMap["RayEnd"]).AsVector3();
197 ray_start = ((OSDArray) ObjMap["RayStart"]).AsVector3();
198 scale = ((OSDArray) ObjMap["Scale"]).AsVector3();
199 rotation = ((OSDArray)ObjMap["Rotation"]).AsQuaternion();
200 }
201 catch (Exception)
202 {
203 responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
204 return responsedata;
205 }
206
207 if (rm.ContainsKey("AgentData"))
208 {
209 if (rm["AgentData"].Type != OSDType.Map)
210 {
211 responsedata["str_response_string"] = "Has AgentData key, but data not in expected format";
212 return responsedata;
213 }
214
215 OSDMap AgentDataMap = (OSDMap) rm["AgentData"];
216
217 //session_id = AgentDataMap["SessionId"].AsUUID();
218 group_id = AgentDataMap["GroupId"].AsUUID();
219 }
220
221 }
222 else
223 { //v1
224 bypass_raycast = rm["bypass_raycast"].AsBoolean();
225
226 everyone_mask = readuintval(rm["everyone_mask"]);
227 flags = readuintval(rm["flags"]);
228 group_id = rm["group_id"].AsUUID();
229 group_mask = readuintval(rm["group_mask"]);
230 hollow = rm["hollow"].AsInteger();
231 material = rm["material"].AsInteger();
232 next_owner_mask = readuintval(rm["next_owner_mask"]);
233 hollow = rm["hollow"].AsInteger();
234 p_code = rm["p_code"].AsInteger();
235 path_begin = rm["path_begin"].AsInteger();
236 path_curve = rm["path_curve"].AsInteger();
237 path_end = rm["path_end"].AsInteger();
238 path_radius_offset = rm["path_radius_offset"].AsInteger();
239 path_revolutions = rm["path_revolutions"].AsInteger();
240 path_scale_x = rm["path_scale_x"].AsInteger();
241 path_scale_y = rm["path_scale_y"].AsInteger();
242 path_shear_x = rm["path_shear_x"].AsInteger();
243 path_shear_y = rm["path_shear_y"].AsInteger();
244 path_skew = rm["path_skew"].AsInteger();
245 path_taper_x = rm["path_taper_x"].AsInteger();
246 path_taper_y = rm["path_taper_y"].AsInteger();
247 path_twist = rm["path_twist"].AsInteger();
248 path_twist_begin = rm["path_twist_begin"].AsInteger();
249 profile_begin = rm["profile_begin"].AsInteger();
250 profile_curve = rm["profile_curve"].AsInteger();
251 profile_end = rm["profile_end"].AsInteger();
252
253 ray_end_is_intersection = rm["ray_end_is_intersection"].AsBoolean();
254
255 ray_target_id = rm["ray_target_id"].AsUUID();
256
257
258 //session_id = rm["session_id"].AsUUID();
259 state = rm["state"].AsInteger();
260 try
261 {
262 ray_end = ((OSDArray)rm["ray_end"]).AsVector3();
263 ray_start = ((OSDArray)rm["ray_start"]).AsVector3();
264 rotation = ((OSDArray)rm["rotation"]).AsQuaternion();
265 scale = ((OSDArray)rm["scale"]).AsVector3();
266 }
267 catch (Exception)
268 {
269 responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
270 return responsedata;
271 }
272 }
273
274
275
276 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);
277
278 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
279
280 pbs.PathBegin = (ushort)path_begin;
281 pbs.PathCurve = (byte)path_curve;
282 pbs.PathEnd = (ushort)path_end;
283 pbs.PathRadiusOffset = (sbyte)path_radius_offset;
284 pbs.PathRevolutions = (byte)path_revolutions;
285 pbs.PathScaleX = (byte)path_scale_x;
286 pbs.PathScaleY = (byte)path_scale_y;
287 pbs.PathShearX = (byte) path_shear_x;
288 pbs.PathShearY = (byte)path_shear_y;
289 pbs.PathSkew = (sbyte)path_skew;
290 pbs.PathTaperX = (sbyte)path_taper_x;
291 pbs.PathTaperY = (sbyte)path_taper_y;
292 pbs.PathTwist = (sbyte)path_twist;
293 pbs.PathTwistBegin = (sbyte)path_twist_begin;
294 pbs.HollowShape = (HollowShape) hollow;
295 pbs.PCode = (byte)p_code;
296 pbs.ProfileBegin = (ushort) profile_begin;
297 pbs.ProfileCurve = (byte) profile_curve;
298 pbs.ProfileEnd = (ushort)profile_end;
299 pbs.Scale = scale;
300 pbs.State = (byte)state;
301
302 SceneObjectGroup obj = null; ;
303
304 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
305 {
306 // rez ON the ground, not IN the ground
307 // pos.Z += 0.25F;
308
309 obj = m_scene.AddNewPrim(avatar.UUID, group_id, pos, rotation, pbs);
310 }
311
312
313 if (obj == null)
314 return responsedata;
315
316 SceneObjectPart rootpart = obj.RootPart;
317 rootpart.Shape = pbs;
318 rootpart.Flags |= (PrimFlags)flags;
319 rootpart.EveryoneMask = everyone_mask;
320 rootpart.GroupID = group_id;
321 rootpart.GroupMask = group_mask;
322 rootpart.NextOwnerMask = next_owner_mask;
323 rootpart.Material = (byte)material;
324
325
326
327 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
328
329 responsedata["int_response_code"] = 200; //501; //410; //404;
330 responsedata["content_type"] = "text/plain";
331 responsedata["keepalive"] = false;
332 responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>",ConvertUintToBytes(obj.LocalId));
333
334 return responsedata;
335 }
336
337 private uint readuintval(OSD obj)
338 {
339 byte[] tmp = obj.AsBinary();
340 if (BitConverter.IsLittleEndian)
341 Array.Reverse(tmp);
342 return Utils.BytesToUInt(tmp);
343
344 }
345 private string ConvertUintToBytes(uint val)
346 {
347 byte[] resultbytes = Utils.UIntToBytes(val);
348 if (BitConverter.IsLittleEndian)
349 Array.Reverse(resultbytes);
350 return String.Format("<binary encoding=\"base64\">{0}</binary>",Convert.ToBase64String(resultbytes));
351 }
352
353 public void Close()
354 {
355
356 }
357
358 public string Name
359 {
360 get { return "ObjectAddModule"; }
361 }
362
363 public bool IsSharedModule
364 {
365 get { return false; }
366 }
367
368 #endregion
369 }
370}
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 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Specialized;
31using System.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenMetaverse.Messages.Linden;
40using OpenSim.Framework;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Servers.HttpServer;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47using OSD = OpenMetaverse.StructuredData.OSD;
48using OSDMap = OpenMetaverse.StructuredData.OSDMap;
49using OpenSim.Framework.Capabilities;
50using ExtraParamType = OpenMetaverse.ExtraParamType;
51
52namespace OpenSim.Region.ClientStack.Linden
53{
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
55 public class UploadObjectAssetModule : INonSharedRegionModule
56 {
57 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 private Scene m_scene;
60
61 #region IRegionModuleBase Members
62
63
64 public Type ReplaceableInterface
65 {
66 get { return null; }
67 }
68
69 public void Initialise(IConfigSource source)
70 {
71
72 }
73
74 public void AddRegion(Scene pScene)
75 {
76 m_scene = pScene;
77 }
78
79 public void RemoveRegion(Scene scene)
80 {
81
82 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
83 m_scene = null;
84 }
85
86 public void RegionLoaded(Scene scene)
87 {
88
89 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
90 }
91
92 #endregion
93
94
95 #region IRegionModule Members
96
97
98
99 public void Close() { }
100
101 public string Name { get { return "UploadObjectAssetModuleModule"; } }
102
103
104 public void RegisterCaps(UUID agentID, Caps caps)
105 {
106 UUID capID = UUID.Random();
107
108// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
109 caps.RegisterHandler("UploadObjectAsset",
110 new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/",
111 delegate(Hashtable m_dhttpMethod)
112 {
113 return ProcessAdd(m_dhttpMethod, agentID, caps);
114 }));
115 /*
116 caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
117
118 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
119 "/CAPS/" + capID.ToString(),
120 delegate(LLSDAssetUploadRequest req)
121 {
122 return NewAgentInventoryRequest(req,agentID);
123 }));
124 */
125
126 }
127
128 #endregion
129
130
131 /// <summary>
132 /// Parses ad request
133 /// </summary>
134 /// <param name="request"></param>
135 /// <param name="AgentId"></param>
136 /// <param name="cap"></param>
137 /// <returns></returns>
138 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
139 {
140 Hashtable responsedata = new Hashtable();
141 responsedata["int_response_code"] = 400; //501; //410; //404;
142 responsedata["content_type"] = "text/plain";
143 responsedata["keepalive"] = false;
144 responsedata["str_response_string"] = "Request wasn't what was expected";
145 ScenePresence avatar;
146
147 if (!m_scene.TryGetScenePresence(AgentId, out avatar))
148 return responsedata;
149
150 OSDMap r = (OSDMap)OSDParser.Deserialize((string)request["requestbody"]);
151 UploadObjectAssetMessage message = new UploadObjectAssetMessage();
152 try
153 {
154 message.Deserialize(r);
155
156 }
157 catch (Exception ex)
158 {
159 m_log.Error("[UPLOAD OBJECT ASSET MODULE]: Error deserializing message " + ex.ToString());
160 message = null;
161 }
162
163 if (message == null)
164 {
165 responsedata["int_response_code"] = 400; //501; //410; //404;
166 responsedata["content_type"] = "text/plain";
167 responsedata["keepalive"] = false;
168 responsedata["str_response_string"] =
169 "<llsd><map><key>error</key><string>Error parsing Object</string></map></llsd>";
170
171 return responsedata;
172 }
173
174 Vector3 pos = avatar.AbsolutePosition + (Vector3.UnitX * avatar.Rotation);
175 Quaternion rot = Quaternion.Identity;
176 Vector3 rootpos = Vector3.Zero;
177// Quaternion rootrot = Quaternion.Identity;
178
179 SceneObjectGroup rootGroup = null;
180 SceneObjectGroup[] allparts = new SceneObjectGroup[message.Objects.Length];
181 for (int i = 0; i < message.Objects.Length; i++)
182 {
183 UploadObjectAssetMessage.Object obj = message.Objects[i];
184 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
185
186 if (i == 0)
187 {
188 rootpos = obj.Position;
189// rootrot = obj.Rotation;
190 }
191
192 // Combine the extraparams data into it's ugly blob again....
193 //int bytelength = 0;
194 //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
195 //{
196 // bytelength += obj.ExtraParams[extparams].ExtraParamData.Length;
197 //}
198 //byte[] extraparams = new byte[bytelength];
199 //int position = 0;
200
201
202
203 //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
204 //{
205 // Buffer.BlockCopy(obj.ExtraParams[extparams].ExtraParamData, 0, extraparams, position,
206 // obj.ExtraParams[extparams].ExtraParamData.Length);
207 //
208 // position += obj.ExtraParams[extparams].ExtraParamData.Length;
209 // }
210
211 //pbs.ExtraParams = extraparams;
212 for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
213 {
214 UploadObjectAssetMessage.Object.ExtraParam extraParam = obj.ExtraParams[extparams];
215 switch ((ushort)extraParam.Type)
216 {
217 case (ushort)ExtraParamType.Sculpt:
218 Primitive.SculptData sculpt = new Primitive.SculptData(extraParam.ExtraParamData, 0);
219
220 pbs.SculptEntry = true;
221
222 pbs.SculptTexture = obj.SculptID;
223 pbs.SculptType = (byte)sculpt.Type;
224
225 break;
226 case (ushort)ExtraParamType.Flexible:
227 Primitive.FlexibleData flex = new Primitive.FlexibleData(extraParam.ExtraParamData, 0);
228 pbs.FlexiEntry = true;
229 pbs.FlexiDrag = flex.Drag;
230 pbs.FlexiForceX = flex.Force.X;
231 pbs.FlexiForceY = flex.Force.Y;
232 pbs.FlexiForceZ = flex.Force.Z;
233 pbs.FlexiGravity = flex.Gravity;
234 pbs.FlexiSoftness = flex.Softness;
235 pbs.FlexiTension = flex.Tension;
236 pbs.FlexiWind = flex.Wind;
237 break;
238 case (ushort)ExtraParamType.Light:
239 Primitive.LightData light = new Primitive.LightData(extraParam.ExtraParamData, 0);
240 pbs.LightColorA = light.Color.A;
241 pbs.LightColorB = light.Color.B;
242 pbs.LightColorG = light.Color.G;
243 pbs.LightColorR = light.Color.R;
244 pbs.LightCutoff = light.Cutoff;
245 pbs.LightEntry = true;
246 pbs.LightFalloff = light.Falloff;
247 pbs.LightIntensity = light.Intensity;
248 pbs.LightRadius = light.Radius;
249 break;
250 case 0x40:
251 pbs.ReadProjectionData(extraParam.ExtraParamData, 0);
252 break;
253
254 }
255
256
257 }
258 pbs.PathBegin = (ushort) obj.PathBegin;
259 pbs.PathCurve = (byte) obj.PathCurve;
260 pbs.PathEnd = (ushort) obj.PathEnd;
261 pbs.PathRadiusOffset = (sbyte) obj.RadiusOffset;
262 pbs.PathRevolutions = (byte) obj.Revolutions;
263 pbs.PathScaleX = (byte) obj.ScaleX;
264 pbs.PathScaleY = (byte) obj.ScaleY;
265 pbs.PathShearX = (byte) obj.ShearX;
266 pbs.PathShearY = (byte) obj.ShearY;
267 pbs.PathSkew = (sbyte) obj.Skew;
268 pbs.PathTaperX = (sbyte) obj.TaperX;
269 pbs.PathTaperY = (sbyte) obj.TaperY;
270 pbs.PathTwist = (sbyte) obj.Twist;
271 pbs.PathTwistBegin = (sbyte) obj.TwistBegin;
272 pbs.HollowShape = (HollowShape) obj.ProfileHollow;
273 pbs.PCode = (byte) PCode.Prim;
274 pbs.ProfileBegin = (ushort) obj.ProfileBegin;
275 pbs.ProfileCurve = (byte) obj.ProfileCurve;
276 pbs.ProfileEnd = (ushort) obj.ProfileEnd;
277 pbs.Scale = obj.Scale;
278 pbs.State = (byte) 0;
279 SceneObjectPart prim = new SceneObjectPart();
280 prim.UUID = UUID.Random();
281 prim.CreatorID = AgentId;
282 prim.OwnerID = AgentId;
283 prim.GroupID = obj.GroupID;
284 prim.LastOwnerID = prim.OwnerID;
285 prim.CreationDate = Util.UnixTimeSinceEpoch();
286 prim.Name = obj.Name;
287 prim.Description = "";
288
289 prim.PayPrice[0] = -2;
290 prim.PayPrice[1] = -2;
291 prim.PayPrice[2] = -2;
292 prim.PayPrice[3] = -2;
293 prim.PayPrice[4] = -2;
294 Primitive.TextureEntry tmp =
295 new Primitive.TextureEntry(UUID.Parse("89556747-24cb-43ed-920b-47caed15465f"));
296
297 for (int j = 0; j < obj.Faces.Length; j++)
298 {
299 UploadObjectAssetMessage.Object.Face face = obj.Faces[j];
300
301 Primitive.TextureEntryFace primFace = tmp.CreateFace((uint) j);
302
303 primFace.Bump = face.Bump;
304 primFace.RGBA = face.Color;
305 primFace.Fullbright = face.Fullbright;
306 primFace.Glow = face.Glow;
307 primFace.TextureID = face.ImageID;
308 primFace.Rotation = face.ImageRot;
309 primFace.MediaFlags = ((face.MediaFlags & 1) != 0);
310
311 primFace.OffsetU = face.OffsetS;
312 primFace.OffsetV = face.OffsetT;
313 primFace.RepeatU = face.ScaleS;
314 primFace.RepeatV = face.ScaleT;
315 primFace.TexMapType = (MappingType) (face.MediaFlags & 6);
316 }
317 pbs.TextureEntry = tmp.GetBytes();
318 prim.Shape = pbs;
319 prim.Scale = obj.Scale;
320
321
322 SceneObjectGroup grp = new SceneObjectGroup();
323
324 grp.SetRootPart(prim);
325 prim.ParentID = 0;
326 if (i == 0)
327 {
328 rootGroup = grp;
329
330 }
331 grp.AttachToScene(m_scene);
332 grp.AbsolutePosition = obj.Position;
333 prim.RotationOffset = obj.Rotation;
334
335 grp.RootPart.IsAttachment = false;
336 // Required for linking
337 grp.RootPart.UpdateFlag = 0;
338
339 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
340 {
341 m_scene.AddSceneObject(grp);
342 grp.AbsolutePosition = obj.Position;
343 }
344 allparts[i] = grp;
345
346 }
347
348 for (int j = 1; j < allparts.Length; j++)
349 {
350 rootGroup.RootPart.UpdateFlag = 0;
351 allparts[j].RootPart.UpdateFlag = 0;
352 rootGroup.LinkToGroup(allparts[j]);
353 }
354
355 rootGroup.ScheduleGroupForFullUpdate();
356 pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false);
357
358 responsedata["int_response_code"] = 200; //501; //410; //404;
359 responsedata["content_type"] = "text/plain";
360 responsedata["keepalive"] = false;
361 responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>", ConvertUintToBytes(allparts[0].LocalId));
362
363 return responsedata;
364 }
365
366 private string ConvertUintToBytes(uint val)
367 {
368 byte[] resultbytes = Utils.UIntToBytes(val);
369 if (BitConverter.IsLittleEndian)
370 Array.Reverse(resultbytes);
371 return String.Format("<binary encoding=\"base64\">{0}</binary>", Convert.ToBase64String(resultbytes));
372 }
373 }
374} \ No newline at end of file