aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
diff options
context:
space:
mode:
authorDr Scofield2009-02-10 13:10:57 +0000
committerDr Scofield2009-02-10 13:10:57 +0000
commit180be7de07014aa33bc6066f12a0819b731c1c9d (patch)
tree3aa13af3cda4b808fa9453655875327699b61311 /OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
parentStopgap measure: To use gridlaunch, or GUI, start opensim with (diff)
downloadopensim-SC_OLD-180be7de07014aa33bc6066f12a0819b731c1c9d.zip
opensim-SC_OLD-180be7de07014aa33bc6066f12a0819b731c1c9d.tar.gz
opensim-SC_OLD-180be7de07014aa33bc6066f12a0819b731c1c9d.tar.bz2
opensim-SC_OLD-180be7de07014aa33bc6066f12a0819b731c1c9d.tar.xz
this is step 2 of 2 of the OpenSim.Region.Environment refactor.
NOTHING has been deleted or moved off to forge at this point. what has happened is that OpenSim.Region.Environment.Modules has been split in two: - OpenSim.Region.CoreModules: all those modules that are either directly or indirectly referenced from other OpenSim packages, or that provide functionality that the OpenSim developer community considers core functionality: CoreModules/Agent/AssetTransaction CoreModules/Agent/Capabilities CoreModules/Agent/TextureDownload CoreModules/Agent/TextureSender CoreModules/Agent/TextureSender/Tests CoreModules/Agent/Xfer CoreModules/Avatar/AvatarFactory CoreModules/Avatar/Chat/ChatModule CoreModules/Avatar/Combat CoreModules/Avatar/Currency/SampleMoney CoreModules/Avatar/Dialog CoreModules/Avatar/Friends CoreModules/Avatar/Gestures CoreModules/Avatar/Groups CoreModules/Avatar/InstantMessage CoreModules/Avatar/Inventory CoreModules/Avatar/Inventory/Archiver CoreModules/Avatar/Inventory/Transfer CoreModules/Avatar/Lure CoreModules/Avatar/ObjectCaps CoreModules/Avatar/Profiles CoreModules/Communications/Local CoreModules/Communications/REST CoreModules/Framework/EventQueue CoreModules/Framework/InterfaceCommander CoreModules/Hypergrid CoreModules/InterGrid CoreModules/Scripting/DynamicTexture CoreModules/Scripting/EMailModules CoreModules/Scripting/HttpRequest CoreModules/Scripting/LoadImageURL CoreModules/Scripting/VectorRender CoreModules/Scripting/WorldComm CoreModules/Scripting/XMLRPC CoreModules/World/Archiver CoreModules/World/Archiver/Tests CoreModules/World/Estate CoreModules/World/Land CoreModules/World/Permissions CoreModules/World/Serialiser CoreModules/World/Sound CoreModules/World/Sun CoreModules/World/Terrain CoreModules/World/Terrain/DefaultEffects CoreModules/World/Terrain/DefaultEffects/bin CoreModules/World/Terrain/DefaultEffects/bin/Debug CoreModules/World/Terrain/Effects CoreModules/World/Terrain/FileLoaders CoreModules/World/Terrain/FloodBrushes CoreModules/World/Terrain/PaintBrushes CoreModules/World/Terrain/Tests CoreModules/World/Vegetation CoreModules/World/Wind CoreModules/World/WorldMap - OpenSim.Region.OptionalModules: all those modules that are not core modules: OptionalModules/Avatar/Chat/IRC-stuff OptionalModules/Avatar/Concierge OptionalModules/Avatar/Voice/AsterixVoice OptionalModules/Avatar/Voice/SIPVoice OptionalModules/ContentManagementSystem OptionalModules/Grid/Interregion OptionalModules/Python OptionalModules/SvnSerialiser OptionalModules/World/NPC OptionalModules/World/TreePopulator
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs726
1 files changed, 726 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
new file mode 100644
index 0000000..c363940
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -0,0 +1,726 @@
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 OpenSim 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.Collections;
30using System.Collections.Generic;
31using OpenMetaverse;
32using Nini.Config;
33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes;
36
37// using log4net;
38// using System.Reflection;
39
40
41/*****************************************************
42 *
43 * WorldCommModule
44 *
45 *
46 * Holding place for world comms - basically llListen
47 * function implementation.
48 *
49 * lLListen(integer channel, string name, key id, string msg)
50 * The name, id, and msg arguments specify the filtering
51 * criteria. You can pass the empty string
52 * (or NULL_KEY for id) for these to set a completely
53 * open filter; this causes the listen() event handler to be
54 * invoked for all chat on the channel. To listen only
55 * for chat spoken by a specific object or avatar,
56 * specify the name and/or id arguments. To listen
57 * only for a specific command, specify the
58 * (case-sensitive) msg argument. If msg is not empty,
59 * listener will only hear strings which are exactly equal
60 * to msg. You can also use all the arguments to establish
61 * the most restrictive filtering criteria.
62 *
63 * It might be useful for each listener to maintain a message
64 * digest, with a list of recent messages by UUID. This can
65 * be used to prevent in-world repeater loops. However, the
66 * linden functions do not have this capability, so for now
67 * thats the way it works.
68 * Instead it blocks messages originating from the same prim.
69 * (not Object!)
70 *
71 * For LSL compliance, note the following:
72 * (Tested again 1.21.1 on May 2, 2008)
73 * 1. 'id' has to be parsed into a UUID. None-UUID keys are
74 * to be replaced by the ZeroID key. (Well, TryParse does
75 * that for us.
76 * 2. Setting up an listen event from the same script, with the
77 * same filter settings (including step 1), returns the same
78 * handle as the original filter.
79 * 3. (TODO) handles should be script-local. Starting from 1.
80 * Might be actually easier to map the global handle into
81 * script-local handle in the ScriptEngine. Not sure if its
82 * worth the effort tho.
83 *
84 * **************************************************/
85
86namespace OpenSim.Region.CoreModules.Scripting.WorldComm
87{
88 public class WorldCommModule : IRegionModule, IWorldComm
89 {
90 // private static readonly ILog m_log =
91 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
92
93 private ListenerManager m_listenerManager;
94 private Queue m_pending;
95 private Queue m_pendingQ;
96 private Scene m_scene;
97 private int m_whisperdistance = 10;
98 private int m_saydistance = 30;
99 private int m_shoutdistance = 100;
100
101 #region IRegionModule Members
102
103 public void Initialise(Scene scene, IConfigSource config)
104 {
105 // wrap this in a try block so that defaults will work if
106 // the config file doesn't specify otherwise.
107 int maxlisteners = 1000;
108 int maxhandles = 64;
109 try
110 {
111 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
112 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
113 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
114 maxlisteners = config.Configs["Chat"].GetInt("max_listens_per_region", maxlisteners);
115 maxhandles = config.Configs["Chat"].GetInt("max_listens_per_script", maxhandles);
116 }
117 catch (Exception)
118 {
119 }
120 if (maxlisteners < 1) maxlisteners = int.MaxValue;
121 if (maxhandles < 1) maxhandles = int.MaxValue;
122
123 m_scene = scene;
124 m_scene.RegisterModuleInterface<IWorldComm>(this);
125 m_listenerManager = new ListenerManager(maxlisteners, maxhandles);
126 m_scene.EventManager.OnChatFromClient += DeliverClientMessage;
127 m_scene.EventManager.OnChatBroadcast += DeliverClientMessage;
128 m_pendingQ = new Queue();
129 m_pending = Queue.Synchronized(m_pendingQ);
130 }
131
132 public void PostInitialise()
133 {
134 }
135
136 public void Close()
137 {
138 }
139
140 public string Name
141 {
142 get { return "WorldCommModule"; }
143 }
144
145 public bool IsSharedModule
146 {
147 get { return false; }
148 }
149
150 #endregion
151
152 #region IWorldComm Members
153
154 /// <summary>
155 /// Create a listen event callback with the specified filters.
156 /// The parameters localID,itemID are needed to uniquely identify
157 /// the script during 'peek' time. Parameter hostID is needed to
158 /// determine the position of the script.
159 /// </summary>
160 /// <param name="localID">localID of the script engine</param>
161 /// <param name="itemID">UUID of the script engine</param>
162 /// <param name="hostID">UUID of the SceneObjectPart</param>
163 /// <param name="channel">channel to listen on</param>
164 /// <param name="name">name to filter on</param>
165 /// <param name="id">key to filter on (user given, could be totally faked)</param>
166 /// <param name="msg">msg to filter on</param>
167 /// <returns>number of the scripts handle</returns>
168 public int Listen(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg)
169 {
170 return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg);
171 }
172
173 /// <summary>
174 /// Sets the listen event with handle as active (active = TRUE) or inactive (active = FALSE).
175 /// The handle used is returned from Listen()
176 /// </summary>
177 /// <param name="itemID">UUID of the script engine</param>
178 /// <param name="handle">handle returned by Listen()</param>
179 /// <param name="active">temp. activate or deactivate the Listen()</param>
180 public void ListenControl(UUID itemID, int handle, int active)
181 {
182 if (active == 1)
183 m_listenerManager.Activate(itemID, handle);
184 else if (active == 0)
185 m_listenerManager.Dectivate(itemID, handle);
186 }
187
188 /// <summary>
189 /// Removes the listen event callback with handle
190 /// </summary>
191 /// <param name="itemID">UUID of the script engine</param>
192 /// <param name="handle">handle returned by Listen()</param>
193 public void ListenRemove(UUID itemID, int handle)
194 {
195 m_listenerManager.Remove(itemID, handle);
196 }
197
198 /// <summary>
199 /// Removes all listen event callbacks for the given itemID
200 /// (script engine)
201 /// </summary>
202 /// <param name="itemID">UUID of the script engine</param>
203 public void DeleteListener(UUID itemID)
204 {
205 m_listenerManager.DeleteListener(itemID);
206 }
207
208
209 protected static Vector3 CenterOfRegion = new Vector3(128, 128, 20);
210
211 public void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg)
212 {
213 Vector3 position;
214 SceneObjectPart source;
215 ScenePresence avatar;
216
217 if ((source = m_scene.GetSceneObjectPart(id)) != null)
218 position = source.AbsolutePosition;
219 else if ((avatar = m_scene.GetScenePresence(id)) != null)
220 position = avatar.AbsolutePosition;
221 else if (ChatTypeEnum.Region == type)
222 position = CenterOfRegion;
223 else
224 return;
225
226 DeliverMessage(type, channel, name, id, msg, position);
227 }
228
229 /// <summary>
230 /// This method scans over the objects which registered an interest in listen callbacks.
231 /// For everyone it finds, it checks if it fits the given filter. If it does, then
232 /// enqueue the message for delivery to the objects listen event handler.
233 /// The enqueued ListenerInfo no longer has filter values, but the actually trigged values.
234 /// Objects that do an llSay have their messages delivered here and for nearby avatars,
235 /// the OnChatFromClient event is used.
236 /// </summary>
237 /// <param name="type">type of delvery (whisper,say,shout or regionwide)</param>
238 /// <param name="channel">channel to sent on</param>
239 /// <param name="name">name of sender (object or avatar)</param>
240 /// <param name="id">key of sender (object or avatar)</param>
241 /// <param name="msg">msg to sent</param>
242 public void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg, Vector3 position)
243 {
244 // m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}",
245 // type, channel, name, id, msg);
246
247 // Determine which listen event filters match the given set of arguments, this results
248 // in a limited set of listeners, each belonging a host. If the host is in range, add them
249 // to the pending queue.
250 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
251 {
252 // Dont process if this message is from yourself!
253 if (li.GetHostID().Equals(id))
254 continue;
255
256 SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID());
257 if (sPart == null)
258 continue;
259
260 double dis = Util.GetDistanceTo(sPart.AbsolutePosition, position);
261 switch (type)
262 {
263 case ChatTypeEnum.Whisper:
264 if (dis < m_whisperdistance)
265 {
266 lock (m_pending.SyncRoot)
267 {
268 m_pending.Enqueue(new ListenerInfo(li,name,id,msg));
269 }
270 }
271 break;
272
273 case ChatTypeEnum.Say:
274 if (dis < m_saydistance)
275 {
276 lock (m_pending.SyncRoot)
277 {
278 m_pending.Enqueue(new ListenerInfo(li,name,id,msg));
279 }
280 }
281 break;
282
283 case ChatTypeEnum.Shout:
284 if (dis < m_shoutdistance)
285 {
286 lock (m_pending.SyncRoot)
287 {
288 m_pending.Enqueue(new ListenerInfo(li,name,id,msg));
289 }
290 }
291 break;
292
293 case ChatTypeEnum.Region:
294 lock (m_pending.SyncRoot)
295 {
296 m_pending.Enqueue(new ListenerInfo(li,name,id,msg));
297 }
298 break;
299 }
300 }
301 }
302
303 /// <summary>
304 /// Are there any listen events ready to be dispatched?
305 /// </summary>
306 /// <returns>boolean indication</returns>
307 public bool HasMessages()
308 {
309 return (m_pending.Count > 0);
310 }
311
312 /// <summary>
313 /// Pop the first availlable listen event from the queue
314 /// </summary>
315 /// <returns>ListenerInfo with filter filled in</returns>
316 public IWorldCommListenerInfo GetNextMessage()
317 {
318 ListenerInfo li = null;
319
320 lock (m_pending.SyncRoot)
321 {
322 li = (ListenerInfo) m_pending.Dequeue();
323 }
324
325 return li;
326 }
327
328 #endregion
329
330 /********************************************************************
331 *
332 * Listener Stuff
333 *
334 * *****************************************************************/
335
336 private void DeliverClientMessage(Object sender, OSChatMessage e)
337 {
338 if (null != e.Sender)
339 DeliverMessage(e.Type, e.Channel, e.Sender.Name, e.Sender.AgentId, e.Message, e.Position);
340 else
341 DeliverMessage(e.Type, e.Channel, e.From, UUID.Zero, e.Message, e.Position);
342 }
343
344 public Object[] GetSerializationData(UUID itemID)
345 {
346 return m_listenerManager.GetSerializationData(itemID);
347 }
348
349 public void CreateFromData(uint localID, UUID itemID, UUID hostID,
350 Object[] data)
351 {
352 m_listenerManager.AddFromData(localID, itemID, hostID, data);
353 }
354 }
355
356 public class ListenerManager
357 {
358 private Dictionary<int, List<ListenerInfo>> m_listeners = new Dictionary<int, List<ListenerInfo>>();
359 private int m_maxlisteners;
360 private int m_maxhandles;
361 private int m_curlisteners;
362
363 public ListenerManager(int maxlisteners, int maxhandles)
364 {
365 m_maxlisteners = maxlisteners;
366 m_maxhandles = maxhandles;
367 m_curlisteners = 0;
368 }
369
370 public int AddListener(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg)
371 {
372 // do we already have a match on this particular filter event?
373 List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, msg);
374
375 if (coll.Count > 0)
376 {
377 // special case, called with same filter settings, return same handle
378 // (2008-05-02, tested on 1.21.1 server, still holds)
379 return coll[0].GetHandle();
380 }
381
382 if (m_curlisteners < m_maxlisteners)
383 {
384 int newHandle = GetNewHandle(itemID);
385
386 if (newHandle > 0)
387 {
388 ListenerInfo li = new ListenerInfo(newHandle, localID, itemID, hostID, channel, name, id, msg);
389
390 lock (m_listeners)
391 {
392 List<ListenerInfo> listeners;
393 if (!m_listeners.TryGetValue(channel,out listeners))
394 {
395 listeners = new List<ListenerInfo>();
396 m_listeners.Add(channel, listeners);
397 }
398 listeners.Add(li);
399 m_curlisteners++;
400 }
401
402 return newHandle;
403 }
404 }
405 return -1;
406 }
407
408 public void Remove(UUID itemID, int handle)
409 {
410 lock (m_listeners)
411 {
412 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners)
413 {
414 foreach (ListenerInfo li in lis.Value)
415 {
416 if (li.GetItemID().Equals(itemID) && li.GetHandle().Equals(handle))
417 {
418 lis.Value.Remove(li);
419 if (lis.Value.Count == 0)
420 {
421 m_listeners.Remove(lis.Key);
422 m_curlisteners--;
423 }
424 // there should be only one, so we bail out early
425 return;
426 }
427 }
428 }
429 }
430 }
431
432 public void DeleteListener(UUID itemID)
433 {
434 List<int> emptyChannels = new List<int>();
435 List<ListenerInfo> removedListeners = new List<ListenerInfo>();
436
437 lock (m_listeners)
438 {
439 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners)
440 {
441 foreach (ListenerInfo li in lis.Value)
442 {
443 if (li.GetItemID().Equals(itemID))
444 {
445 // store them first, else the enumerated bails on us
446 removedListeners.Add(li);
447 }
448 }
449 foreach (ListenerInfo li in removedListeners)
450 {
451 lis.Value.Remove(li);
452 m_curlisteners--;
453 }
454 removedListeners.Clear();
455 if (lis.Value.Count == 0)
456 {
457 // again, store first, remove later
458 emptyChannels.Add(lis.Key);
459 }
460 }
461 foreach (int channel in emptyChannels)
462 {
463 m_listeners.Remove(channel);
464 }
465 }
466 }
467
468 public void Activate(UUID itemID, int handle)
469 {
470 lock (m_listeners)
471 {
472 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners)
473 {
474 foreach (ListenerInfo li in lis.Value)
475 {
476 if (li.GetItemID().Equals(itemID) && li.GetHandle() == handle)
477 {
478 li.Activate();
479 // only one, bail out
480 return;
481 }
482 }
483 }
484 }
485 }
486
487 public void Dectivate(UUID itemID, int handle)
488 {
489 lock (m_listeners)
490 {
491 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners)
492 {
493 foreach (ListenerInfo li in lis.Value)
494 {
495 if (li.GetItemID().Equals(itemID) && li.GetHandle() == handle)
496 {
497 li.Deactivate();
498 // only one, bail out
499 return;
500 }
501 }
502 }
503 }
504 }
505
506 // non-locked access, since its always called in the context of the lock
507 private int GetNewHandle(UUID itemID)
508 {
509 List<int> handles = new List<int>();
510
511 // build a list of used keys for this specific itemID...
512 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners)
513 {
514 foreach (ListenerInfo li in lis.Value)
515 {
516 if (li.GetItemID().Equals(itemID))
517 handles.Add(li.GetHandle());
518 }
519 }
520
521 // Note: 0 is NOT a valid handle for llListen() to return
522 for (int i = 1; i <= m_maxhandles; i++)
523 {
524 if (!handles.Contains(i))
525 return i;
526 }
527
528 return -1;
529 }
530
531 // Theres probably a more clever and efficient way to
532 // do this, maybe with regex.
533 // PM2008: Ha, one could even be smart and define a specialized Enumerator.
534 public List<ListenerInfo> GetListeners(UUID itemID, int channel, string name, UUID id, string msg)
535 {
536 List<ListenerInfo> collection = new List<ListenerInfo>();
537
538 lock (m_listeners)
539 {
540 List<ListenerInfo> listeners;
541 if (!m_listeners.TryGetValue(channel,out listeners))
542 {
543 return collection;
544 }
545
546 foreach (ListenerInfo li in listeners)
547 {
548 if (!li.IsActive())
549 {
550 continue;
551 }
552 if (!itemID.Equals(UUID.Zero) && !li.GetItemID().Equals(itemID))
553 {
554 continue;
555 }
556 if (li.GetName().Length > 0 && !li.GetName().Equals(name))
557 {
558 continue;
559 }
560 if (!li.GetID().Equals(UUID.Zero) && !li.GetID().Equals(id))
561 {
562 continue;
563 }
564 if (li.GetMessage().Length > 0 && !li.GetMessage().Equals(msg))
565 {
566 continue;
567 }
568 collection.Add(li);
569 }
570 }
571 return collection;
572 }
573
574 public Object[] GetSerializationData(UUID itemID)
575 {
576 List<Object> data = new List<Object>();
577
578 foreach (List<ListenerInfo> list in m_listeners.Values)
579 {
580 foreach (ListenerInfo l in list)
581 {
582 if (l.GetItemID() == itemID)
583 data.AddRange(l.GetSerializationData());
584 }
585 }
586 return (Object[])data.ToArray();
587 }
588
589 public void AddFromData(uint localID, UUID itemID, UUID hostID,
590 Object[] data)
591 {
592 int idx = 0;
593 Object[] item = new Object[6];
594
595 while (idx < data.Length)
596 {
597 Array.Copy(data, idx, item, 0, 6);
598
599 ListenerInfo info =
600 ListenerInfo.FromData(localID, itemID, hostID, item);
601
602 if (!m_listeners.ContainsKey((int)item[2]))
603 m_listeners.Add((int)item[2], new List<ListenerInfo>());
604 m_listeners[(int)item[2]].Add(info);
605
606 idx+=6;
607 }
608 }
609 }
610
611 public class ListenerInfo: IWorldCommListenerInfo
612 {
613 private bool m_active; // Listener is active or not
614 private int m_handle; // Assigned handle of this listener
615 private uint m_localID; // Local ID from script engine
616 private UUID m_itemID; // ID of the host script engine
617 private UUID m_hostID; // ID of the host/scene part
618 private int m_channel; // Channel
619 private UUID m_id; // ID to filter messages from
620 private string m_name; // Object name to filter messages from
621 private string m_message; // The message
622
623 public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message)
624 {
625 Initialise(handle, localID, ItemID, hostID, channel, name, id, message);
626 }
627
628 public ListenerInfo(ListenerInfo li, string name, UUID id, string message)
629 {
630 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message);
631 }
632
633 private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name,
634 UUID id, string message)
635 {
636 m_active = true;
637 m_handle = handle;
638 m_localID = localID;
639 m_itemID = ItemID;
640 m_hostID = hostID;
641 m_channel = channel;
642 m_name = name;
643 m_id = id;
644 m_message = message;
645 }
646
647 public Object[] GetSerializationData()
648 {
649 Object[] data = new Object[6];
650
651 data[0] = m_active;
652 data[1] = m_handle;
653 data[2] = m_channel;
654 data[3] = m_name;
655 data[4] = m_id;
656 data[5] = m_message;
657
658 return data;
659 }
660
661 public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data)
662 {
663 ListenerInfo linfo = new ListenerInfo((int)data[1], localID,
664 ItemID, hostID, (int)data[2], (string)data[3],
665 (UUID)data[4], (string)data[5]);
666 linfo.m_active=(bool)data[0];
667
668 return linfo;
669 }
670
671 public UUID GetItemID()
672 {
673 return m_itemID;
674 }
675
676 public UUID GetHostID()
677 {
678 return m_hostID;
679 }
680
681 public int GetChannel()
682 {
683 return m_channel;
684 }
685
686 public uint GetLocalID()
687 {
688 return m_localID;
689 }
690
691 public int GetHandle()
692 {
693 return m_handle;
694 }
695
696 public string GetMessage()
697 {
698 return m_message;
699 }
700
701 public string GetName()
702 {
703 return m_name;
704 }
705
706 public bool IsActive()
707 {
708 return m_active;
709 }
710
711 public void Deactivate()
712 {
713 m_active = false;
714 }
715
716 public void Activate()
717 {
718 m_active = true;
719 }
720
721 public UUID GetID()
722 {
723 return m_id;
724 }
725 }
726}