adding ability for listeners to be filtered by regular expressions and a general-purpose function to see if a given string matches a given regex

This commit is contained in:
SignpostMarv
2012-10-23 15:42:16 +01:00
committed by Justin Clark-Casey (justincc)
parent 18b1ee6f37
commit e977761071
6 changed files with 242 additions and 19 deletions

View File

@@ -28,6 +28,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
@@ -170,12 +171,42 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
/// <param name="hostID">UUID of the SceneObjectPart</param>
/// <param name="channel">channel to listen on</param>
/// <param name="name">name to filter on</param>
/// <param name="id">key to filter on (user given, could be totally faked)</param>
/// <param name="id">
/// key to filter on (user given, could be totally faked)
/// </param>
/// <param name="msg">msg to filter on</param>
/// <returns>number of the scripts handle</returns>
public int Listen(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg)
public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
string name, UUID id, string msg)
{
return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg);
return m_listenerManager.AddListener(localID, itemID, hostID,
channel, name, id, msg);
}
/// <summary>
/// Create a listen event callback with the specified filters.
/// The parameters localID,itemID are needed to uniquely identify
/// the script during 'peek' time. Parameter hostID is needed to
/// determine the position of the script.
/// </summary>
/// <param name="localID">localID of the script engine</param>
/// <param name="itemID">UUID of the script engine</param>
/// <param name="hostID">UUID of the SceneObjectPart</param>
/// <param name="channel">channel to listen on</param>
/// <param name="name">name to filter on</param>
/// <param name="id">
/// key to filter on (user given, could be totally faked)
/// </param>
/// <param name="msg">msg to filter on</param>
/// <param name="regexBitfield">
/// Bitfield indicating which strings should be processed as regex.
/// </param>
/// <returns>number of the scripts handle</returns>
public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
string name, UUID id, string msg, int regexBitfield)
{
return m_listenerManager.AddListener(localID, itemID, hostID,
channel, name, id, msg, regexBitfield);
}
/// <summary>
@@ -465,10 +496,20 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
m_curlisteners = 0;
}
public int AddListener(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg)
public int AddListener(uint localID, UUID itemID, UUID hostID,
int channel, string name, UUID id, string msg)
{
return AddListener(localID, itemID, hostID, channel, name, id,
msg, 0);
}
public int AddListener(uint localID, UUID itemID, UUID hostID,
int channel, string name, UUID id, string msg,
int regexBitfield)
{
// do we already have a match on this particular filter event?
List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, msg);
List<ListenerInfo> coll = GetListeners(itemID, channel, name, id,
msg);
if (coll.Count > 0)
{
@@ -485,7 +526,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
if (newHandle > 0)
{
ListenerInfo li = new ListenerInfo(newHandle, localID, itemID, hostID, channel, name, id, msg);
ListenerInfo li = new ListenerInfo(newHandle, localID,
itemID, hostID, channel, name, id, msg,
regexBitfield);
List<ListenerInfo> listeners;
if (!m_listeners.TryGetValue(channel,out listeners))
@@ -626,6 +669,22 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
return -1;
}
/// These are duplicated from ScriptBaseClass
/// http://opensimulator.org/mantis/view.php?id=6106#c21945
#region Constants for the bitfield parameter of osListenRegex
/// <summary>
/// process name parameter as regex
/// </summary>
public const int OS_LISTEN_REGEX_NAME = 0x1;
/// <summary>
/// process message parameter as regex
/// </summary>
public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
#endregion
// Theres probably a more clever and efficient way to
// do this, maybe with regex.
// PM2008: Ha, one could even be smart and define a specialized Enumerator.
@@ -651,7 +710,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
{
continue;
}
if (li.GetName().Length > 0 && !li.GetName().Equals(name))
if (li.GetName().Length > 0 && (
((li.GetRegexBitfield() & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) ||
((li.GetRegexBitfield() & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName()))
))
{
continue;
}
@@ -659,7 +721,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
{
continue;
}
if (li.GetMessage().Length > 0 && !li.GetMessage().Equals(msg))
if (li.GetMessage().Length > 0 && (
((li.GetRegexBitfield() & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) ||
((li.GetRegexBitfield() & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage()))
))
{
continue;
}
@@ -692,10 +757,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
{
int idx = 0;
Object[] item = new Object[6];
int dataItemLength = 6;
while (idx < data.Length)
{
Array.Copy(data, idx, item, 0, 6);
dataItemLength = (idx + 7 == data.Length || (idx + 7 < data.Length && data[idx + 7] is bool)) ? 7 : 6;
item = new Object[dataItemLength];
Array.Copy(data, idx, item, 0, dataItemLength);
ListenerInfo info =
ListenerInfo.FromData(localID, itemID, hostID, item);
@@ -707,7 +775,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
m_listeners[(int)item[2]].Add(info);
}
idx+=6;
idx+=dataItemLength;
}
}
}
@@ -723,19 +791,33 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
private UUID m_id; // ID to filter messages from
private string m_name; // Object name to filter messages from
private string m_message; // The message
private int m_regexBitfield; // The regex bitfield
public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message)
{
Initialise(handle, localID, ItemID, hostID, channel, name, id, message);
Initialise(handle, localID, ItemID, hostID, channel, name, id,
message, 0);
}
public ListenerInfo(int handle, uint localID, UUID ItemID,
UUID hostID, int channel, string name, UUID id,
string message, int regexBitfield)
{
Initialise(handle, localID, ItemID, hostID, channel, name, id,
message, regexBitfield);
}
public ListenerInfo(ListenerInfo li, string name, UUID id, string message)
{
Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message);
Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, 0);
}
private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name,
UUID id, string message)
public ListenerInfo(ListenerInfo li, string name, UUID id, string message, int regexBitfield)
{
Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, regexBitfield);
}
private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message, int regexBitfield)
{
m_active = true;
m_handle = handle;
@@ -746,11 +828,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
m_name = name;
m_id = id;
m_message = message;
m_regexBitfield = regexBitfield;
}
public Object[] GetSerializationData()
{
Object[] data = new Object[6];
Object[] data = new Object[7];
data[0] = m_active;
data[1] = m_handle;
@@ -758,16 +841,19 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
data[3] = m_name;
data[4] = m_id;
data[5] = m_message;
data[6] = m_regexBitfield;
return data;
}
public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data)
{
ListenerInfo linfo = new ListenerInfo((int)data[1], localID,
ItemID, hostID, (int)data[2], (string)data[3],
(UUID)data[4], (string)data[5]);
linfo.m_active=(bool)data[0];
ListenerInfo linfo = new ListenerInfo((int)data[1], localID, ItemID, hostID, (int)data[2], (string)data[3], (UUID)data[4], (string)data[5]);
linfo.m_active = (bool)data[0];
if (data.Length >= 7)
{
linfo.m_regexBitfield = (int)data[6];
}
return linfo;
}
@@ -826,5 +912,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
{
return m_id;
}
public int GetRegexBitfield()
{
return m_regexBitfield;
}
}
}