aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IDynamicFloaterModule.cs51
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs228
2 files changed, 279 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicFloaterModule.cs b/OpenSim/Region/Framework/Interfaces/IDynamicFloaterModule.cs
new file mode 100644
index 0000000..5e633e6
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IDynamicFloaterModule.cs
@@ -0,0 +1,51 @@
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.Collections.Generic;
29using OpenMetaverse;
30using OpenSim.Framework;
31using OpenSim.Region.Framework.Scenes;
32
33namespace OpenSim.Region.Framework.Interfaces
34{
35 public delegate bool HandlerDelegate(IClientAPI client, FloaterData data, string[] msg);
36
37 public abstract class FloaterData
38 {
39 public abstract int Channel { get; }
40 public abstract string FloaterName { get; }
41 public virtual string XmlName { get; set; }
42 public virtual HandlerDelegate Handler { get; set; }
43 }
44
45
46 public interface IDynamicFloaterModule
47 {
48 void DoUserFloater(UUID agentID, FloaterData dialogData, string configuration);
49 void FloaterControl(ScenePresence sp, FloaterData d, string msg);
50 }
51}
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs
new file mode 100644
index 0000000..7919fef
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicFloaterModule.cs
@@ -0,0 +1,228 @@
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;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Servers.HttpServer;
43using Nini.Config;
44using log4net;
45using Mono.Addins;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47using OSDMap = OpenMetaverse.StructuredData.OSDMap;
48
49namespace OpenSim.Region.OptionalModules.ViewerSupport
50{
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicFloater")]
52 public class DynamicFloaterModule : INonSharedRegionModule, IDynamicFloaterModule
53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Scene m_scene;
57
58 private Dictionary<UUID, Dictionary<int, FloaterData>> m_floaters = new Dictionary<UUID, Dictionary<int, FloaterData>>();
59
60 public string Name
61 {
62 get { return "DynamicFloaterModule"; }
63 }
64
65 public Type ReplaceableInterface
66 {
67 get { return null; }
68 }
69
70 public void Initialise(IConfigSource config)
71 {
72 }
73
74 public void Close()
75 {
76 }
77
78 public void AddRegion(Scene scene)
79 {
80 m_scene = scene;
81 scene.EventManager.OnNewClient += OnNewClient;
82 scene.EventManager.OnClientClosed += OnClientClosed;
83 m_scene.RegisterModuleInterface<IDynamicFloaterModule>(this);
84 }
85
86 public void RegionLoaded(Scene scene)
87 {
88 }
89
90 public void RemoveRegion(Scene scene)
91 {
92 }
93
94 private void OnNewClient(IClientAPI client)
95 {
96 client.OnChatFromClient += OnChatFromClient;
97 }
98
99 private void OnClientClosed(UUID agentID, Scene scene)
100 {
101 m_floaters.Remove(agentID);
102 }
103
104 private void SendToClient(ScenePresence sp, string msg)
105 {
106 sp.ControllingClient.SendChatMessage(msg,
107 (byte)ChatTypeEnum.Owner,
108 sp.AbsolutePosition,
109 "Server",
110 UUID.Zero,
111 UUID.Zero,
112 (byte)ChatSourceType.Object,
113 (byte)ChatAudibleLevel.Fully);
114 }
115
116 public void DoUserFloater(UUID agentID, FloaterData dialogData, string configuration)
117 {
118 ScenePresence sp = m_scene.GetScenePresence(agentID);
119 if (sp == null || sp.IsChildAgent)
120 return;
121
122 if (!m_floaters.ContainsKey(agentID))
123 m_floaters[agentID] = new Dictionary<int, FloaterData>();
124
125 m_floaters[agentID].Add(dialogData.Channel, dialogData);
126
127 string xml;
128 using (FileStream fs = File.Open(dialogData.XmlName + ".xml", FileMode.Open))
129 {
130 using (StreamReader sr = new StreamReader(fs))
131 xml = sr.ReadToEnd().Replace("\n", "");
132 }
133
134 List<string> xparts = new List<string>();
135
136 while (xml.Length > 0)
137 {
138 string x = xml;
139 if (x.Length > 600)
140 {
141 x = x.Substring(0, 600);
142 xml = xml.Substring(600);
143 }
144 else
145 {
146 xml = String.Empty;
147 }
148
149 xparts.Add(x);
150 }
151
152 for (int i = 0 ; i < xparts.Count ; i++)
153 SendToClient(sp, String.Format("># floater {2} create {0}/{1} " + xparts[i], i + 1, xparts.Count, dialogData.FloaterName));
154
155 SendToClient(sp, String.Format("># floater {0} {{notify:1}} {{channel: {1}}} {{node:cancel {{notify:1}}}} {{node:ok {{notify:1}}}} {2}", dialogData.FloaterName, (uint)dialogData.Channel, configuration));
156 }
157
158 private void OnChatFromClient(object sender, OSChatMessage msg)
159 {
160 if (msg.Sender == null)
161 return;
162
163 //m_log.DebugFormat("chan {0} msg {1}", msg.Channel, msg.Message);
164
165 IClientAPI client = msg.Sender;
166
167 if (!m_floaters.ContainsKey(client.AgentId))
168 return;
169
170 string[] parts = msg.Message.Split(new char[] {':'});
171 if (parts.Length == 0)
172 return;
173
174 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
175 if (sp == null || sp.IsChildAgent)
176 return;
177
178 Dictionary<int, FloaterData> d = m_floaters[client.AgentId];
179
180 // Work around a viewer bug - VALUE from any
181 // dialog can appear on this channel and needs to
182 // be dispatched to ALL open dialogs for the user
183 if (msg.Channel == 427169570)
184 {
185 if (parts[0] == "VALUE")
186 {
187 foreach (FloaterData dd in d.Values)
188 {
189 if(dd.Handler(client, dd, parts))
190 {
191 m_floaters[client.AgentId].Remove(dd.Channel);
192 SendToClient(sp, String.Format("># floater {0} destroy", dd.FloaterName));
193 break;
194 }
195 }
196 }
197 return;
198 }
199
200 if (!d.ContainsKey(msg.Channel))
201 return;
202
203 FloaterData data = d[msg.Channel];
204
205 if (parts[0] == "NOTIFY")
206 {
207 if (parts[1] == "cancel" || parts[1] == data.FloaterName)
208 {
209 m_floaters[client.AgentId].Remove(data.Channel);
210 SendToClient(sp, String.Format("># floater {0} destroy", data.FloaterName));
211 }
212 }
213
214 if (data.Handler(client, data, parts))
215 {
216 m_floaters[client.AgentId].Remove(data.Channel);
217 SendToClient(sp, String.Format("># floater {0} destroy", data.FloaterName));
218 }
219 }
220
221 public void FloaterControl(ScenePresence sp, FloaterData d, string msg)
222 {
223 string sendData = String.Format("># floater {0} {1}", d.FloaterName, msg);
224 SendToClient(sp, sendData);
225
226 }
227 }
228}