aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs304
1 files changed, 304 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
new file mode 100644
index 0000000..d37369c
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
@@ -0,0 +1,304 @@
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.IO;
30using System.Reflection;
31using System.Text;
32using System.Collections.Generic;
33using OpenMetaverse;
34using OpenMetaverse.StructuredData;
35using OpenSim;
36using OpenSim.Region;
37using OpenSim.Region.Framework;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Framework;
41//using OpenSim.Framework.Capabilities;
42using OpenSim.Framework.Servers;
43using OpenSim.Framework.Servers.HttpServer;
44using Nini.Config;
45using log4net;
46using Mono.Addins;
47using Caps = OpenSim.Framework.Capabilities.Caps;
48using OSDMap = OpenMetaverse.StructuredData.OSDMap;
49
50namespace OpenSim.Region.OptionalModules.ViewerSupport
51{
52 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicMenu")]
53 public class DynamicMenuModule : INonSharedRegionModule, IDynamicMenuModule
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 (d.Mode == UserMode.God && (!m_scene.Permissions.IsGod(agentID)))
135 continue;
136
137 OSDMap loc = null;
138 switch (d.Location)
139 {
140 case InsertLocation.Agent:
141 loc = agent;
142 break;
143 case InsertLocation.World:
144 loc = world;
145 break;
146 case InsertLocation.Tools:
147 loc = tools;
148 break;
149 case InsertLocation.Advanced:
150 loc = advanced;
151 break;
152 case InsertLocation.Admin:
153 loc = admin;
154 break;
155 }
156
157 if (loc == null)
158 continue;
159
160 loc[d.Title] = OSD.FromString(d.Title);
161 }
162 }
163
164 if (m_menuItems.ContainsKey(agentID))
165 {
166 foreach (MenuItemData d in m_menuItems[agentID])
167 {
168 if (d.Mode == UserMode.God && (!m_scene.Permissions.IsGod(agentID)))
169 continue;
170
171 OSDMap loc = null;
172 switch (d.Location)
173 {
174 case InsertLocation.Agent:
175 loc = agent;
176 break;
177 case InsertLocation.World:
178 loc = world;
179 break;
180 case InsertLocation.Tools:
181 loc = tools;
182 break;
183 case InsertLocation.Advanced:
184 loc = advanced;
185 break;
186 case InsertLocation.Admin:
187 loc = admin;
188 break;
189 }
190
191 if (loc == null)
192 continue;
193
194 loc[d.Title] = OSD.FromString(d.Title);
195 }
196 }
197
198
199 ((OSDMap)menus)["agent"] = agent;
200 ((OSDMap)menus)["world"] = world;
201 ((OSDMap)menus)["tools"] = tools;
202 ((OSDMap)menus)["advanced"] = advanced;
203 ((OSDMap)menus)["admin"] = admin;
204
205 features["menus"] = menus;
206 }
207
208 private void OnRegisterCaps(UUID agentID, Caps caps)
209 {
210 string capUrl = "/CAPS/" + UUID.Random() + "/";
211
212 capUrl = "/CAPS/" + UUID.Random() + "/";
213 caps.RegisterHandler("CustomMenuAction", new MenuActionHandler(capUrl, "CustomMenuAction", agentID, this, m_scene));
214 }
215
216 internal void HandleMenuSelection(string action, UUID agentID, List<uint> selection)
217 {
218 if (m_menuItems.ContainsKey(agentID))
219 {
220 foreach (MenuItemData d in m_menuItems[agentID])
221 {
222 if (d.Title == action)
223 d.Handler(action, agentID, selection);
224 }
225 }
226
227 if (m_menuItems.ContainsKey(UUID.Zero))
228 {
229 foreach (MenuItemData d in m_menuItems[UUID.Zero])
230 {
231 if (d.Title == action)
232 d.Handler(action, agentID, selection);
233 }
234 }
235 }
236
237 public void AddMenuItem(string title, InsertLocation location, UserMode mode, CustomMenuHandler handler)
238 {
239 AddMenuItem(UUID.Zero, title, location, mode, handler);
240 }
241
242 public void AddMenuItem(UUID agentID, string title, InsertLocation location, UserMode mode, CustomMenuHandler handler)
243 {
244 if (!m_menuItems.ContainsKey(agentID))
245 m_menuItems[agentID] = new List<MenuItemData>();
246
247 m_menuItems[agentID].Add(new MenuItemData() { Title = title, AgentID = agentID, Location = location, Mode = mode, Handler = handler });
248 }
249
250 public void RemoveMenuItem(string action)
251 {
252 foreach (KeyValuePair<UUID,List< MenuItemData>> kvp in m_menuItems)
253 {
254 List<MenuItemData> pendingDeletes = new List<MenuItemData>();
255 foreach (MenuItemData d in kvp.Value)
256 {
257 if (d.Title == action)
258 pendingDeletes.Add(d);
259 }
260
261 foreach (MenuItemData d in pendingDeletes)
262 kvp.Value.Remove(d);
263 }
264 }
265 }
266
267 public class MenuActionHandler : BaseStreamHandler
268 {
269 private static readonly ILog m_log =
270 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
271
272 private UUID m_agentID;
273 private Scene m_scene;
274 private DynamicMenuModule m_module;
275
276 public MenuActionHandler(string path, string name, UUID agentID, DynamicMenuModule module, Scene scene)
277 :base("POST", path, name, agentID.ToString())
278 {
279 m_agentID = agentID;
280 m_scene = scene;
281 m_module = module;
282 }
283
284 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
285 {
286 StreamReader reader = new StreamReader(request);
287 string requestBody = reader.ReadToEnd();
288
289 OSD osd = OSDParser.DeserializeLLSDXml(requestBody);
290
291 string action = ((OSDMap)osd)["action"].AsString();
292 OSDArray selection = (OSDArray)((OSDMap)osd)["selection"];
293 List<uint> sel = new List<uint>();
294 for (int i = 0 ; i < selection.Count ; i++)
295 sel.Add(selection[i].AsUInteger());
296
297 Util.FireAndForget(
298 x => { m_module.HandleMenuSelection(action, m_agentID, sel); }, null, "DynamicMenuModule.HandleMenuSelection");
299
300 Encoding encoding = Encoding.UTF8;
301 return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD()));
302 }
303 }
304}