OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
ObjectAdd.cs
Go to the documentation of this file.
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 
28 using System;
29 using System.Collections;
30 using System.Reflection;
31 using log4net;
32 using Nini.Config;
33 using OpenMetaverse;
34 using OpenMetaverse.StructuredData;
35 using Mono.Addins;
36 using OpenSim.Framework;
37 using OpenSim.Framework.Servers;
38 using OpenSim.Framework.Servers.HttpServer;
39 using OpenSim.Region.Framework.Interfaces;
40 using OpenSim.Region.Framework.Scenes;
42 
43 namespace OpenSim.Region.ClientStack.Linden
44 {
45  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ObjectAdd")]
47  {
48 // private static readonly ILog m_log =
49 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 
51  private Scene m_scene;
52 
53  #region INonSharedRegionModule Members
54 
55  public void Initialise(IConfigSource pSource)
56  {
57  }
58 
59  public void AddRegion(Scene scene)
60  {
61  m_scene = scene;
62  m_scene.EventManager.OnRegisterCaps += RegisterCaps;
63  }
64 
65  public void RemoveRegion(Scene scene)
66  {
67  if (m_scene == scene)
68  {
69  m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
70  m_scene = null;
71  }
72  }
73 
74  public void RegionLoaded(Scene scene)
75  {
76  }
77 
78  public void Close()
79  {
80  }
81 
82  public string Name
83  {
84  get { return "ObjectAddModule"; }
85  }
86 
87  public Type ReplaceableInterface
88  {
89  get { return null; }
90  }
91 
92  #endregion
93 
94  public void RegisterCaps(UUID agentID, Caps caps)
95  {
96  UUID capuuid = UUID.Random();
97 
98  // m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
99 
100  caps.RegisterHandler(
101  "ObjectAdd",
102  new RestHTTPHandler(
103  "POST",
104  "/CAPS/OA/" + capuuid + "/",
105  httpMethod => ProcessAdd(httpMethod, agentID, caps),
106  "ObjectAdd",
107  agentID.ToString())); ;
108  }
109 
110  public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
111  {
112  Hashtable responsedata = new Hashtable();
113  responsedata["int_response_code"] = 400; //501; //410; //404;
114  responsedata["content_type"] = "text/plain";
115  responsedata["keepalive"] = false;
116  responsedata["str_response_string"] = "Request wasn't what was expected";
117  ScenePresence avatar;
118 
119  if (!m_scene.TryGetScenePresence(AgentId, out avatar))
120  return responsedata;
121 
122 
123  OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]);
124  //UUID session_id = UUID.Zero;
125  bool bypass_raycast = false;
126  uint everyone_mask = 0;
127  uint group_mask = 0;
128  uint next_owner_mask = 0;
129  uint flags = 0;
130  UUID group_id = UUID.Zero;
131  int hollow = 0;
132  int material = 0;
133  int p_code = 0;
134  int path_begin = 0;
135  int path_curve = 0;
136  int path_end = 0;
137  int path_radius_offset = 0;
138  int path_revolutions = 0;
139  int path_scale_x = 0;
140  int path_scale_y = 0;
141  int path_shear_x = 0;
142  int path_shear_y = 0;
143  int path_skew = 0;
144  int path_taper_x = 0;
145  int path_taper_y = 0;
146  int path_twist = 0;
147  int path_twist_begin = 0;
148  int profile_begin = 0;
149  int profile_curve = 0;
150  int profile_end = 0;
151  Vector3 ray_end = Vector3.Zero;
152  bool ray_end_is_intersection = false;
153  Vector3 ray_start = Vector3.Zero;
154  UUID ray_target_id = UUID.Zero;
155  Quaternion rotation = Quaternion.Identity;
156  Vector3 scale = Vector3.Zero;
157  int state = 0;
158  int lastattach = 0;
159 
160  if (r.Type != OSDType.Map) // not a proper req
161  return responsedata;
162 
163  OSDMap rm = (OSDMap)r;
164 
165  if (rm.ContainsKey("ObjectData")) //v2
166  {
167  if (rm["ObjectData"].Type != OSDType.Map)
168  {
169  responsedata["str_response_string"] = "Has ObjectData key, but data not in expected format";
170  return responsedata;
171  }
172 
173  OSDMap ObjMap = (OSDMap)rm["ObjectData"];
174 
175  bypass_raycast = ObjMap["BypassRaycast"].AsBoolean();
176  everyone_mask = readuintval(ObjMap["EveryoneMask"]);
177  flags = readuintval(ObjMap["Flags"]);
178  group_mask = readuintval(ObjMap["GroupMask"]);
179  material = ObjMap["Material"].AsInteger();
180  next_owner_mask = readuintval(ObjMap["NextOwnerMask"]);
181  p_code = ObjMap["PCode"].AsInteger();
182 
183  if (ObjMap.ContainsKey("Path"))
184  {
185  if (ObjMap["Path"].Type != OSDType.Map)
186  {
187  responsedata["str_response_string"] = "Has Path key, but data not in expected format";
188  return responsedata;
189  }
190 
191  OSDMap PathMap = (OSDMap)ObjMap["Path"];
192  path_begin = PathMap["Begin"].AsInteger();
193  path_curve = PathMap["Curve"].AsInteger();
194  path_end = PathMap["End"].AsInteger();
195  path_radius_offset = PathMap["RadiusOffset"].AsInteger();
196  path_revolutions = PathMap["Revolutions"].AsInteger();
197  path_scale_x = PathMap["ScaleX"].AsInteger();
198  path_scale_y = PathMap["ScaleY"].AsInteger();
199  path_shear_x = PathMap["ShearX"].AsInteger();
200  path_shear_y = PathMap["ShearY"].AsInteger();
201  path_skew = PathMap["Skew"].AsInteger();
202  path_taper_x = PathMap["TaperX"].AsInteger();
203  path_taper_y = PathMap["TaperY"].AsInteger();
204  path_twist = PathMap["Twist"].AsInteger();
205  path_twist_begin = PathMap["TwistBegin"].AsInteger();
206 
207  }
208 
209  if (ObjMap.ContainsKey("Profile"))
210  {
211  if (ObjMap["Profile"].Type != OSDType.Map)
212  {
213  responsedata["str_response_string"] = "Has Profile key, but data not in expected format";
214  return responsedata;
215  }
216 
217  OSDMap ProfileMap = (OSDMap)ObjMap["Profile"];
218 
219  profile_begin = ProfileMap["Begin"].AsInteger();
220  profile_curve = ProfileMap["Curve"].AsInteger();
221  profile_end = ProfileMap["End"].AsInteger();
222  hollow = ProfileMap["Hollow"].AsInteger();
223  }
224  ray_end_is_intersection = ObjMap["RayEndIsIntersection"].AsBoolean();
225 
226  ray_target_id = ObjMap["RayTargetId"].AsUUID();
227  state = ObjMap["State"].AsInteger();
228  lastattach = ObjMap["LastAttachPoint"].AsInteger();
229  try
230  {
231  ray_end = ((OSDArray)ObjMap["RayEnd"]).AsVector3();
232  ray_start = ((OSDArray)ObjMap["RayStart"]).AsVector3();
233  scale = ((OSDArray)ObjMap["Scale"]).AsVector3();
234  rotation = ((OSDArray)ObjMap["Rotation"]).AsQuaternion();
235  }
236  catch (Exception)
237  {
238  responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
239  return responsedata;
240  }
241 
242  if (rm.ContainsKey("AgentData"))
243  {
244  if (rm["AgentData"].Type != OSDType.Map)
245  {
246  responsedata["str_response_string"] = "Has AgentData key, but data not in expected format";
247  return responsedata;
248  }
249 
250  OSDMap AgentDataMap = (OSDMap)rm["AgentData"];
251 
252  //session_id = AgentDataMap["SessionId"].AsUUID();
253  group_id = AgentDataMap["GroupId"].AsUUID();
254  }
255 
256  }
257  else
258  { //v1
259  bypass_raycast = rm["bypass_raycast"].AsBoolean();
260 
261  everyone_mask = readuintval(rm["everyone_mask"]);
262  flags = readuintval(rm["flags"]);
263  group_id = rm["group_id"].AsUUID();
264  group_mask = readuintval(rm["group_mask"]);
265  hollow = rm["hollow"].AsInteger();
266  material = rm["material"].AsInteger();
267  next_owner_mask = readuintval(rm["next_owner_mask"]);
268  hollow = rm["hollow"].AsInteger();
269  p_code = rm["p_code"].AsInteger();
270  path_begin = rm["path_begin"].AsInteger();
271  path_curve = rm["path_curve"].AsInteger();
272  path_end = rm["path_end"].AsInteger();
273  path_radius_offset = rm["path_radius_offset"].AsInteger();
274  path_revolutions = rm["path_revolutions"].AsInteger();
275  path_scale_x = rm["path_scale_x"].AsInteger();
276  path_scale_y = rm["path_scale_y"].AsInteger();
277  path_shear_x = rm["path_shear_x"].AsInteger();
278  path_shear_y = rm["path_shear_y"].AsInteger();
279  path_skew = rm["path_skew"].AsInteger();
280  path_taper_x = rm["path_taper_x"].AsInteger();
281  path_taper_y = rm["path_taper_y"].AsInteger();
282  path_twist = rm["path_twist"].AsInteger();
283  path_twist_begin = rm["path_twist_begin"].AsInteger();
284  profile_begin = rm["profile_begin"].AsInteger();
285  profile_curve = rm["profile_curve"].AsInteger();
286  profile_end = rm["profile_end"].AsInteger();
287 
288  ray_end_is_intersection = rm["ray_end_is_intersection"].AsBoolean();
289 
290  ray_target_id = rm["ray_target_id"].AsUUID();
291 
292 
293  //session_id = rm["session_id"].AsUUID();
294  state = rm["state"].AsInteger();
295  lastattach = rm["last_attach_point"].AsInteger();
296  try
297  {
298  ray_end = ((OSDArray)rm["ray_end"]).AsVector3();
299  ray_start = ((OSDArray)rm["ray_start"]).AsVector3();
300  rotation = ((OSDArray)rm["rotation"]).AsQuaternion();
301  scale = ((OSDArray)rm["scale"]).AsVector3();
302  }
303  catch (Exception)
304  {
305  responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
306  return responsedata;
307  }
308  }
309 
310 
311 
312  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);
313 
314  PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
315 
316  pbs.PathBegin = (ushort)path_begin;
317  pbs.PathCurve = (byte)path_curve;
318  pbs.PathEnd = (ushort)path_end;
319  pbs.PathRadiusOffset = (sbyte)path_radius_offset;
320  pbs.PathRevolutions = (byte)path_revolutions;
321  pbs.PathScaleX = (byte)path_scale_x;
322  pbs.PathScaleY = (byte)path_scale_y;
323  pbs.PathShearX = (byte)path_shear_x;
324  pbs.PathShearY = (byte)path_shear_y;
325  pbs.PathSkew = (sbyte)path_skew;
326  pbs.PathTaperX = (sbyte)path_taper_x;
327  pbs.PathTaperY = (sbyte)path_taper_y;
328  pbs.PathTwist = (sbyte)path_twist;
329  pbs.PathTwistBegin = (sbyte)path_twist_begin;
330  pbs.HollowShape = (HollowShape)hollow;
331  pbs.PCode = (byte)p_code;
332  pbs.ProfileBegin = (ushort)profile_begin;
333  pbs.ProfileCurve = (byte)profile_curve;
334  pbs.ProfileEnd = (ushort)profile_end;
335  pbs.Scale = scale;
336  pbs.State = (byte)state;
337  pbs.LastAttachPoint = (byte)lastattach;
338 
339  SceneObjectGroup obj = null; ;
340 
341  if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
342  {
343  // rez ON the ground, not IN the ground
344  // pos.Z += 0.25F;
345 
346  obj = m_scene.AddNewPrim(avatar.UUID, group_id, pos, rotation, pbs);
347  }
348 
349 
350  if (obj == null)
351  return responsedata;
352 
353  SceneObjectPart rootpart = obj.RootPart;
354  rootpart.Shape = pbs;
355  rootpart.Flags |= (PrimFlags)flags;
356  rootpart.EveryoneMask = everyone_mask;
357  rootpart.GroupID = group_id;
358  rootpart.GroupMask = group_mask;
359  rootpart.NextOwnerMask = next_owner_mask;
360  rootpart.Material = (byte)material;
361 
362  m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
363 
364  responsedata["int_response_code"] = 200; //501; //410; //404;
365  responsedata["content_type"] = "text/plain";
366  responsedata["keepalive"] = false;
367  responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>", ConvertUintToBytes(obj.LocalId));
368 
369  return responsedata;
370  }
371 
372  private uint readuintval(OSD obj)
373  {
374  byte[] tmp = obj.AsBinary();
375  if (BitConverter.IsLittleEndian)
376  Array.Reverse(tmp);
377  return Utils.BytesToUInt(tmp);
378 
379  }
380  private string ConvertUintToBytes(uint val)
381  {
382  byte[] resultbytes = Utils.UIntToBytes(val);
383  if (BitConverter.IsLittleEndian)
384  Array.Reverse(resultbytes);
385  return String.Format("<binary encoding=\"base64\">{0}</binary>", Convert.ToBase64String(resultbytes));
386  }
387 
388  }
389 }
OpenMetaverse.StructuredData.OSDArray OSDArray
void RegisterCaps(UUID agentID, Caps caps)
Definition: ObjectAdd.cs:94
OpenMetaverse.StructuredData.OSDMap OSDMap
Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
Definition: ObjectAdd.cs:110
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
OpenSim.Framework.Capabilities.Caps Caps
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
Definition: ObjectAdd.cs:65
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
Definition: ICM_Api.cs:32
OpenSim.Framework.Capabilities.Caps Caps
Definition: ObjectAdd.cs:41
OpenMetaverse.StructuredData.OSD OSD
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
Definition: ObjectAdd.cs:78
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
Definition: ObjectAdd.cs:59
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
Definition: ObjectAdd.cs:74
void Initialise(IConfigSource pSource)
This is called to initialize the region module. For shared modules, this is called exactly once...
Definition: ObjectAdd.cs:55