OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
SimulatorFeaturesModule.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.Collections.Generic;
31 using System.Reflection;
32 using log4net;
33 using Nini.Config;
34 using Mono.Addins;
35 using OpenMetaverse;
36 using OpenMetaverse.StructuredData;
37 using OpenSim.Framework;
38 using OpenSim.Framework.Servers.HttpServer;
39 using OpenSim.Region.Framework.Interfaces;
40 using OpenSim.Region.Framework.Scenes;
41 // using OpenSim.Services.Interfaces;
43 
44 namespace OpenSim.Region.ClientStack.Linden
45 {
57  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimulatorFeaturesModule")]
59  {
60  private static readonly ILog m_log =
61  LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62 
64 
65  private Scene m_scene;
66 
70  private OSDMap m_features = new OSDMap();
71 
72  private string m_SearchURL = string.Empty;
73  private string m_DestinationGuideURL = string.Empty;
74  private bool m_ExportSupported = false;
75  private string m_GridName = string.Empty;
76  private string m_GridURL = string.Empty;
77 
78  #region ISharedRegionModule Members
79 
80  public void Initialise(IConfigSource source)
81  {
82  IConfig config = source.Configs["SimulatorFeatures"];
83 
84  if (config != null)
85  {
86  //
87  // All this is obsolete since getting these features from the grid service!!
88  // Will be removed after the next release
89  //
90  m_SearchURL = config.GetString("SearchServerURI", m_SearchURL);
91 
92  m_DestinationGuideURL = config.GetString ("DestinationGuideURI", m_DestinationGuideURL);
93 
94  if (m_DestinationGuideURL == string.Empty) // Make this consistent with the variable in the LoginService config
95  m_DestinationGuideURL = config.GetString("DestinationGuide", m_DestinationGuideURL);
96 
97  m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported);
98 
99  m_GridURL = Util.GetConfigVarFromSections<string>(
100  source, "GatekeeperURI", new string[] { "Startup", "Hypergrid", "SimulatorFeatures" }, String.Empty);
101 
102  m_GridName = config.GetString("GridName", string.Empty);
103  if (m_GridName == string.Empty)
104  m_GridName = Util.GetConfigVarFromSections<string>(
105  source, "gridname", new string[] { "GridInfo", "SimulatorFeatures" }, String.Empty);
106  }
107 
108  AddDefaultFeatures();
109  }
110 
111  public void AddRegion(Scene s)
112  {
113  m_scene = s;
114  m_scene.EventManager.OnRegisterCaps += RegisterCaps;
115 
116  m_scene.RegisterModuleInterface<ISimulatorFeaturesModule>(this);
117  }
118 
119  public void RemoveRegion(Scene s)
120  {
121  m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
122  }
123 
124  public void RegionLoaded(Scene s)
125  {
126  GetGridExtraFeatures(s);
127  }
128 
129  public void PostInitialise()
130  {
131  }
132 
133  public void Close() { }
134 
135  public string Name { get { return "SimulatorFeaturesModule"; } }
136 
137  public Type ReplaceableInterface
138  {
139  get { return null; }
140  }
141 
142  #endregion
143 
150  private void AddDefaultFeatures()
151  {
152 
153  lock (m_features)
154  {
155  m_features["MeshRezEnabled"] = true;
156  m_features["MeshUploadEnabled"] = true;
157  m_features["MeshXferEnabled"] = true;
158 
159  m_features["PhysicsMaterialsEnabled"] = true;
160 
161  OSDMap typesMap = new OSDMap();
162  typesMap["convex"] = true;
163  typesMap["none"] = true;
164  typesMap["prim"] = true;
165  m_features["PhysicsShapeTypes"] = typesMap;
166 
167  // Extra information for viewers that want to use it
168  // TODO: Take these out of here into their respective modules, like map-server-url
169  OSDMap extrasMap;
170  if(m_features.ContainsKey("OpenSimExtras"))
171  {
172  extrasMap = (OSDMap)m_features["OpenSimExtras"];
173  }
174  else
175  extrasMap = new OSDMap();
176 
177  extrasMap["AvatarSkeleton"] = true;
178  extrasMap["AnimationSet"] = true;
179 
180  // TODO: Take these out of here into their respective modules, like map-server-url
181  if (m_SearchURL != string.Empty)
182  extrasMap["search-server-url"] = m_SearchURL;
183  if (!string.IsNullOrEmpty(m_DestinationGuideURL))
184  extrasMap["destination-guide-url"] = m_DestinationGuideURL;
185  if (m_ExportSupported)
186  extrasMap["ExportSupported"] = true;
187  if (m_GridURL != string.Empty)
188  extrasMap["GridURL"] = m_GridURL;
189  if (m_GridName != string.Empty)
190  extrasMap["GridName"] = m_GridName;
191 
192  if (extrasMap.Count > 0)
193  m_features["OpenSimExtras"] = extrasMap;
194  }
195  }
196 
197  public void RegisterCaps(UUID agentID, Caps caps)
198  {
199  IRequestHandler reqHandler
200  = new RestHTTPHandler(
201  "GET", "/CAPS/" + UUID.Random(),
202  x => { return HandleSimulatorFeaturesRequest(x, agentID); }, "SimulatorFeatures", agentID.ToString());
203 
204  caps.RegisterHandler("SimulatorFeatures", reqHandler);
205  }
206 
207  public void AddFeature(string name, OSD value)
208  {
209  lock (m_features)
210  m_features[name] = value;
211  }
212 
213  public bool RemoveFeature(string name)
214  {
215  lock (m_features)
216  return m_features.Remove(name);
217  }
218 
219  public bool TryGetFeature(string name, out OSD value)
220  {
221  lock (m_features)
222  return m_features.TryGetValue(name, out value);
223  }
224 
226  {
227  lock (m_features)
228  return new OSDMap(m_features);
229  }
230 
231  private OSDMap DeepCopy()
232  {
233  // This isn't the cheapest way of doing this but the rate
234  // of occurrence is low (on sim entry only) and it's a sure
235  // way to get a true deep copy.
236  OSD copy = OSDParser.DeserializeLLSDXml(OSDParser.SerializeLLSDXmlString(m_features));
237 
238  return (OSDMap)copy;
239  }
240 
241  private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod, UUID agentID)
242  {
243 // m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
244 
245  OSDMap copy = DeepCopy();
246 
247  // Let's add the agentID to the destination guide, if it is expecting that.
248  if (copy.ContainsKey("OpenSimExtras") && ((OSDMap)(copy["OpenSimExtras"])).ContainsKey("destination-guide-url"))
249  ((OSDMap)copy["OpenSimExtras"])["destination-guide-url"] = Replace(((OSDMap)copy["OpenSimExtras"])["destination-guide-url"], "[USERID]", agentID.ToString());
250 
251  SimulatorFeaturesRequestDelegate handlerOnSimulatorFeaturesRequest = OnSimulatorFeaturesRequest;
252 
253  if (handlerOnSimulatorFeaturesRequest != null)
254  handlerOnSimulatorFeaturesRequest(agentID, ref copy);
255 
256  //Send back data
257  Hashtable responsedata = new Hashtable();
258  responsedata["int_response_code"] = 200;
259  responsedata["content_type"] = "text/plain";
260  responsedata["keepalive"] = false;
261 
262  responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(copy);
263 
264  return responsedata;
265  }
266 
273  private void GetGridExtraFeatures(Scene scene)
274  {
275  Dictionary<string, object> extraFeatures = scene.GridService.GetExtraFeatures();
276  if (extraFeatures.ContainsKey("Result") && extraFeatures["Result"] != null && extraFeatures["Result"].ToString() == "Failure")
277  {
278  m_log.WarnFormat("[SIMULATOR FEATURES MODULE]: Unable to retrieve grid-wide features");
279  return;
280  }
281 
282  lock (m_features)
283  {
284  OSDMap extrasMap = new OSDMap();
285 
286  foreach(string key in extraFeatures.Keys)
287  {
288  extrasMap[key] = (string)extraFeatures[key];
289 
290  if (key == "ExportSupported")
291  {
292  bool.TryParse(extraFeatures[key].ToString(), out m_ExportSupported);
293  }
294  }
295  m_features["OpenSimExtras"] = extrasMap;
296 
297  }
298  }
299 
300  private string Replace(string url, string substring, string replacement)
301  {
302  if (!String.IsNullOrEmpty(url) && url.Contains(substring))
303  return url.Replace(substring, replacement);
304 
305  return url;
306  }
307  }
308 }
void RemoveRegion(Scene s)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
OpenSim.Framework.Capabilities.Caps Caps
OpenMetaverse.StructuredData.OSDMap OSDMap
Add remove or retrieve Simulator Features that will be given to a viewer via the SimulatorFeatures ca...
OpenSim.Framework.Capabilities.Caps Caps
void RegionLoaded(Scene s)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString key
Definition: ICM_Api.cs:31
delegate void SimulatorFeaturesRequestDelegate(UUID agentID, ref OSDMap features)
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
OpenMetaverse.StructuredData.OSD OSD
void AddRegion(Scene s)
This is called whenever a Scene is added. For shared modules, this can happen several times...
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void PostInitialise()
This is called exactly once after all the shared region-modules have been instanciated and IRegionMod...