OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
DynamicMenuModule.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.IO;
30 using System.Reflection;
31 using System.Text;
32 using System.Collections.Generic;
33 using OpenMetaverse;
34 using OpenMetaverse.StructuredData;
35 using OpenSim;
36 using OpenSim.Region;
37 using OpenSim.Region.Framework;
38 using OpenSim.Region.Framework.Scenes;
39 using OpenSim.Region.Framework.Interfaces;
40 using OpenSim.Framework;
41 //using OpenSim.Framework.Capabilities;
42 using OpenSim.Framework.Servers;
43 using OpenSim.Framework.Servers.HttpServer;
44 using Nini.Config;
45 using log4net;
46 using Mono.Addins;
49 
50 namespace OpenSim.Region.OptionalModules.ViewerSupport
51 {
52  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicMenu")]
54  {
55  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 
57  private class MenuItemData
58  {
59  public string Title;
60  public UUID AgentID;
61  public InsertLocation Location;
62  public UserMode Mode;
63  public CustomMenuHandler Handler;
64  }
65 
66  private Dictionary<UUID, List<MenuItemData>> m_menuItems =
67  new Dictionary<UUID, List<MenuItemData>>();
68 
69  private Scene m_scene;
70 
71  public string Name
72  {
73  get { return "DynamicMenuModule"; }
74  }
75 
76  public Type ReplaceableInterface
77  {
78  get { return null; }
79  }
80 
81  public void Initialise(IConfigSource config)
82  {
83  }
84 
85  public void Close()
86  {
87  }
88 
89  public void AddRegion(Scene scene)
90  {
91  m_scene = scene;
92  scene.EventManager.OnRegisterCaps += OnRegisterCaps;
93  m_scene.RegisterModuleInterface<IDynamicMenuModule>(this);
94  }
95 
96  public void RegionLoaded(Scene scene)
97  {
98  ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface<ISimulatorFeaturesModule>();
99 
100  if (featuresModule != null)
101  featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest;
102  }
103 
104  public void RemoveRegion(Scene scene)
105  {
106  }
107 
108  private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features)
109  {
110  OSD menus = new OSDMap();
111  if (features.ContainsKey("menus"))
112  menus = features["menus"];
113 
114  OSDMap agent = new OSDMap();
115  OSDMap world = new OSDMap();
116  OSDMap tools = new OSDMap();
117  OSDMap advanced = new OSDMap();
118  OSDMap admin = new OSDMap();
119  if (((OSDMap)menus).ContainsKey("agent"))
120  agent = (OSDMap)((OSDMap)menus)["agent"];
121  if (((OSDMap)menus).ContainsKey("world"))
122  world = (OSDMap)((OSDMap)menus)["world"];
123  if (((OSDMap)menus).ContainsKey("tools"))
124  tools = (OSDMap)((OSDMap)menus)["tools"];
125  if (((OSDMap)menus).ContainsKey("advanced"))
126  advanced = (OSDMap)((OSDMap)menus)["advanced"];
127  if (((OSDMap)menus).ContainsKey("admin"))
128  admin = (OSDMap)((OSDMap)menus)["admin"];
129 
130  if (m_menuItems.ContainsKey(UUID.Zero))
131  {
132  foreach (MenuItemData d in m_menuItems[UUID.Zero])
133  {
134  if (!m_scene.Permissions.IsGod(agentID))
135  {
136  if (d.Mode == UserMode.RegionManager && (!m_scene.Permissions.IsAdministrator(agentID)))
137  continue;
138  }
139 
140  OSDMap loc = null;
141  switch (d.Location)
142  {
143  case InsertLocation.Agent:
144  loc = agent;
145  break;
146  case InsertLocation.World:
147  loc = world;
148  break;
149  case InsertLocation.Tools:
150  loc = tools;
151  break;
152  case InsertLocation.Advanced:
153  loc = advanced;
154  break;
155  case InsertLocation.Admin:
156  loc = admin;
157  break;
158  }
159 
160  if (loc == null)
161  continue;
162 
163  loc[d.Title] = OSD.FromString(d.Title);
164  }
165  }
166 
167  if (m_menuItems.ContainsKey(agentID))
168  {
169  foreach (MenuItemData d in m_menuItems[agentID])
170  {
171  if (d.Mode == UserMode.God && (!m_scene.Permissions.IsGod(agentID)))
172  continue;
173 
174  OSDMap loc = null;
175  switch (d.Location)
176  {
177  case InsertLocation.Agent:
178  loc = agent;
179  break;
180  case InsertLocation.World:
181  loc = world;
182  break;
183  case InsertLocation.Tools:
184  loc = tools;
185  break;
186  case InsertLocation.Advanced:
187  loc = advanced;
188  break;
189  case InsertLocation.Admin:
190  loc = admin;
191  break;
192  }
193 
194  if (loc == null)
195  continue;
196 
197  loc[d.Title] = OSD.FromString(d.Title);
198  }
199  }
200 
201 
202  ((OSDMap)menus)["agent"] = agent;
203  ((OSDMap)menus)["world"] = world;
204  ((OSDMap)menus)["tools"] = tools;
205  ((OSDMap)menus)["advanced"] = advanced;
206  ((OSDMap)menus)["admin"] = admin;
207 
208  features["menus"] = menus;
209  }
210 
211  private void OnRegisterCaps(UUID agentID, Caps caps)
212  {
213  string capUrl = "/CAPS/" + UUID.Random() + "/";
214 
215  capUrl = "/CAPS/" + UUID.Random() + "/";
216  caps.RegisterHandler("CustomMenuAction", new MenuActionHandler(capUrl, "CustomMenuAction", agentID, this, m_scene));
217  }
218 
219  internal void HandleMenuSelection(string action, UUID agentID, List<uint> selection)
220  {
221  if (m_menuItems.ContainsKey(agentID))
222  {
223  foreach (MenuItemData d in m_menuItems[agentID])
224  {
225  if (d.Title == action)
226  d.Handler(action, agentID, selection);
227  }
228  }
229 
230  if (m_menuItems.ContainsKey(UUID.Zero))
231  {
232  foreach (MenuItemData d in m_menuItems[UUID.Zero])
233  {
234  if (d.Title == action)
235  d.Handler(action, agentID, selection);
236  }
237  }
238  }
239 
240  public void AddMenuItem(string title, InsertLocation location, UserMode mode, CustomMenuHandler handler)
241  {
242  AddMenuItem(UUID.Zero, title, location, mode, handler);
243  }
244 
245  public void AddMenuItem(UUID agentID, string title, InsertLocation location, UserMode mode, CustomMenuHandler handler)
246  {
247  if (!m_menuItems.ContainsKey(agentID))
248  m_menuItems[agentID] = new List<MenuItemData>();
249 
250  m_menuItems[agentID].Add(new MenuItemData() { Title = title, AgentID = agentID, Location = location, Mode = mode, Handler = handler });
251  }
252 
253  public void RemoveMenuItem(string action)
254  {
255  foreach (KeyValuePair<UUID,List< MenuItemData>> kvp in m_menuItems)
256  {
257  List<MenuItemData> pendingDeletes = new List<MenuItemData>();
258  foreach (MenuItemData d in kvp.Value)
259  {
260  if (d.Title == action)
261  pendingDeletes.Add(d);
262  }
263 
264  foreach (MenuItemData d in pendingDeletes)
265  kvp.Value.Remove(d);
266  }
267  }
268  }
269 
271  {
272  private static readonly ILog m_log =
273  LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
274 
275  private UUID m_agentID;
276  private Scene m_scene;
277  private DynamicMenuModule m_module;
278 
279  public MenuActionHandler(string path, string name, UUID agentID, DynamicMenuModule module, Scene scene)
280  :base("POST", path, name, agentID.ToString())
281  {
282  m_agentID = agentID;
283  m_scene = scene;
284  m_module = module;
285  }
286 
287  protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
288  {
289  StreamReader reader = new StreamReader(request);
290  string requestBody = reader.ReadToEnd();
291 
292  OSD osd = OSDParser.DeserializeLLSDXml(requestBody);
293 
294  string action = ((OSDMap)osd)["action"].AsString();
295  OSDArray selection = (OSDArray)((OSDMap)osd)["selection"];
296  List<uint> sel = new List<uint>();
297  for (int i = 0 ; i < selection.Count ; i++)
298  sel.Add(selection[i].AsUInteger());
299 
300  Util.FireAndForget(
301  x => { m_module.HandleMenuSelection(action, m_agentID, sel); }, null, "DynamicMenuModule.HandleMenuSelection");
302 
303  Encoding encoding = Encoding.UTF8;
304  return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD()));
305  }
306  }
307 }
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
OpenMetaverse.StructuredData.OSDArray OSDArray
MenuActionHandler(string path, string name, UUID agentID, DynamicMenuModule module, Scene scene)
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
override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
OpenMetaverse.StructuredData.OSDMap OSDMap
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
void Initialise(IConfigSource config)
This is called to initialize the region module. For shared modules, this is called exactly once...
void AddMenuItem(string title, InsertLocation location, UserMode mode, CustomMenuHandler handler)
OpenMetaverse.StructuredData.OSD OSD
Interactive OpenSim region server
Definition: OpenSim.cs:55
void AddMenuItem(UUID agentID, string title, InsertLocation location, UserMode mode, CustomMenuHandler handler)
delegate void CustomMenuHandler(string action, UUID agentID, List< uint > selection)
OpenSim.Framework.Capabilities.Caps Caps
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...