aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs329
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs58
2 files changed, 379 insertions, 8 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs
new file mode 100644
index 0000000..d5c6e9d
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/ObjectCaps/UploadObjectAssetModule.cs
@@ -0,0 +1,329 @@
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;
50
51namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps
52{
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
54 public class UploadObjectAssetModule : INonSharedRegionModule
55 {
56 private static readonly ILog m_log =
57 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58 private Scene m_scene;
59
60 #region IRegionModuleBase Members
61
62
63 public Type ReplaceableInterface
64 {
65 get { return null; }
66 }
67
68 public void Initialise(IConfigSource source)
69 {
70
71 }
72
73 public void AddRegion(Scene pScene)
74 {
75 m_scene = pScene;
76 }
77
78 public void RemoveRegion(Scene scene)
79 {
80
81 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
82 m_scene = null;
83 }
84
85 public void RegionLoaded(Scene scene)
86 {
87
88 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
89 }
90
91 #endregion
92
93
94 #region IRegionModule Members
95
96
97
98 public void Close() { }
99
100 public string Name { get { return "UploadObjectAssetModuleModule"; } }
101
102
103 public void RegisterCaps(UUID agentID, Caps caps)
104 {
105 UUID capID = UUID.Random();
106
107 m_log.Info("[UploadObjectAssetModule]: /CAPS/" + capID);
108 caps.RegisterHandler("UploadObjectAsset",
109 new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/",
110 delegate(Hashtable m_dhttpMethod)
111 {
112 return ProcessAdd(m_dhttpMethod, agentID, caps);
113 }));
114 /*
115 caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
116
117 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
118 "/CAPS/" + capID.ToString(),
119 delegate(LLSDAssetUploadRequest req)
120 {
121 return NewAgentInventoryRequest(req,agentID);
122 }));
123 */
124
125 }
126
127 #endregion
128
129
130 /// <summary>
131 /// Parses ad request
132 /// </summary>
133 /// <param name="request"></param>
134 /// <param name="AgentId"></param>
135 /// <param name="cap"></param>
136 /// <returns></returns>
137 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
138 {
139 Hashtable responsedata = new Hashtable();
140 responsedata["int_response_code"] = 400; //501; //410; //404;
141 responsedata["content_type"] = "text/plain";
142 responsedata["keepalive"] = false;
143 responsedata["str_response_string"] = "Request wasn't what was expected";
144 ScenePresence avatar;
145
146 if (!m_scene.TryGetScenePresence(AgentId, out avatar))
147 return responsedata;
148
149 OSDMap r = (OSDMap)OSDParser.Deserialize((string)request["requestbody"]);
150 UploadObjectAssetMessage message = new UploadObjectAssetMessage();
151 try
152 {
153 message.Deserialize(r);
154
155 }
156 catch (Exception ex)
157 {
158 m_log.Error("[UploadObjectAssetModule]: Error deserializing message " + ex.ToString());
159 message = null;
160 }
161
162 if (message == null)
163 {
164 responsedata["int_response_code"] = 400; //501; //410; //404;
165 responsedata["content_type"] = "text/plain";
166 responsedata["keepalive"] = false;
167 responsedata["str_response_string"] =
168 "<llsd><map><key>error</key><string>Error parsing Object</string></map></llsd>";
169
170 return responsedata;
171 }
172
173 Vector3 pos = avatar.AbsolutePosition + (Vector3.UnitX * avatar.Rotation);
174 Quaternion rot = Quaternion.Identity;
175 Vector3 rootpos = Vector3.Zero;
176 Quaternion rootrot = Quaternion.Identity;
177
178 SceneObjectGroup rootGroup = null;
179 SceneObjectGroup[] allparts = new SceneObjectGroup[message.Objects.Length];
180 for (int i = 0; i < message.Objects.Length; i++)
181 {
182 UploadObjectAssetMessage.Object obj = message.Objects[i];
183 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
184
185 if (i == 0)
186 {
187 rootpos = obj.Position;
188 rootrot = obj.Rotation;
189
190 }
191 // Combine the extraparams data into it's ugly blob again....
192 int bytelength = 0;
193 for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
194 {
195 bytelength += obj.ExtraParams[extparams].ExtraParamData.Length;
196 }
197 byte[] extraparams = new byte[bytelength];
198 int position = 0;
199
200 for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
201 {
202 Buffer.BlockCopy(obj.ExtraParams[extparams].ExtraParamData, 0, extraparams, position,
203 obj.ExtraParams[extparams].ExtraParamData.Length);
204
205 position += obj.ExtraParams[extparams].ExtraParamData.Length;
206 }
207
208 pbs.ExtraParams = extraparams;
209
210 pbs.PathBegin = (ushort) obj.PathBegin;
211 pbs.PathCurve = (byte) obj.PathCurve;
212 pbs.PathEnd = (ushort) obj.PathEnd;
213 pbs.PathRadiusOffset = (sbyte) obj.RadiusOffset;
214 pbs.PathRevolutions = (byte) obj.Revolutions;
215 pbs.PathScaleX = (byte) obj.ScaleX;
216 pbs.PathScaleY = (byte) obj.ScaleY;
217 pbs.PathShearX = (byte) obj.ShearX;
218 pbs.PathShearY = (byte) obj.ShearY;
219 pbs.PathSkew = (sbyte) obj.Skew;
220 pbs.PathTaperX = (sbyte) obj.TaperX;
221 pbs.PathTaperY = (sbyte) obj.TaperY;
222 pbs.PathTwist = (sbyte) obj.Twist;
223 pbs.PathTwistBegin = (sbyte) obj.TwistBegin;
224 pbs.HollowShape = (HollowShape) obj.ProfileHollow;
225 pbs.PCode = (byte) PCode.Prim;
226 pbs.ProfileBegin = (ushort) obj.ProfileBegin;
227 pbs.ProfileCurve = (byte) obj.ProfileCurve;
228 pbs.ProfileEnd = (ushort) obj.ProfileEnd;
229 pbs.Scale = obj.Scale;
230 pbs.State = (byte) 0;
231 SceneObjectPart prim = new SceneObjectPart();
232 prim.UUID = UUID.Random();
233 prim.CreatorID = AgentId;
234 prim.OwnerID = AgentId;
235 prim.GroupID = obj.GroupID;
236 prim.LastOwnerID = prim.OwnerID;
237 prim.CreationDate = Util.UnixTimeSinceEpoch();
238 prim.Name = obj.Name;
239 prim.Description = "";
240
241 prim.PayPrice[0] = -2;
242 prim.PayPrice[1] = -2;
243 prim.PayPrice[2] = -2;
244 prim.PayPrice[3] = -2;
245 prim.PayPrice[4] = -2;
246 Primitive.TextureEntry tmp =
247 new Primitive.TextureEntry(UUID.Parse("89556747-24cb-43ed-920b-47caed15465f"));
248
249 for (int j = 0; j < obj.Faces.Length; j++)
250 {
251 UploadObjectAssetMessage.Object.Face face = obj.Faces[j];
252
253 Primitive.TextureEntryFace primFace = tmp.CreateFace((uint) j);
254
255 primFace.Bump = face.Bump;
256 primFace.RGBA = face.Color;
257 primFace.Fullbright = face.Fullbright;
258 primFace.Glow = face.Glow;
259 primFace.TextureID = face.ImageID;
260 primFace.Rotation = face.ImageRot;
261 primFace.MediaFlags = ((face.MediaFlags & 1) != 0);
262
263 primFace.OffsetU = face.OffsetS;
264 primFace.OffsetV = face.OffsetT;
265 primFace.RepeatU = face.ScaleS;
266 primFace.RepeatV = face.ScaleT;
267 primFace.TexMapType = (MappingType) (face.MediaFlags & 6);
268 }
269 pbs.TextureEntry = tmp.GetBytes();
270 prim.Shape = pbs;
271 prim.Scale = obj.Scale;
272 prim.Shape.SculptEntry = true;
273 prim.Shape.SculptTexture = obj.SculptID;
274 prim.Shape.SculptType = (byte) SculptType.Mesh;
275
276 SceneObjectGroup grp = new SceneObjectGroup();
277
278 grp.SetRootPart(prim);
279 prim.ParentID = 0;
280 if (i == 0)
281 {
282 rootGroup = grp;
283
284 }
285 grp.AttachToScene(m_scene);
286 grp.AbsolutePosition = obj.Position;
287 prim.RotationOffset = obj.Rotation;
288
289 grp.RootPart.IsAttachment = false;
290 // Required for linking
291 grp.RootPart.UpdateFlag = 0;
292
293 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
294 {
295 m_scene.AddSceneObject(grp);
296 grp.AbsolutePosition = obj.Position;
297 }
298 allparts[i] = grp;
299
300 }
301
302 for (int j = 1; j < allparts.Length; j++)
303 {
304 rootGroup.RootPart.UpdateFlag = 0;
305 allparts[j].RootPart.UpdateFlag = 0;
306 rootGroup.LinkToGroup(allparts[j]);
307 }
308
309 rootGroup.ScheduleGroupForFullUpdate();
310 pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false);
311
312 responsedata["int_response_code"] = 200; //501; //410; //404;
313 responsedata["content_type"] = "text/plain";
314 responsedata["keepalive"] = false;
315 responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>", ConvertUintToBytes(allparts[0].LocalId));
316
317 return responsedata;
318
319
320 }
321 private string ConvertUintToBytes(uint val)
322 {
323 byte[] resultbytes = Utils.UIntToBytes(val);
324 if (BitConverter.IsLittleEndian)
325 Array.Reverse(resultbytes);
326 return String.Format("<binary encoding=\"base64\">{0}</binary>", Convert.ToBase64String(resultbytes));
327 }
328 }
329}
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 7b94a81..044b599 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -318,6 +318,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
318 m_SOPXmlProcessors.Add("CollisionSound", ProcessCollisionSound); 318 m_SOPXmlProcessors.Add("CollisionSound", ProcessCollisionSound);
319 m_SOPXmlProcessors.Add("CollisionSoundVolume", ProcessCollisionSoundVolume); 319 m_SOPXmlProcessors.Add("CollisionSoundVolume", ProcessCollisionSoundVolume);
320 m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl); 320 m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl);
321 m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation);
322 m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem);
321 #endregion 323 #endregion
322 324
323 #region TaskInventoryXmlProcessors initialization 325 #region TaskInventoryXmlProcessors initialization
@@ -663,6 +665,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
663 { 665 {
664 obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty); 666 obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty);
665 } 667 }
668
669 private static void ProcessTextureAnimation(SceneObjectPart obj, XmlTextReader reader)
670 {
671 obj.TextureAnimation = Convert.FromBase64String(reader.ReadElementContentAsString("TextureAnimation", String.Empty));
672 }
673
674 private static void ProcessParticleSystem(SceneObjectPart obj, XmlTextReader reader)
675 {
676 obj.ParticleSystem = Convert.FromBase64String(reader.ReadElementContentAsString("ParticleSystem", String.Empty));
677 }
666 #endregion 678 #endregion
667 679
668 #region TaskInventoryXmlProcessors 680 #region TaskInventoryXmlProcessors
@@ -1128,6 +1140,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1128 writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString()); 1140 writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString());
1129 if (sop.MediaUrl != null) 1141 if (sop.MediaUrl != null)
1130 writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString()); 1142 writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString());
1143 WriteBytes(writer, "TextureAnimation", sop.TextureAnimation);
1144 WriteBytes(writer, "ParticleSystem", sop.ParticleSystem);
1131 1145
1132 writer.WriteEndElement(); 1146 writer.WriteEndElement();
1133 } 1147 }
@@ -1161,6 +1175,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1161 writer.WriteEndElement(); 1175 writer.WriteEndElement();
1162 } 1176 }
1163 1177
1178 static void WriteBytes(XmlTextWriter writer, string name, byte[] data)
1179 {
1180 writer.WriteStartElement(name);
1181 byte[] d;
1182 if (data != null)
1183 d = data;
1184 else
1185 d = Utils.EmptyBytes;
1186 writer.WriteBase64(d, 0, d.Length);
1187 writer.WriteEndElement(); // name
1188
1189 }
1190
1164 static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options) 1191 static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options)
1165 { 1192 {
1166 if (tinv.Count > 0) // otherwise skip this 1193 if (tinv.Count > 0) // otherwise skip this
@@ -1398,9 +1425,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1398 Vector3 vec; 1425 Vector3 vec;
1399 1426
1400 reader.ReadStartElement(name); 1427 reader.ReadStartElement(name);
1401 vec.X = reader.ReadElementContentAsFloat("X", String.Empty); 1428 vec.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // X or x
1402 vec.Y = reader.ReadElementContentAsFloat("Y", String.Empty); 1429 vec.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // Y or Y
1403 vec.Z = reader.ReadElementContentAsFloat("Z", String.Empty); 1430 vec.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // Z or z
1404 reader.ReadEndElement(); 1431 reader.ReadEndElement();
1405 1432
1406 return vec; 1433 return vec;
@@ -1408,13 +1435,28 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1408 1435
1409 static Quaternion ReadQuaternion(XmlTextReader reader, string name) 1436 static Quaternion ReadQuaternion(XmlTextReader reader, string name)
1410 { 1437 {
1411 Quaternion quat; 1438 Quaternion quat = new Quaternion();
1412 1439
1413 reader.ReadStartElement(name); 1440 reader.ReadStartElement(name);
1414 quat.X = reader.ReadElementContentAsFloat("X", String.Empty); 1441 while (reader.NodeType != XmlNodeType.EndElement)
1415 quat.Y = reader.ReadElementContentAsFloat("Y", String.Empty); 1442 {
1416 quat.Z = reader.ReadElementContentAsFloat("Z", String.Empty); 1443 switch (reader.Name.ToLower())
1417 quat.W = reader.ReadElementContentAsFloat("W", String.Empty); 1444 {
1445 case "x":
1446 quat.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1447 break;
1448 case "y":
1449 quat.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1450 break;
1451 case "z":
1452 quat.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1453 break;
1454 case "w":
1455 quat.W = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1456 break;
1457 }
1458 }
1459
1418 reader.ReadEndElement(); 1460 reader.ReadEndElement();
1419 1461
1420 return quat; 1462 return quat;