diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs (renamed from OpenSim/Region/Environment/Modules/WorldCommModule.cs) | 1162 |
1 files changed, 578 insertions, 584 deletions
diff --git a/OpenSim/Region/Environment/Modules/WorldCommModule.cs b/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs index 638deed..a949fb6 100644 --- a/OpenSim/Region/Environment/Modules/WorldCommModule.cs +++ b/OpenSim/Region/Environment/Modules/Scripting/WorldComm/WorldCommModule.cs | |||
@@ -1,584 +1,578 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using Nini.Config; | 31 | using Nini.Config; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Interfaces; |
34 | using OpenSim.Region.Environment.Scenes; | 34 | using OpenSim.Region.Environment.Scenes; |
35 | 35 | ||
36 | /***************************************************** | 36 | /***************************************************** |
37 | * | 37 | * |
38 | * WorldCommModule | 38 | * WorldCommModule |
39 | * | 39 | * |
40 | * | 40 | * |
41 | * Holding place for world comms - basically llListen | 41 | * Holding place for world comms - basically llListen |
42 | * function implementation. | 42 | * function implementation. |
43 | * | 43 | * |
44 | * lLListen(integer channel, string name, key id, string msg) | 44 | * lLListen(integer channel, string name, key id, string msg) |
45 | * The name, id, and msg arguments specify the filtering | 45 | * The name, id, and msg arguments specify the filtering |
46 | * criteria. You can pass the empty string | 46 | * criteria. You can pass the empty string |
47 | * (or NULL_KEY for id) for these to set a completely | 47 | * (or NULL_KEY for id) for these to set a completely |
48 | * open filter; this causes the listen() event handler to be | 48 | * open filter; this causes the listen() event handler to be |
49 | * invoked for all chat on the channel. To listen only | 49 | * invoked for all chat on the channel. To listen only |
50 | * for chat spoken by a specific object or avatar, | 50 | * for chat spoken by a specific object or avatar, |
51 | * specify the name and/or id arguments. To listen | 51 | * specify the name and/or id arguments. To listen |
52 | * only for a specific command, specify the | 52 | * only for a specific command, specify the |
53 | * (case-sensitive) msg argument. If msg is not empty, | 53 | * (case-sensitive) msg argument. If msg is not empty, |
54 | * listener will only hear strings which are exactly equal | 54 | * listener will only hear strings which are exactly equal |
55 | * to msg. You can also use all the arguments to establish | 55 | * to msg. You can also use all the arguments to establish |
56 | * the most restrictive filtering criteria. | 56 | * the most restrictive filtering criteria. |
57 | * | 57 | * |
58 | * It might be useful for each listener to maintain a message | 58 | * It might be useful for each listener to maintain a message |
59 | * digest, with a list of recent messages by UUID. This can | 59 | * digest, with a list of recent messages by UUID. This can |
60 | * be used to prevent in-world repeater loops. However, the | 60 | * be used to prevent in-world repeater loops. However, the |
61 | * linden functions do not have this capability, so for now | 61 | * linden functions do not have this capability, so for now |
62 | * thats the way it works. | 62 | * thats the way it works. |
63 | * | 63 | * |
64 | * **************************************************/ | 64 | * **************************************************/ |
65 | 65 | ||
66 | namespace OpenSim.Region.Environment.Modules | 66 | namespace OpenSim.Region.Environment.Modules.Scripting.WorldComm |
67 | { | 67 | { |
68 | public class WorldCommModule : IRegionModule, IWorldComm | 68 | public class WorldCommModule : IRegionModule, IWorldComm |
69 | { | 69 | { |
70 | private Scene m_scene; | 70 | private Scene m_scene; |
71 | private object CommListLock = new object(); | 71 | private object CommListLock = new object(); |
72 | private object ListLock = new object(); | 72 | private object ListLock = new object(); |
73 | private string m_name = "WorldCommModule"; | 73 | private string m_name = "WorldCommModule"; |
74 | private ListenerManager m_listenerManager; | 74 | private ListenerManager m_listenerManager; |
75 | private Queue m_pendingQ; | 75 | private Queue m_pendingQ; |
76 | private Queue m_pending; | 76 | private Queue m_pending; |
77 | 77 | ||
78 | public WorldCommModule() | 78 | public WorldCommModule() |
79 | { | 79 | { |
80 | } | 80 | } |
81 | 81 | ||
82 | public void Initialise(Scene scene, IConfigSource config) | 82 | public void Initialise(Scene scene, IConfigSource config) |
83 | { | 83 | { |
84 | m_scene = scene; | 84 | m_scene = scene; |
85 | m_scene.RegisterModuleInterface<IWorldComm>(this); | 85 | m_scene.RegisterModuleInterface<IWorldComm>(this); |
86 | m_listenerManager = new ListenerManager(); | 86 | m_listenerManager = new ListenerManager(); |
87 | m_scene.EventManager.OnNewClient += NewClient; | 87 | m_scene.EventManager.OnNewClient += NewClient; |
88 | m_pendingQ = new Queue(); | 88 | m_pendingQ = new Queue(); |
89 | m_pending = Queue.Synchronized(m_pendingQ); | 89 | m_pending = Queue.Synchronized(m_pendingQ); |
90 | } | 90 | } |
91 | 91 | ||
92 | public void PostInitialise() | 92 | public void PostInitialise() |
93 | { | 93 | { |
94 | } | 94 | } |
95 | 95 | ||
96 | public void Close() | 96 | public void Close() |
97 | { | 97 | { |
98 | } | 98 | } |
99 | 99 | ||
100 | public string Name | 100 | public string Name |
101 | { | 101 | { |
102 | get { return m_name; } | 102 | get { return m_name; } |
103 | } | 103 | } |
104 | 104 | ||
105 | public bool IsSharedModule | 105 | public bool IsSharedModule |
106 | { | 106 | { |
107 | get { return false; } | 107 | get { return false; } |
108 | } | 108 | } |
109 | 109 | ||
110 | public void NewClient(IClientAPI client) | 110 | public void NewClient(IClientAPI client) |
111 | { | 111 | { |
112 | client.OnChatFromViewer += DeliverClientMessage; | 112 | client.OnChatFromViewer += DeliverClientMessage; |
113 | } | 113 | } |
114 | 114 | ||
115 | /******************************************************************** | 115 | /******************************************************************** |
116 | * | 116 | * |
117 | * Listener Stuff | 117 | * Listener Stuff |
118 | * | 118 | * |
119 | * *****************************************************************/ | 119 | * *****************************************************************/ |
120 | private void DeliverClientMessage(Object sender, ChatFromViewerArgs e) | 120 | private void DeliverClientMessage(Object sender, ChatFromViewerArgs e) |
121 | { | 121 | { |
122 | DeliverMessage(e.Sender.AgentId.ToString(), | 122 | DeliverMessage(e.Sender.AgentId.ToString(), |
123 | e.Type, e.Channel, | 123 | e.Type, e.Channel, |
124 | e.Sender.FirstName + " " + e.Sender.LastName, | 124 | e.Sender.FirstName + " " + e.Sender.LastName, |
125 | e.Message); | 125 | e.Message); |
126 | } | 126 | } |
127 | 127 | ||
128 | public int Listen(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) | 128 | public int Listen(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) |
129 | { | 129 | { |
130 | return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); | 130 | return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); |
131 | } | 131 | } |
132 | 132 | ||
133 | public void ListenControl(int handle, int active) | 133 | public void ListenControl(int handle, int active) |
134 | { | 134 | { |
135 | if (m_listenerManager != null) | 135 | if (m_listenerManager != null) |
136 | { | 136 | { |
137 | if (active == 1) | 137 | if (active == 1) |
138 | m_listenerManager.Activate(handle); | 138 | m_listenerManager.Activate(handle); |
139 | else if (active == 0) | 139 | else if (active == 0) |
140 | m_listenerManager.Dectivate(handle); | 140 | m_listenerManager.Dectivate(handle); |
141 | } | 141 | } |
142 | } | 142 | } |
143 | 143 | ||
144 | public void ListenRemove(int handle) | 144 | public void ListenRemove(int handle) |
145 | { | 145 | { |
146 | if (m_listenerManager != null) | 146 | if (m_listenerManager != null) |
147 | { | 147 | { |
148 | m_listenerManager.Remove(handle); | 148 | m_listenerManager.Remove(handle); |
149 | } | 149 | } |
150 | } | 150 | } |
151 | 151 | ||
152 | public void DeleteListener(LLUUID itemID) | 152 | public void DeleteListener(LLUUID itemID) |
153 | { | 153 | { |
154 | if (m_listenerManager != null) | 154 | if (m_listenerManager != null) |
155 | { | 155 | { |
156 | m_listenerManager.DeleteListener(itemID); | 156 | m_listenerManager.DeleteListener(itemID); |
157 | } | 157 | } |
158 | } | 158 | } |
159 | 159 | ||
160 | // This method scans nearby objects and determines if they are listeners, | 160 | // This method scans nearby objects and determines if they are listeners, |
161 | // and if so if this message fits the filter. If it does, then | 161 | // and if so if this message fits the filter. If it does, then |
162 | // enqueue the message for delivery to the objects listen event handler. | 162 | // enqueue the message for delivery to the objects listen event handler. |
163 | // Objects that do an llSay have their messages delivered here, and for | 163 | // Objects that do an llSay have their messages delivered here, and for |
164 | // nearby avatars, the SimChat function is used. | 164 | // nearby avatars, the SimChat function is used. |
165 | public void DeliverMessage(string sourceItemID, ChatTypeEnum type, int channel, string name, string msg) | 165 | public void DeliverMessage(string sourceItemID, ChatTypeEnum type, int channel, string name, string msg) |
166 | { | 166 | { |
167 | SceneObjectPart source = null; | 167 | SceneObjectPart source = null; |
168 | ScenePresence avatar = null; | 168 | ScenePresence avatar = null; |
169 | 169 | ||
170 | source = m_scene.GetSceneObjectPart(new LLUUID(sourceItemID)); | 170 | source = m_scene.GetSceneObjectPart(new LLUUID(sourceItemID)); |
171 | if (source == null) | 171 | if (source == null) |
172 | { | 172 | { |
173 | avatar = m_scene.GetScenePresence(new LLUUID(sourceItemID)); | 173 | avatar = m_scene.GetScenePresence(new LLUUID(sourceItemID)); |
174 | } | 174 | } |
175 | if ((avatar != null) || (source != null)) | 175 | if ((avatar != null) || (source != null)) |
176 | { | 176 | { |
177 | // Loop through the objects in the scene | 177 | // Loop through the objects in the scene |
178 | // If they are in proximity, then if they are | 178 | // If they are in proximity, then if they are |
179 | // listeners, if so add them to the pending queue | 179 | // listeners, if so add them to the pending queue |
180 | 180 | ||
181 | foreach (ListenerInfo li in m_listenerManager.GetListeners()) | 181 | foreach (ListenerInfo li in m_listenerManager.GetListeners()) |
182 | { | 182 | { |
183 | EntityBase sPart; | 183 | EntityBase sPart; |
184 | 184 | ||
185 | m_scene.Entities.TryGetValue(li.GetHostID(), out sPart); | 185 | m_scene.Entities.TryGetValue(li.GetHostID(), out sPart); |
186 | 186 | ||
187 | if (sPart != null) | 187 | if (sPart != null) |
188 | { | 188 | { |
189 | double dis = 0; | 189 | double dis = 0; |
190 | 190 | ||
191 | if (source != null) | 191 | if (source != null) |
192 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, source.AbsolutePosition); | 192 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, source.AbsolutePosition); |
193 | else | 193 | else |
194 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, avatar.AbsolutePosition); | 194 | dis = Util.GetDistanceTo(sPart.AbsolutePosition, avatar.AbsolutePosition); |
195 | 195 | ||
196 | switch (type) | 196 | switch (type) |
197 | { | 197 | { |
198 | case ChatTypeEnum.Whisper: | 198 | case ChatTypeEnum.Whisper: |
199 | 199 | ||
200 | if ((dis < 10) && (dis > -10)) | 200 | if ((dis < 10) && (dis > -10)) |
201 | { | 201 | { |
202 | if (li.GetChannel() == channel) | 202 | if (li.GetChannel() == channel) |
203 | { | 203 | { |
204 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 204 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
205 | sourceItemID, sPart.UUID, channel, name, msg | 205 | sourceItemID, sPart.UUID, channel, name, msg |
206 | ); | 206 | ); |
207 | if (isListener != null) | 207 | if (isListener != null) |
208 | { | 208 | { |
209 | lock (m_pending.SyncRoot) | 209 | lock (m_pending.SyncRoot) |
210 | { | 210 | { |
211 | m_pending.Enqueue(isListener); | 211 | m_pending.Enqueue(isListener); |
212 | } | 212 | } |
213 | } | 213 | } |
214 | } | 214 | } |
215 | } | 215 | } |
216 | break; | 216 | break; |
217 | 217 | ||
218 | case ChatTypeEnum.Say: | 218 | case ChatTypeEnum.Say: |
219 | 219 | ||
220 | if ((dis < 30) && (dis > -30)) | 220 | if ((dis < 30) && (dis > -30)) |
221 | { | 221 | { |
222 | if (li.GetChannel() == channel) | 222 | if (li.GetChannel() == channel) |
223 | { | 223 | { |
224 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 224 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
225 | sourceItemID, sPart.UUID, channel, name, msg | 225 | sourceItemID, sPart.UUID, channel, name, msg |
226 | ); | 226 | ); |
227 | if (isListener != null) | 227 | if (isListener != null) |
228 | { | 228 | { |
229 | lock (m_pending.SyncRoot) | 229 | lock (m_pending.SyncRoot) |
230 | { | 230 | { |
231 | m_pending.Enqueue(isListener); | 231 | m_pending.Enqueue(isListener); |
232 | } | 232 | } |
233 | } | 233 | } |
234 | } | 234 | } |
235 | } | 235 | } |
236 | break; | 236 | break; |
237 | 237 | ||
238 | case ChatTypeEnum.Shout: | 238 | case ChatTypeEnum.Shout: |
239 | if ((dis < 100) && (dis > -100)) | 239 | if ((dis < 100) && (dis > -100)) |
240 | { | 240 | { |
241 | if (li.GetChannel() == channel) | 241 | if (li.GetChannel() == channel) |
242 | { | 242 | { |
243 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 243 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
244 | sourceItemID, sPart.UUID, channel, name, msg | 244 | sourceItemID, sPart.UUID, channel, name, msg |
245 | ); | 245 | ); |
246 | if (isListener != null) | 246 | if (isListener != null) |
247 | { | 247 | { |
248 | lock (m_pending.SyncRoot) | 248 | lock (m_pending.SyncRoot) |
249 | { | 249 | { |
250 | m_pending.Enqueue(isListener); | 250 | m_pending.Enqueue(isListener); |
251 | } | 251 | } |
252 | } | 252 | } |
253 | } | 253 | } |
254 | } | 254 | } |
255 | break; | 255 | break; |
256 | 256 | ||
257 | case ChatTypeEnum.Broadcast: | 257 | case ChatTypeEnum.Broadcast: |
258 | // Dont process if this message is from itself! | 258 | // Dont process if this message is from itself! |
259 | if (li.GetHostID().ToString().Equals(sourceItemID) || | 259 | if (li.GetHostID().ToString().Equals(sourceItemID) || |
260 | sPart.UUID.ToString().Equals(sourceItemID)) | 260 | sPart.UUID.ToString().Equals(sourceItemID)) |
261 | continue; | 261 | continue; |
262 | 262 | ||
263 | if (li.GetChannel() == channel) | 263 | if (li.GetChannel() == channel) |
264 | { | 264 | { |
265 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( | 265 | ListenerInfo isListener = m_listenerManager.IsListenerMatch( |
266 | sourceItemID, sPart.UUID, channel, name, msg | 266 | sourceItemID, sPart.UUID, channel, name, msg |
267 | ); | 267 | ); |
268 | if (isListener != null) | 268 | if (isListener != null) |
269 | { | 269 | { |
270 | lock (m_pending.SyncRoot) | 270 | lock (m_pending.SyncRoot) |
271 | { | 271 | { |
272 | m_pending.Enqueue(isListener); | 272 | m_pending.Enqueue(isListener); |
273 | } | 273 | } |
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
277 | break; | 277 | break; |
278 | } | 278 | } |
279 | } | 279 | } |
280 | } | 280 | } |
281 | } | 281 | } |
282 | } | 282 | } |
283 | 283 | ||
284 | public bool HasMessages() | 284 | public bool HasMessages() |
285 | { | 285 | { |
286 | if (m_pending != null) | 286 | if (m_pending != null) |
287 | return (m_pending.Count > 0); | 287 | return (m_pending.Count > 0); |
288 | else | 288 | else |
289 | return false; | 289 | return false; |
290 | } | 290 | } |
291 | 291 | ||
292 | public ListenerInfo GetNextMessage() | 292 | public ListenerInfo GetNextMessage() |
293 | { | 293 | { |
294 | ListenerInfo li = null; | 294 | ListenerInfo li = null; |
295 | 295 | ||
296 | lock (m_pending.SyncRoot) | 296 | lock (m_pending.SyncRoot) |
297 | { | 297 | { |
298 | li = (ListenerInfo)m_pending.Dequeue(); | 298 | li = (ListenerInfo)m_pending.Dequeue(); |
299 | } | 299 | } |
300 | 300 | ||
301 | return li; | 301 | return li; |
302 | } | 302 | } |
303 | 303 | ||
304 | public uint PeekNextMessageLocalID() | 304 | public uint PeekNextMessageLocalID() |
305 | { | 305 | { |
306 | return ((ListenerInfo)m_pending.Peek()).GetLocalID(); | 306 | return ((ListenerInfo)m_pending.Peek()).GetLocalID(); |
307 | } | 307 | } |
308 | 308 | ||
309 | public LLUUID PeekNextMessageItemID() | 309 | public LLUUID PeekNextMessageItemID() |
310 | { | 310 | { |
311 | return ((ListenerInfo)m_pending.Peek()).GetItemID(); | 311 | return ((ListenerInfo)m_pending.Peek()).GetItemID(); |
312 | } | 312 | } |
313 | } | 313 | } |
314 | 314 | ||
315 | /********************************************************** | 315 | public class ListenerManager |
316 | * | 316 | { |
317 | * Even more listener stuff | 317 | //private Dictionary<int, ListenerInfo> m_listeners; |
318 | * | 318 | private Hashtable m_listeners = Hashtable.Synchronized(new Hashtable()); |
319 | * ********************************************************/ | 319 | private object ListenersLock = new object(); |
320 | public class ListenerManager | 320 | private int m_MaxListeners = 100; |
321 | { | 321 | |
322 | //private Dictionary<int, ListenerInfo> m_listeners; | 322 | public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) |
323 | private Hashtable m_listeners = Hashtable.Synchronized(new Hashtable()); | 323 | { |
324 | private object ListenersLock = new object(); | 324 | if (m_listeners.Count < m_MaxListeners) |
325 | private int m_MaxListeners = 100; | 325 | { |
326 | 326 | ListenerInfo isListener = IsListenerMatch(LLUUID.Zero.ToString(), itemID, channel, name, msg); | |
327 | public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg) | 327 | |
328 | { | 328 | if (isListener == null) |
329 | if (m_listeners.Count < m_MaxListeners) | 329 | { |
330 | { | 330 | int newHandle = GetNewHandle(); |
331 | ListenerInfo isListener = IsListenerMatch(LLUUID.Zero.ToString(), itemID, channel, name, msg); | 331 | |
332 | 332 | if (newHandle > -1) | |
333 | if (isListener == null) | 333 | { |
334 | { | 334 | ListenerInfo li = new ListenerInfo(localID, newHandle, itemID, hostID, channel, name, id, msg); |
335 | int newHandle = GetNewHandle(); | 335 | |
336 | 336 | lock (m_listeners.SyncRoot) | |
337 | if (newHandle > -1) | 337 | { |
338 | { | 338 | m_listeners.Add(newHandle, li); |
339 | ListenerInfo li = new ListenerInfo(localID, newHandle, itemID, hostID, channel, name, id, msg); | 339 | } |
340 | 340 | ||
341 | lock (m_listeners.SyncRoot) | 341 | return newHandle; |
342 | { | 342 | } |
343 | m_listeners.Add(newHandle, li); | 343 | } |
344 | } | 344 | } |
345 | 345 | ||
346 | return newHandle; | 346 | return -1; |
347 | } | 347 | } |
348 | } | 348 | |
349 | } | 349 | public void Remove(int handle) |
350 | 350 | { | |
351 | return -1; | 351 | lock (m_listeners.SyncRoot) |
352 | } | 352 | { |
353 | 353 | m_listeners.Remove(handle); | |
354 | public void Remove(int handle) | 354 | } |
355 | { | 355 | } |
356 | lock (m_listeners.SyncRoot) | 356 | |
357 | { | 357 | public void DeleteListener(LLUUID itemID) |
358 | m_listeners.Remove(handle); | 358 | { |
359 | } | 359 | ArrayList removedListeners = new ArrayList(); |
360 | } | 360 | |
361 | 361 | lock (m_listeners.SyncRoot) | |
362 | public void DeleteListener(LLUUID itemID) | 362 | { |
363 | { | 363 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); |
364 | ArrayList removedListeners = new ArrayList(); | 364 | while (en.MoveNext()) |
365 | 365 | { | |
366 | lock (m_listeners.SyncRoot) | 366 | ListenerInfo li = (ListenerInfo)en.Value; |
367 | { | 367 | if (li.GetItemID().Equals(itemID)) |
368 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); | 368 | { |
369 | while (en.MoveNext()) | 369 | removedListeners.Add(li.GetHandle()); |
370 | { | 370 | } |
371 | ListenerInfo li = (ListenerInfo)en.Value; | 371 | } |
372 | if (li.GetItemID().Equals(itemID)) | 372 | foreach (int handle in removedListeners) |
373 | { | 373 | { |
374 | removedListeners.Add(li.GetHandle()); | 374 | m_listeners.Remove(handle); |
375 | } | 375 | } |
376 | } | 376 | } |
377 | foreach (int handle in removedListeners) | 377 | } |
378 | { | 378 | |
379 | m_listeners.Remove(handle); | 379 | private int GetNewHandle() |
380 | } | 380 | { |
381 | } | 381 | for (int i = 0; i < int.MaxValue - 1; i++) |
382 | } | 382 | { |
383 | 383 | if (!m_listeners.ContainsKey(i)) | |
384 | private int GetNewHandle() | 384 | return i; |
385 | { | 385 | } |
386 | for (int i = 0; i < int.MaxValue - 1; i++) | 386 | |
387 | { | 387 | return -1; |
388 | if (!m_listeners.ContainsKey(i)) | 388 | } |
389 | return i; | 389 | |
390 | } | 390 | public bool IsListener(LLUUID hostID) |
391 | 391 | { | |
392 | return -1; | 392 | foreach (ListenerInfo li in m_listeners.Values) |
393 | } | 393 | { |
394 | 394 | if (li.GetHostID().Equals(hostID)) | |
395 | public bool IsListener(LLUUID hostID) | 395 | return true; |
396 | { | 396 | } |
397 | foreach (ListenerInfo li in m_listeners.Values) | 397 | |
398 | { | 398 | return false; |
399 | if (li.GetHostID().Equals(hostID)) | 399 | } |
400 | return true; | 400 | |
401 | } | 401 | public void Activate(int handle) |
402 | 402 | { | |
403 | return false; | 403 | |
404 | } | 404 | if (m_listeners.ContainsKey(handle)) |
405 | 405 | { | |
406 | public void Activate(int handle) | 406 | lock (m_listeners.SyncRoot) |
407 | { | 407 | { |
408 | 408 | ListenerInfo li = (ListenerInfo)m_listeners[handle]; | |
409 | if (m_listeners.ContainsKey(handle)) | 409 | li.Activate(); |
410 | { | 410 | } |
411 | lock (m_listeners.SyncRoot) | 411 | } |
412 | { | 412 | } |
413 | ListenerInfo li = (ListenerInfo)m_listeners[handle]; | 413 | |
414 | li.Activate(); | 414 | public void Dectivate(int handle) |
415 | } | 415 | { |
416 | } | 416 | |
417 | } | 417 | if (m_listeners.ContainsKey(handle)) |
418 | 418 | { | |
419 | public void Dectivate(int handle) | 419 | ListenerInfo li = (ListenerInfo)m_listeners[handle]; |
420 | { | 420 | li.Deactivate(); |
421 | 421 | } | |
422 | if (m_listeners.ContainsKey(handle)) | 422 | } |
423 | { | 423 | |
424 | ListenerInfo li = (ListenerInfo)m_listeners[handle]; | 424 | // Theres probably a more clever and efficient way to |
425 | li.Deactivate(); | 425 | // do this, maybe with regex. |
426 | } | 426 | public ListenerInfo IsListenerMatch(string sourceItemID, LLUUID listenerKey, int channel, string name, |
427 | } | 427 | string msg) |
428 | 428 | { | |
429 | // Theres probably a more clever and efficient way to | 429 | bool isMatch = true; |
430 | // do this, maybe with regex. | 430 | lock (m_listeners.SyncRoot) |
431 | public ListenerInfo IsListenerMatch(string sourceItemID, LLUUID listenerKey, int channel, string name, | 431 | { |
432 | string msg) | 432 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); |
433 | { | 433 | while (en.MoveNext()) |
434 | bool isMatch = true; | 434 | { |
435 | lock (m_listeners.SyncRoot) | 435 | ListenerInfo li = (ListenerInfo)en.Value; |
436 | { | 436 | |
437 | IDictionaryEnumerator en = m_listeners.GetEnumerator(); | 437 | if (li.IsActive()) |
438 | while (en.MoveNext()) | 438 | { |
439 | { | 439 | if (li.GetHostID().Equals(listenerKey)) |
440 | ListenerInfo li = (ListenerInfo)en.Value; | 440 | { |
441 | 441 | if (channel == li.GetChannel()) | |
442 | if (li.IsActive()) | 442 | { |
443 | { | 443 | if ((li.GetID().ToString().Length > 0) && |
444 | if (li.GetHostID().Equals(listenerKey)) | 444 | (!li.GetID().Equals(LLUUID.Zero))) |
445 | { | 445 | { |
446 | if (channel == li.GetChannel()) | 446 | if (!li.GetID().ToString().Equals(sourceItemID)) |
447 | { | 447 | { |
448 | if ((li.GetID().ToString().Length > 0) && | 448 | isMatch = false; |
449 | (!li.GetID().Equals(LLUUID.Zero))) | 449 | } |
450 | { | 450 | } |
451 | if (!li.GetID().ToString().Equals(sourceItemID)) | 451 | if (isMatch && (li.GetName().Length > 0)) |
452 | { | 452 | { |
453 | isMatch = false; | 453 | if (li.GetName().Equals(name)) |
454 | } | 454 | { |
455 | } | 455 | isMatch = false; |
456 | if (isMatch && (li.GetName().Length > 0)) | 456 | } |
457 | { | 457 | } |
458 | if (li.GetName().Equals(name)) | 458 | if (isMatch) |
459 | { | 459 | { |
460 | isMatch = false; | 460 | return new ListenerInfo( |
461 | } | 461 | li.GetLocalID(), li.GetHandle(), li.GetItemID(), li.GetHostID(), |
462 | } | 462 | li.GetChannel(), name, li.GetID(), msg, new LLUUID(sourceItemID) |
463 | if (isMatch) | 463 | ); |
464 | { | 464 | } |
465 | return new ListenerInfo( | 465 | } |
466 | li.GetLocalID(), li.GetHandle(), li.GetItemID(), li.GetHostID(), | 466 | } |
467 | li.GetChannel(), name, li.GetID(), msg, new LLUUID(sourceItemID) | 467 | } |
468 | ); | 468 | } |
469 | } | 469 | } |
470 | } | 470 | return null; |
471 | } | 471 | } |
472 | } | 472 | |
473 | } | 473 | public ICollection GetListeners() |
474 | } | 474 | { |
475 | return null; | 475 | return m_listeners.Values; |
476 | } | 476 | } |
477 | 477 | } | |
478 | public ICollection GetListeners() | 478 | |
479 | { | 479 | public class ListenerInfo |
480 | return m_listeners.Values; | 480 | { |
481 | } | 481 | private LLUUID m_itemID; // ID of the host script engine |
482 | } | 482 | private LLUUID m_hostID; // ID of the host/scene part |
483 | 483 | private LLUUID m_sourceItemID; // ID of the scenePart or avatar source of the message | |
484 | public class ListenerInfo | 484 | private int m_channel; // Channel |
485 | { | 485 | private int m_handle; // Assigned handle of this listener |
486 | private LLUUID m_itemID; // ID of the host script engine | 486 | private uint m_localID; // Local ID from script engine |
487 | private LLUUID m_hostID; // ID of the host/scene part | 487 | private string m_name; // Object name to filter messages from |
488 | private LLUUID m_sourceItemID; // ID of the scenePart or avatar source of the message | 488 | private LLUUID m_id; // ID to filter messages from |
489 | private int m_channel; // Channel | 489 | private string m_message; // The message |
490 | private int m_handle; // Assigned handle of this listener | 490 | private bool m_active; // Listener is active or not |
491 | private uint m_localID; // Local ID from script engine | 491 | |
492 | private string m_name; // Object name to filter messages from | 492 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message) |
493 | private LLUUID m_id; // ID to filter messages from | 493 | { |
494 | private string m_message; // The message | 494 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); |
495 | private bool m_active; // Listener is active or not | 495 | } |
496 | 496 | ||
497 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message) | 497 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, |
498 | { | 498 | string message, LLUUID sourceItemID) |
499 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); | 499 | { |
500 | } | 500 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); |
501 | 501 | m_sourceItemID = sourceItemID; | |
502 | public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, | 502 | } |
503 | string message, LLUUID sourceItemID) | 503 | |
504 | { | 504 | private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, |
505 | Initialise(localID, handle, ItemID, hostID, channel, name, id, message); | 505 | LLUUID id, string message) |
506 | m_sourceItemID = sourceItemID; | 506 | { |
507 | } | 507 | m_handle = handle; |
508 | 508 | m_channel = channel; | |
509 | private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, | 509 | m_itemID = ItemID; |
510 | LLUUID id, string message) | 510 | m_hostID = hostID; |
511 | { | 511 | m_name = name; |
512 | m_handle = handle; | 512 | m_id = id; |
513 | m_channel = channel; | 513 | m_message = message; |
514 | m_itemID = ItemID; | 514 | m_active = true; |
515 | m_hostID = hostID; | 515 | m_localID = localID; |
516 | m_name = name; | 516 | } |
517 | m_id = id; | 517 | |
518 | m_message = message; | 518 | public LLUUID GetItemID() |
519 | m_active = true; | 519 | { |
520 | m_localID = localID; | 520 | return m_itemID; |
521 | } | 521 | } |
522 | 522 | ||
523 | public LLUUID GetItemID() | 523 | public LLUUID GetHostID() |
524 | { | 524 | { |
525 | return m_itemID; | 525 | return m_hostID; |
526 | } | 526 | } |
527 | 527 | ||
528 | public LLUUID GetHostID() | 528 | public LLUUID GetSourceItemID() |
529 | { | 529 | { |
530 | return m_hostID; | 530 | return m_sourceItemID; |
531 | } | 531 | } |
532 | 532 | ||
533 | public LLUUID GetSourceItemID() | 533 | public int GetChannel() |
534 | { | 534 | { |
535 | return m_sourceItemID; | 535 | return m_channel; |
536 | } | 536 | } |
537 | 537 | ||
538 | public int GetChannel() | 538 | public uint GetLocalID() |
539 | { | 539 | { |
540 | return m_channel; | 540 | return m_localID; |
541 | } | 541 | } |
542 | 542 | ||
543 | public uint GetLocalID() | 543 | public int GetHandle() |
544 | { | 544 | { |
545 | return m_localID; | 545 | return m_handle; |
546 | } | 546 | } |
547 | 547 | ||
548 | public int GetHandle() | 548 | public string GetMessage() |
549 | { | 549 | { |
550 | return m_handle; | 550 | return m_message; |
551 | } | 551 | } |
552 | 552 | ||
553 | public string GetMessage() | 553 | public string GetName() |
554 | { | 554 | { |
555 | return m_message; | 555 | return m_name; |
556 | } | 556 | } |
557 | 557 | ||
558 | public string GetName() | 558 | public bool IsActive() |
559 | { | 559 | { |
560 | return m_name; | 560 | return m_active; |
561 | } | 561 | } |
562 | 562 | ||
563 | public bool IsActive() | 563 | public void Deactivate() |
564 | { | 564 | { |
565 | return m_active; | 565 | m_active = false; |
566 | } | 566 | } |
567 | 567 | ||
568 | public void Deactivate() | 568 | public void Activate() |
569 | { | 569 | { |
570 | m_active = false; | 570 | m_active = true; |
571 | } | 571 | } |
572 | 572 | ||
573 | public void Activate() | 573 | public LLUUID GetID() |
574 | { | 574 | { |
575 | m_active = true; | 575 | return m_id; |
576 | } | 576 | } |
577 | 577 | } | |
578 | public LLUUID GetID() | 578 | } \ No newline at end of file |
579 | { | ||
580 | return m_id; | ||
581 | } | ||
582 | } | ||
583 | |||
584 | } | ||