aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Chat/ChannelState.cs61
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs2
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs34
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Chat/RegionState.cs47
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCBridgeModule.cs2
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCConnector.cs5
6 files changed, 84 insertions, 67 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChannelState.cs
index 7a3eadf..f9089cb 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/ChannelState.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChannelState.cs
@@ -50,6 +50,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
50 50
51 private static Regex arg = new Regex(@"\[[^\[\]]*\]"); 51 private static Regex arg = new Regex(@"\[[^\[\]]*\]");
52 private static int _idk_ = 0; 52 private static int _idk_ = 0;
53 private static int DEBUG_CHANNEL = 2147483647;
53 54
54 // These are the IRC Connector configurable parameters with hard-wired 55 // These are the IRC Connector configurable parameters with hard-wired
55 // default values (retained for compatability). 56 // default values (retained for compatability).
@@ -61,8 +62,10 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
61 internal string User = "USER OpenSimBot 8 * :I'm an OpenSim to IRC bot"; 62 internal string User = "USER OpenSimBot 8 * :I'm an OpenSim to IRC bot";
62 63
63 internal bool ClientReporting = true; 64 internal bool ClientReporting = true;
65 internal bool RelayChat = true;
64 internal bool RelayPrivateChannels = false; 66 internal bool RelayPrivateChannels = false;
65 internal int RelayChannel = 1; 67 internal int RelayChannel = 1;
68 internal List<int> ValidInWorldChannels = new List<int>();
66 69
67 // Connector agnostic parameters. These values are NOT shared with the 70 // Connector agnostic parameters. These values are NOT shared with the
68 // connector and do not differentiate at an IRC level 71 // connector and do not differentiate at an IRC level
@@ -71,13 +74,27 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
71 internal string NoticeMessageFormat = "PRIVMSG {0} :<{2}> {3}"; 74 internal string NoticeMessageFormat = "PRIVMSG {0} :<{2}> {3}";
72 internal int RelayChannelOut = -1; 75 internal int RelayChannelOut = -1;
73 internal bool RandomizeNickname = true; 76 internal bool RandomizeNickname = true;
74 internal string AccessPassword = "badkitty";
75 internal bool CommandsEnabled = false; 77 internal bool CommandsEnabled = false;
76 internal int CommandChannel = -1; 78 internal int CommandChannel = -1;
77 internal int ConnectDelay = 10; 79 internal int ConnectDelay = 10;
78 internal int PingDelay = 15; 80 internal int PingDelay = 15;
79 internal string DefaultZone = "Sim"; 81 internal string DefaultZone = "Sim";
80 82
83 internal string _accessPassword = String.Empty;
84 internal Regex AccessPasswordRegex = null;
85 internal string AccessPassword
86 {
87 get { return _accessPassword; }
88 set
89 {
90 _accessPassword = value;
91 AccessPasswordRegex = new Regex(String.Format(@"^{0},\s*(?<avatar>[^,]+),\s*(?<message>.+)$", _accessPassword),
92 RegexOptions.Compiled);
93 }
94 }
95
96
97
81 // IRC connector reference 98 // IRC connector reference
82 99
83 internal XIRCConnector irc = null; 100 internal XIRCConnector irc = null;
@@ -108,9 +125,11 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
108 User = model.User; 125 User = model.User;
109 CommandsEnabled = model.CommandsEnabled; 126 CommandsEnabled = model.CommandsEnabled;
110 CommandChannel = model.CommandChannel; 127 CommandChannel = model.CommandChannel;
128 RelayChat = model.RelayChat;
111 RelayPrivateChannels = model.RelayPrivateChannels; 129 RelayPrivateChannels = model.RelayPrivateChannels;
112 RelayChannelOut = model.RelayChannelOut; 130 RelayChannelOut = model.RelayChannelOut;
113 RelayChannel = model.RelayChannel; 131 RelayChannel = model.RelayChannel;
132 ValidInWorldChannels = model.ValidInWorldChannels;
114 PrivateMessageFormat = model.PrivateMessageFormat; 133 PrivateMessageFormat = model.PrivateMessageFormat;
115 NoticeMessageFormat = model.NoticeMessageFormat; 134 NoticeMessageFormat = model.NoticeMessageFormat;
116 ClientReporting = model.ClientReporting; 135 ClientReporting = model.ClientReporting;
@@ -158,6 +177,8 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
158 m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); 177 m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel);
159 cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel)))); 178 cs.CommandChannel = Convert.ToInt32(Substitute(rs, config.GetString("command_channel", Convert.ToString(cs.CommandChannel))));
160 m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel); 179 m_log.DebugFormat("[IRC-Channel-{0}] CommandChannel : <{1}>", cs.idn, cs.CommandChannel);
180 cs.RelayChat = Convert.ToBoolean(Substitute(rs, config.GetString("relay_chat", Convert.ToString(cs.RelayChat))));
181 m_log.DebugFormat("[IRC-Channel-{0}] RelayChat : <{1}>", cs.idn, cs.RelayChat);
161 cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("relay_private_channels", Convert.ToString(cs.RelayPrivateChannels)))); 182 cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("relay_private_channels", Convert.ToString(cs.RelayPrivateChannels))));
162 m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels); 183 m_log.DebugFormat("[IRC-Channel-{0}] RelayPrivateChannels : <{1}>", cs.idn, cs.RelayPrivateChannels);
163 cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("useworldcomm", Convert.ToString(cs.RelayPrivateChannels)))); 184 cs.RelayPrivateChannels = Convert.ToBoolean(Substitute(rs, config.GetString("useworldcomm", Convert.ToString(cs.RelayPrivateChannels))));
@@ -176,14 +197,15 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
176 m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); 197 m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting);
177 cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting)))); 198 cs.ClientReporting = Convert.ToBoolean(Substitute(rs, config.GetString("report_clients", Convert.ToString(cs.ClientReporting))));
178 m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting); 199 m_log.DebugFormat("[IRC-Channel-{0}] ClientReporting : <{1}>", cs.idn, cs.ClientReporting);
179 cs.AccessPassword = Substitute(rs, config.GetString("access_password", cs.AccessPassword));
180 m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword);
181 cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone)); 200 cs.DefaultZone = Substitute(rs, config.GetString("fallback_region", cs.DefaultZone));
182 m_log.DebugFormat("[IRC-Channel-{0}] DefaultZone : <{1}>", cs.idn, cs.DefaultZone); 201 m_log.DebugFormat("[IRC-Channel-{0}] DefaultZone : <{1}>", cs.idn, cs.DefaultZone);
183 cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay)))); 202 cs.ConnectDelay = Convert.ToInt32(Substitute(rs, config.GetString("connect_delay", Convert.ToString(cs.ConnectDelay))));
184 m_log.DebugFormat("[IRC-Channel-{0}] ConnectDelay : <{1}>", cs.idn, cs.ConnectDelay); 203 m_log.DebugFormat("[IRC-Channel-{0}] ConnectDelay : <{1}>", cs.idn, cs.ConnectDelay);
185 cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay)))); 204 cs.PingDelay = Convert.ToInt32(Substitute(rs, config.GetString("ping_delay", Convert.ToString(cs.PingDelay))));
186 m_log.DebugFormat("[IRC-Channel-{0}] PingDelay : <{1}>", cs.idn, cs.PingDelay); 205 m_log.DebugFormat("[IRC-Channel-{0}] PingDelay : <{1}>", cs.idn, cs.PingDelay);
206 cs.AccessPassword = Substitute(rs, config.GetString("access_password", cs.AccessPassword));
207 m_log.DebugFormat("[IRC-Channel-{0}] AccessPassword : <{1}>", cs.idn, cs.AccessPassword);
208
187 209
188 // Fail if fundamental information is still missing 210 // Fail if fundamental information is still missing
189 211
@@ -199,6 +221,15 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
199 221
200 // Set the channel state for this region 222 // Set the channel state for this region
201 223
224 if (cs.RelayChat)
225 {
226 cs.ValidInWorldChannels.Add(0);
227 cs.ValidInWorldChannels.Add(DEBUG_CHANNEL);
228 }
229
230 if (cs.RelayPrivateChannels)
231 cs.ValidInWorldChannels.Add(cs.RelayChannelOut);
232
202 rs.cs = Integrate(rs, cs); 233 rs.cs = Integrate(rs, cs);
203 234
204 } 235 }
@@ -377,18 +408,18 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
377 private bool IsAPerfectMatchFor(ChannelState cs) 408 private bool IsAPerfectMatchFor(ChannelState cs)
378 { 409 {
379 return ( IsAConnectionMatchFor(cs) && 410 return ( IsAConnectionMatchFor(cs) &&
380 411 RelayChannelOut == cs.RelayChannelOut &&
381 RelayChannelOut == cs.RelayChannelOut && 412 PrivateMessageFormat == cs.PrivateMessageFormat &&
382 PrivateMessageFormat == cs.PrivateMessageFormat && 413 NoticeMessageFormat == cs.NoticeMessageFormat &&
383 NoticeMessageFormat == cs.NoticeMessageFormat && 414 RandomizeNickname == cs.RandomizeNickname &&
384 RandomizeNickname == cs.RandomizeNickname && 415 AccessPassword == cs.AccessPassword &&
385 AccessPassword == cs.AccessPassword && 416 CommandsEnabled == cs.CommandsEnabled &&
386 CommandsEnabled == cs.CommandsEnabled && 417 CommandChannel == cs.CommandChannel &&
387 CommandChannel == cs.CommandChannel && 418 DefaultZone == cs.DefaultZone &&
388 DefaultZone == cs.DefaultZone && 419 RelayPrivateChannels == cs.RelayPrivateChannels &&
389 RelayPrivateChannels == cs.RelayPrivateChannels && 420 RelayChannel == cs.RelayChannel &&
390 RelayChannel == cs.RelayChannel && 421 RelayChat == cs.RelayChat &&
391 ClientReporting == cs.ClientReporting 422 ClientReporting == cs.ClientReporting
392 ); 423 );
393 } 424 }
394 425
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs
index f1aa756..482f469 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
75 { 75 {
76 try 76 try
77 { 77 {
78 if ((m_config = config.Configs["IRC"]) == null) 78 if ((m_config = config.Configs["OIRC"]) == null)
79 { 79 {
80 m_log.InfoFormat("[IRC] module not configured"); 80 m_log.InfoFormat("[IRC] module not configured");
81 return; 81 return;
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs
index ddf6601..29ba17d 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs
@@ -177,23 +177,23 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
177 177
178 try 178 try
179 { 179 {
180 m_server = config.Configs["IRC"].GetString("server"); 180 m_server = config.Configs["OIRC"].GetString("server");
181 m_baseNick = config.Configs["IRC"].GetString("nick", "OSimBot"); 181 m_baseNick = config.Configs["OIRC"].GetString("nick", "OSimBot");
182 182
183 m_randomizeNick = config.Configs["IRC"].GetBoolean("randomize_nick", m_randomizeNick); 183 m_randomizeNick = config.Configs["OIRC"].GetBoolean("randomize_nick", m_randomizeNick);
184 m_randomizeNick = config.Configs["IRC"].GetBoolean("nicknum", m_randomizeNick); // compat 184 m_randomizeNick = config.Configs["OIRC"].GetBoolean("nicknum", m_randomizeNick); // compat
185 m_ircChannel = config.Configs["IRC"].GetString("channel"); 185 m_ircChannel = config.Configs["OIRC"].GetString("channel");
186 m_port = (uint)config.Configs["IRC"].GetInt("port", (int)m_port); 186 m_port = (uint)config.Configs["OIRC"].GetInt("port", (int)m_port);
187 m_user = config.Configs["IRC"].GetString("username", m_user); 187 m_user = config.Configs["OIRC"].GetString("username", m_user);
188 m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat); 188 m_privmsgformat = config.Configs["OIRC"].GetString("msgformat", m_privmsgformat);
189 189
190 m_clientReporting = config.Configs["IRC"].GetInt("verbosity", 2) > 0; 190 m_clientReporting = config.Configs["OIRC"].GetInt("verbosity", 2) > 0;
191 m_clientReporting = config.Configs["IRC"].GetBoolean("report_clients", m_clientReporting); 191 m_clientReporting = config.Configs["OIRC"].GetBoolean("report_clients", m_clientReporting);
192 192
193 m_relayPrivateChannels = config.Configs["IRC"].GetBoolean("relay_private_channels", m_relayPrivateChannels); 193 m_relayPrivateChannels = config.Configs["OIRC"].GetBoolean("relay_private_channels", m_relayPrivateChannels);
194 m_relayPrivateChannels = config.Configs["IRC"].GetBoolean("useworldcomm", m_relayPrivateChannels); //compat 194 m_relayPrivateChannels = config.Configs["OIRC"].GetBoolean("useworldcomm", m_relayPrivateChannels); //compat
195 m_relayChannel = config.Configs["IRC"].GetInt("relay_private_channel_in", m_relayChannel); 195 m_relayChannel = config.Configs["OIRC"].GetInt("relay_private_channel_in", m_relayChannel);
196 m_relayChannel = config.Configs["IRC"].GetInt("inchannel", m_relayChannel); 196 m_relayChannel = config.Configs["OIRC"].GetInt("inchannel", m_relayChannel);
197 197
198 if (m_server != null && m_baseNick != null && m_ircChannel != null) 198 if (m_server != null && m_baseNick != null && m_ircChannel != null)
199 { 199 {
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/RegionState.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/RegionState.cs
index cf2154f..0251388 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/RegionState.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/RegionState.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Text.RegularExpressions;
31using log4net; 32using log4net;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
@@ -331,27 +332,16 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
331 if (!enabled) 332 if (!enabled)
332 return; 333 return;
333 334
334 // drop all messages coming in on a private channel, 335 // drop messages unless they are on a valid in-world
335 // except if we are relaying private channels, in which 336 // channel as configured in the ChannelState
336 // case we drop if the private channel is not the
337 // configured m_relayChannelOut
338 337
339 if (cs.RelayPrivateChannels) 338 if (!cs.ValidInWorldChannels.Contains(msg.Channel))
340 {
341 if (msg.Channel != 0 && msg.Channel != DEBUG_CHANNEL && msg.Channel != cs.RelayChannelOut)
342 {
343 m_log.DebugFormat("[IRC-Region {0}] dropping message {1} on channel {2}", Region, msg, msg.Channel);
344 return;
345 }
346 }
347 else if (msg.Channel != 0 && msg.Channel != DEBUG_CHANNEL)
348 { 339 {
349 m_log.DebugFormat("[IRC-Region {0}] dropping message {1} on channel {2}", Region, msg, msg.Channel); 340 m_log.DebugFormat("[IRC-Region {0}] dropping message {1} on channel {2}", Region, msg, msg.Channel);
350 return; 341 return;
351 } 342 }
352 343
353 ScenePresence avatar = null; 344 ScenePresence avatar = null;
354
355 string fromName = msg.From; 345 string fromName = msg.From;
356 346
357 if (msg.Sender != null) 347 if (msg.Sender != null)
@@ -368,31 +358,26 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
368 358
369 m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message); 359 m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message);
370 360
371 if (null != avatar) 361 if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL))
372 { 362 {
373 string txt = msg.Message; 363 string txt = msg.Message;
374 if (txt.StartsWith("/me ")) 364 if (txt.StartsWith("/me "))
375 txt = String.Format("{0} {1}", fromName, msg.Message.Substring(4)); 365 txt = String.Format("{0} {1}", fromName, msg.Message.Substring(4));
376 366
377 cs.irc.PrivMsg(cs.PrivateMessageFormat, fromName, Region, txt); 367 cs.irc.PrivMsg(cs.PrivateMessageFormat, fromName, Region, txt);
368 return;
378 } 369 }
379 else
380 {
381 //Message came from an object
382 char[] splits = { ',' };
383 string[] tokens = msg.Message.Split(splits,3); // This is certainly wrong
384 370
385 if (tokens.Length == 3) 371 if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword &&
372 msg.Channel == cs.RelayChannelOut)
373 {
374 Match m = cs.AccessPasswordRegex.Match(msg.Message);
375 if (null != m)
386 { 376 {
387 if (tokens[0] == cs.AccessPassword) // This is my really simple check 377 m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(),
388 { 378 m.Groups["message"].ToString());
389 m_log.DebugFormat("[IRC-Region {0}] message from object {1}, {2}", Region, tokens[0], tokens[1]); 379 cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(),
390 cs.irc.PrivMsg(cs.PrivateMessageFormat, tokens[1], scene.RegionInfo.RegionName, tokens[2]); 380 scene.RegionInfo.RegionName, m.Groups["message"].ToString());
391 }
392 else
393 {
394 m_log.WarnFormat("[IRC-Region {0}] prim security key mismatch <{1}> not <{2}>", Region, tokens[0], cs.AccessPassword);
395 }
396 } 381 }
397 } 382 }
398 } 383 }
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCBridgeModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCBridgeModule.cs
index c8d8307..9bd7946 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCBridgeModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCBridgeModule.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
79 79
80 try 80 try
81 { 81 {
82 if ((m_config = config.Configs["XIRC"]) == null) 82 if ((m_config = config.Configs["IRC"]) == null)
83 { 83 {
84 m_log.InfoFormat("[XIRC-Bridge] module not configured"); 84 m_log.InfoFormat("[XIRC-Bridge] module not configured");
85 return; 85 return;
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCConnector.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCConnector.cs
index b9203a8..f6a07b8 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCConnector.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCConnector.cs
@@ -521,6 +521,9 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
521 521
522 } 522 }
523 523
524 private Regex RE = new Regex(@":(?<nick>[\w-]*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)",
525 RegexOptions.Multiline);
526
524 private Dictionary<string, string> ExtractMsg(string input) 527 private Dictionary<string, string> ExtractMsg(string input)
525 { 528 {
526 //examines IRC commands and extracts any private messages 529 //examines IRC commands and extracts any private messages
@@ -529,8 +532,6 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
529 // m_log.InfoFormat("[IRC-Connector-{0}]: ExtractMsg: {1}", idn, input); 532 // m_log.InfoFormat("[IRC-Connector-{0}]: ExtractMsg: {1}", idn, input);
530 533
531 Dictionary<string, string> result = null; 534 Dictionary<string, string> result = null;
532 string regex = @":(?<nick>[\w-]*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)";
533 Regex RE = new Regex(regex, RegexOptions.Multiline);
534 MatchCollection matches = RE.Matches(input); 535 MatchCollection matches = RE.Matches(input);
535 536
536 // Get some direct matches $1 $4 is a 537 // Get some direct matches $1 $4 is a