private void session_RawMessageReceived(object sender, IrcEventArgs e) { if (e.Message.Command == "PRIVMSG" && e.Message.Parameters.Count == 2 && (!CtcpCommand.IsCtcpCommand(e.Message.Parameters[1]) || CtcpCommand.Parse(e.Message.Parameters[1]).Command == "ACTION")) { var target = new IrcTarget(e.Message.Parameters[0]); if (App.IsIgnoreMatch(e.Message.From, target.IsChannel ? IgnoreActions.Channel : IgnoreActions.Private)) { return; } if (!target.IsChannel && e.Message.From is IrcPeer) { if (App.Create(sender as IrcSession, new IrcTarget((IrcPeer)e.Message.From), false) && _notifyIcon != null && _notifyIcon.IsVisible) { _notifyIcon.Show("IRC Message", string.Format("You received a message from {0}.", ((IrcPeer)e.Message.From).Nickname)); } } else if (_notifyIcon != null && _notifyIcon.IsVisible && e.Message.From is IrcPeer) { var title = String.Format("{0} : {1}", e.Message.Parameters[0], ((IrcPeer)e.Message.From).Nickname); _notifyIcon.Show(title, e.Message.Parameters[1]); } } }
internal AliasEventArgs(string name, string[] arguments, IrcPeer from, IrcTarget to, IrcTarget replyTo) { this.Name = name; this.Arguments = new List <string>(arguments).AsReadOnly(); this.From = from; this.To = to; this.ReplyTo = replyTo; }
public FileControl(IrcSession session, IrcTarget target, DccMethod method) : base(ChatPageType.DccFile, session, target, "DCC") { this.DccMethod = method; InitializeComponent(); this.Id = "dcc-file"; this.Header = this.Title = string.Format("{0} [DCC]", target.Name); }
public ChatPage(ChatPageType type, IrcSession session, IrcTarget target, string id) : this() { this.Type = type; this.Session = session; this.Target = target; this.Id = id; this.IsCloseable = true; }
public void DccChat(IrcSession session, IrcTarget target) { var page = new ChatControl(ChatPageType.DccChat, session, target); App.Create(session, page, true); page.StartListen((port) => { session.SendCtcp(target, new CtcpCommand("DCC", "CHAT", "chat", ConvertIPAddressToString(session.ExternalAddress), port.ToString()), false); }); }
public void DccSend(IrcSession session, IrcTarget target, FileInfo file) { var page = new FileControl(session, target, DccMethod.Send); App.Create(session, page, true); page.StartSend(file, (port) => { if (port > 0) { session.SendCtcp(target, new CtcpCommand("DCC", "SEND", file.Name, ConvertIPAddressToString(session.ExternalAddress), port.ToString(), file.Length.ToString(), "T"), false); } }); }
private string[] Split(string command, string args, int minArgs, int maxArgs, bool isChannelRequired) { string[] parts = ChatControl.Split(args, maxArgs); if (isChannelRequired && (parts.Length < 1 || !IrcTarget.IsChannelName(parts[0]))) { if (!this.IsChannel) { throw new CommandException("Not on a channel."); } parts = new[] { this.Target.Name }.Union(ChatControl.Split(args, maxArgs - 1)).ToArray(); } if (parts.Length < minArgs) { throw new CommandException(string.Format("{0} requires {1} parameters.", command, minArgs)); } return(parts); }
public static bool Create(IrcSession session, IrcTarget target, bool makeActive) { var detached = App.Current.Windows.OfType <ChannelWindow>().Where((cw) => cw.Page.Session == session && target.Equals(cw.Page.Target) && cw.Page.Type == ChatPageType.Chat).FirstOrDefault(); if (detached != null) { if (makeActive) { detached.Activate(); } return(false); } var window = App.ChatWindow; var page = window.FindPage(ChatPageType.Chat, session, target); if (page != null) { if (makeActive) { window.Show(); if (window.WindowState == WindowState.Minimized) { window.WindowState = WindowState.Normal; } window.Activate(); window.SwitchToPage(page); } return(false); } else { page = new ChatControl(target == null ? ChatPageType.Server : ChatPageType.Chat, session, target); Create(session, page, makeActive); return(true); } }
internal IrcJoinEventArgs(IrcMessage message) : base(message) { Who = message.From as IrcPeer; Channel = message.Parameters.Count > 0 ? new IrcTarget(message.Parameters[0]) : null; }
private void Execute(string command, string arguments) { string[] args; switch (command) { case "QUOTE": args = Split(command, arguments, 1, 1); this.Session.Quote(args[0]); break; case "QUIT": args = Split(command, arguments, 0, 1); this.Session.AutoReconnect = false; this.Session.Quit(args.Length == 0 ? "Leaving" : args[0]); break; case "NICK": args = Split(command, arguments, 1, 1); this.Session.Nick(args[0]); break; case "NOTICE": args = Split(command, arguments, 2, 2); this.Session.Notice(new IrcTarget(args[0]), args[1]); break; case "JOIN": case "J": args = Split(command, arguments, 1, 2); if (args.Length == 2) { this.Session.Join(args[0], args[1]); } else { this.Session.Join(args[0]); } break; case "PART": case "LEAVE": args = Split(command, arguments, 1, 1, true); this.Session.Part(args[0]); break; case "TOPIC": args = Split(command, arguments, 1, 2, true); if (args.Length > 1) { this.Session.Topic(args[0], args[1]); } else { this.Session.Topic(args[0]); } break; case "INVITE": args = Split(command, arguments, 2, 2); this.Session.Invite(args[1], args[0]); break; case "KICK": args = Split(command, arguments, 2, 3, true); if (args.Length > 2) { this.Session.Kick(args[0], args[1], args[2]); } else { this.Session.Kick(args[0], args[1]); } break; case "MOTD": args = Split(command, arguments, 0, 1); if (args.Length > 0) { this.Session.Motd(args[0]); } else { this.Session.Motd(); } break; case "WHO": args = Split(command, arguments, 1, 1); this.Session.Who(args[0]); break; case "WHOIS": args = Split(command, arguments, 1, 2); if (args != null) { if (args.Length == 2) { this.Session.WhoIs(args[0], args[1]); } else if (args.Length == 1) { this.Session.WhoIs(args[0]); } } break; case "WHOWAS": args = Split(command, arguments, 1, 1); this.Session.WhoWas(args[0]); break; case "AWAY": args = Split(command, arguments, 0, 1); if (args.Length > 0) { this.Session.Away(args[0]); } else { this.Session.UnAway(); } break; case "USERHOST": args = Split(command, arguments, 1, int.MaxValue); this.Session.UserHost(args); break; case "MODE": args = Split(command, arguments, 1, 2); var target = new IrcTarget(args[0]); if (!target.IsChannel) { if (!this.Session.IsSelf(target)) { throw new CommandException("Can't change modes for another user."); } if (args.Length > 1) { this.Session.Mode(args[1]); } else { this.Session.Mode(""); } } else { if (args.Length > 1) { this.Session.Mode(target.Name, args[1]); } else { this.Session.Mode(target.Name, ""); } } break; case "SERVER": { args = Split(command, arguments, 1, 3); int port = 0; bool useSsl = false; if (args.Length > 1 && (args[1] = args[1].Trim()).Length > 0) { if (args[1][0] == '+') { useSsl = true; } int.TryParse(args[1], out port); } string password = null; if (args.Length > 2) { password = args[2]; } if (port == 0) { port = 6667; } if (this.IsConnected) { this.Session.AutoReconnect = false; this.Session.Quit("Changing servers"); } this.Perform = ""; this.Connect(args[0], port, useSsl, false, password); } break; case "ME": case "ACTION": if (this.IsServer) { this.Write("Error", "Can't talk in this window."); } if (this.IsConnected) { args = Split(command, arguments, 1, int.MaxValue); this.Write("Own", string.Format("{0} {1}", this.Session.Nickname, string.Join(" ", args))); if (this.Type == ChatPageType.Chat) { this.Session.SendCtcp(this.Target, new CtcpCommand("ACTION", args), false); } else if (this.Type == ChatPageType.DccChat) { _dcc.QueueMessage(string.Format("\u0001ACTION {0}\u0001", string.Join(" ", args))); } } break; case "SETUP": App.ShowSettings(); break; case "CLEAR": boxOutput.Clear(); break; case "MSG": if (this.IsConnected) { args = Split(command, arguments, 2, 2); this.Session.PrivateMessage(new IrcTarget(args[0]), args[1]); this.Write("Own", string.Format("-> [{0}] {1}", args[0], args[1])); } break; case "LIST": args = Split(command, arguments, 0, 2); if (args.Length > 1) { this.Session.List(args[0], args[1]); } else if (args.Length > 0) { this.Session.List(args[0]); } else { this.Session.List(); } break; case "OP": case "DEOP": case "VOICE": case "DEVOICE": if (!this.IsChannel) { this.Write("Error", "Cannot perform that action in this window."); } else { char mode = (command == "OP" || command == "DEOP") ? 'o' : 'v'; args = Split(command, arguments, 1, int.MaxValue); var modes = from s in args select new IrcChannelMode(command == "OP" || command == "VOICE", mode, s); this.Session.Mode(this.Target.Name, modes); } break; case "HELP": foreach (var s in App.HelpText.Split(Environment.NewLine.ToCharArray())) { if (s.Length > 0) { this.Write("Client", s); } } break; case "CTCP": args = Split(command, arguments, 2, int.MaxValue); this.Session.SendCtcp(new IrcTarget(args[0]), new CtcpCommand(args[1], args.Skip(2).ToArray()), false); break; case "QUERY": args = Split(command, arguments, 1, 1); ChatWindow.ChatCommand.Execute(args[0], this); break; case "BAN": args = Split(command, arguments, 1, 1); ChatControl.BanCommand.Execute(args[0], this); break; case "UNBAN": args = Split(command, arguments, 1, 1); ChatControl.UnbanCommand.Execute(args[0], this); break; case "IGNORE": { args = Split(command, arguments, 0, 2); if (args.Length == 0) { var ignores = App.GetIgnoreInfo(); if (ignores.Any()) { this.Write("Own", "Ignore list:"); foreach (string i in ignores) { this.Write("Own", " " + i); } } else { this.Write("Own", "Ignore list is empty."); } break; } string mask = args[0]; string sactions = args.Length > 1 ? args[1] : "All"; IgnoreActions actions; if (!Enum.TryParse(sactions, true, out actions)) { this.Write("Error", "Invalid ignore action(s)."); break; } if (!mask.Contains('!') && !mask.Contains('@')) { mask = mask + "!*@*"; } App.AddIgnore(mask, actions); this.Write("Own", "Added to ignore list: " + mask); } break; case "UNIGNORE": { args = Split(command, arguments, 1, 2); string mask = args[0]; string sactions = args.Length > 1 ? args[1] : "All"; IgnoreActions actions; if (!Enum.TryParse(sactions, true, out actions)) { this.Write("Error", "Invalid ignore action(s)."); break; } if (!mask.Contains('!') && !mask.Contains('@')) { mask = mask + "!*@*"; } if (App.RemoveIgnore(mask, actions)) { this.Write("Own", "Removed from ignore list: " + mask); } else { this.Write("Error", "Specified pattern was not on ignore list."); } } break; case "DCC": { if (!this.IsConnected) { return; } args = Split(command, arguments, 2, 3); string dccCmd = args[0].ToUpperInvariant(); switch (dccCmd) { case "CHAT": App.ChatWindow.DccChat(this.Session, new IrcTarget(args[1])); break; case "SEND": case "XMIT": string path = null; if (args.Length < 3) { this.Write("Error", "File name is required."); break; } if (System.IO.Path.IsPathRooted(args[2]) && System.IO.File.Exists(args[2])) { path = args[2]; } else if (!System.IO.File.Exists(path = System.IO.Path.Combine(App.Settings.Current.Dcc.DownloadFolder, args[2]))) { this.Write("Error", "Could not find file " + args[2]); break; } if (dccCmd == "XMIT") { App.ChatWindow.DccXmit(this.Session, new IrcTarget(args[1]), new System.IO.FileInfo(path)); } else { App.ChatWindow.DccSend(this.Session, new IrcTarget(args[1]), new System.IO.FileInfo(path)); } break; default: this.Write("Error", "Unsupported DCC mode " + args[0]); break; } } break; default: this.Write("Error", string.Format("Unrecognized command: {0}", command)); break; } }
public ChatControl(ChatPageType type, IrcSession session, IrcTarget target) : base(type, session, target, type == ChatPageType.Server ? "server" : (type == ChatPageType.DccChat ? "dcc-chat" : string.Format("{0}.{1}", session.NetworkName, target.Name).ToLowerInvariant())) { _history = new LinkedList <string>(); this.Nicknames = new ObservableCollection <NicknameItem>(); InitializeComponent(); var state = App.Settings.Current.Windows.States[this.Id]; if (this.Type == ChatPageType.DccChat) { this.Header = string.Format("[CHAT] {0}", this.Target.Name); } else if (this.Type == ChatPageType.Chat || this.Type == ChatPageType.Server) { this.Header = this.Target == null ? "Server" : this.Target.ToString(); this.SubscribeEvents(); if (!this.IsServer) { _logFile = App.OpenLogFile(this.Id); var logLines = new List <ChatLine>(); while (_logFile.Buffer.Count > 0) { var cl = _logFile.Buffer.Dequeue(); cl.Marker = _logFile.Buffer.Count == 0 ? ChatMarker.OldMarker : ChatMarker.None; logLines.Add(cl); } boxOutput.AppendBulkLines(logLines); } if (this.IsChannel) { colNickList.MinWidth = MinNickListWidth; colNickList.Width = new GridLength(state.NickListWidth); this.Write("Join", string.Format("Now talking on {0}", this.Target.Name)); this.Session.AddHandler(new IrcCodeHandler((e) => { if (e.Message.Parameters.Count > 2 && this.Target.Equals(new IrcTarget(e.Message.Parameters[1]))) { _channelModes = e.Message.Parameters[2].ToCharArray().Where((c) => c != '+').ToArray(); this.SetTitle(); } e.Handled = true; return(true); }, IrcCode.RPL_CHANNELMODEIS)); this.Session.Mode(this.Target); splitter.IsEnabled = true; var nameHandler = new IrcCodeHandler((e) => { if (e.Message.Parameters.Count >= 3) { var to = new IrcTarget(e.Message.Parameters[e.Message.Parameters.Count - 2]); if (this.Target.Equals(to)) { foreach (var nick in e.Message.Parameters[e.Message.Parameters.Count - 1].Split(' ')) { this.AddNick(nick); } } } e.Handled = true; return(false); }, IrcCode.RPL_NAMEREPLY); this.Session.AddHandler(nameHandler); this.Session.AddHandler(new IrcCodeHandler((e) => { this.Session.RemoveHandler(nameHandler); e.Handled = true; return(true); }, IrcCode.RPL_ENDOFNAMES)); } else if (this.IsNickname) { _prefix = this.Target.Name; } } else { throw new ArgumentException("Page type is not supported."); } boxOutput.ColumnWidth = state.ColumnWidth; this.Loaded += new RoutedEventHandler(ChatControl_Loaded); this.Unloaded += new RoutedEventHandler(ChatControl_Unloaded); this.PrepareContextMenus(); boxOutput.ContextMenu = this.GetDefaultContextMenu(); }
private bool HandleDcc(IrcSession session, IrcTarget target, string[] args) { if (args.Length < 1) { return(false); } string type = args[0].ToUpperInvariant(); IPAddress addr; int port; switch (type) { case "CHAT": { if (args.Length < 4 || args[1].ToUpperInvariant() != "CHAT" || !IPAddress.TryParse(args[2], out addr) || !int.TryParse(args[3], out port)) { session.SendCtcp(target, new CtcpCommand("ERRMSG", "DCC", "CHAT", "unavailable"), true); return(true); } var page = new ChatControl(ChatPageType.DccChat, session, target); page.StartAccept(addr, port); page.NotifyState = NotifyState.Alert; App.Create(session, page, false); App.Alert(Window.GetWindow(page), string.Format("{0} wants to chat with you.", target.Name)); } break; case "XMIT": { if (args.Length < 5 || string.Compare(args[1], "CLEAR", StringComparison.OrdinalIgnoreCase) != 0 || !IPAddress.TryParse(args[2], out addr) || !int.TryParse(args[3], out port)) { session.SendCtcp(target, new CtcpCommand("ERRMSG", "DCC", "XMIT", "unavailable"), true); return(true); } string name = args[4]; long size = 0; if (args.Length > 5) { long.TryParse(args[5], out size); } var page = new FileControl(session, target, DccMethod.Xmit); page.StartReceive(addr, port, name, size); page.NotifyState = NotifyState.Alert; App.Create(session, page, false); App.Alert(Window.GetWindow(page), string.Format("{0} wants to send you a file.", target.Name)); } break; case "SEND": { if (args.Length < 4 || !IPAddress.TryParse(args[2], out addr) || !int.TryParse(args[3], out port)) { session.SendCtcp(target, new CtcpCommand("ERRMSG", "DCC", "SEND", "unavailable"), true); return(true); } string name = args[1]; long size = 0; if (args.Length > 4) { long.TryParse(args[4], out size); } var page = new FileControl(session, target, DccMethod.Send); page.StartReceive(addr, port, name, size); page.NotifyState = NotifyState.Alert; App.Create(session, page, false); App.Alert(Window.GetWindow(page), string.Format("{0} wants to send you a file.", target.Name)); } break; default: session.SendCtcp(target, new CtcpCommand("ERRMSG", "DCC", args[0], "unavailable"), true); break; } return(true); }
public void Run(XmlDocument configuration) { // Save configuration to instance _config = configuration; // Set localization if ( !configuration.SelectSingleNode("//configuration/interface/language") .InnerText.Equals("auto", StringComparison.OrdinalIgnoreCase)) { Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo( configuration.SelectSingleNode("//configuration/interface/language").InnerText); } // Create IRC session (uninitialized) _irc = new IrcSession(); // On connection errors _irc.ConnectionError += (s, e) => { Console.WriteLine(Resources.MessageErrorOccurred, e.Exception.ToString()); }; // Fix for kicks _irc.SelfKicked += (s, e) => { Thread.Sleep(TimeSpan.FromSeconds(5)); _irc.Join(e.Channel.Name); }; // Triggered when someone joins a channel _irc.Joined += (s, e) => { Console.WriteLine(Resources.MessageIRCUserJoinedChannel, e.Channel.Name, e.Who.Nickname); }; // Triggered when someone leaves a channel _irc.Parted += (s, e) => { Console.WriteLine(Resources.MessageIRCUserLeftChanne, e.Channel.Name, e.Who.Nickname); }; // Triggered when someone changes his nickname _irc.NickChanged += (s, e) => { Console.WriteLine(Resources.MessageIRCUserChangedNickname, e.NewNickname, e.OldNickname); }; // Triggered when we join a channel _irc.SelfJoined += (s, e) => { Console.WriteLine(Resources.MessageBotJoinedChannel, e.Channel.Name); }; // Triggered when we leave a channel _irc.SelfParted += (s, e) => { Console.WriteLine(Resources.MessageBotLeftChannel, e.Channel.Name); }; // Triggered when we change our nickname _irc.SelfNickChanged += (s, e) => { Console.WriteLine(Resources.MessageBotChangedNickname, e.NewNickname); }; // Triggered on connection state change _irc.StateChanged += (s, e) => { switch (_irc.State) { case IrcSessionState.Connected: Console.WriteLine(Resources.MessageIRCConnectionSuccess); if (!_watcher.Alive) { _watcher.Start(); } break; case IrcSessionState.Disconnected: Console.WriteLine(Resources.MessageIRCDisconnected); break; case IrcSessionState.Connecting: Console.WriteLine(Resources.MessageIRCConnecting); break; default: Console.WriteLine(Resources.MessageIRCSessionStateChanged, _irc.State.ToString()); break; } }; // Join on invite _irc.Invited += (s, e) => { // Check if channel is in autojoin list if (_config.SelectNodes("//configuration/channels/channel") .Cast <XmlNode>().Any(node => node.InnerText.Equals(e.Channel, StringComparison.OrdinalIgnoreCase))) { // Join the channel _irc.Join(e.Channel); } }; // Identify when NickServ requests it _irc.PrivateMessaged += (s, e) => { if (e.From.Nickname == "NickServ" && e.Text.Contains("This nickname is registered")) { _irc.PrivateMessage(new IrcTarget(e.From), string.Format("IDENTIFY {0}", _config.SelectSingleNode("//configuration/nickserv/authentication").InnerText)); } _irc.PrivateMessage(new IrcTarget("HostServ"), "ON"); }; // Reply to CTCP Version _irc.CtcpCommandReceived += (s, e) => { Console.WriteLine("Received CTCP {0} from {1}", e.Command.Command, e.From.Nickname); switch (e.Command.Command.ToUpper()) { case "VERSION": _irc.SendCtcp(new IrcTarget(e.From), new CtcpCommand("VERSION", "phpBB IRC bot"), true); break; } }; /* #if DEBUG * // Print out raw messages being received * _irc.RawMessageReceived += (s, e) => * { * Debug.WriteLine("<= {0}", e.Message.ToString(), null); * }; * * // Print out raw messages being sent * _irc.RawMessageSent += (s, e) => * { * Debug.WriteLine("=> {0}", e.Message.ToString(), null); * }; #endif */ // Initialize and connect IRC session Console.WriteLine(Resources.MessageDebugPrintHost, configuration.SelectSingleNode("//configuration/server/host").InnerText); Console.WriteLine(Resources.MessageDebugPrintPort, configuration.SelectSingleNode("//configuration/server/port").InnerText); Console.WriteLine(Resources.MessageDebugPrintSSL, Convert.ToBoolean(configuration.SelectSingleNode("//configuration/server/secure").InnerText)); _irc.AutoReconnect = false; _irc.Open( configuration.SelectSingleNode("//configuration/server/host").InnerText, Convert.ToUInt16(configuration.SelectSingleNode("//configuration/server/port").InnerText), Convert.ToBoolean(configuration.SelectSingleNode("//configuration/server/secure").InnerText), configuration.SelectSingleNode("//configuration/bot/nickname").InnerText, configuration.SelectSingleNode("//configuration/bot/username").InnerText, configuration.SelectSingleNode("//configuration/bot/realname").InnerText, Convert.ToBoolean(configuration.SelectSingleNode("//configuration/server/autoreconnect").InnerText), configuration.SelectSingleNode("//configuration/server/password").InnerText, Convert.ToBoolean(configuration.SelectSingleNode("//configuration/bot/invisible").InnerText), false ); // Fix for existing nicks _irc.AddHandler(new IrcCodeHandler(e => { _irc.Nick(_irc.Nickname + "`"); return(false); // Do not remove handler }, IrcCode.ERR_NICKCOLLISION, IrcCode.ERR_NICKNAMEINUSE)); // Fix for invitation-lockout _irc.AddHandler(new IrcCodeHandler(e => { _irc.PrivateMessage(new IrcTarget("ChanServ"), "INVITE " + e.Text.Split(' ').First()); return(false); // Do not remove handler }, IrcCode.ERR_INVITEONLYCHAN)); // Fix for bans _irc.AddHandler(new IrcCodeHandler(e => { _irc.PrivateMessage(new IrcTarget("ChanServ"), "UNBAN " + e.Text.Split(' ').First()); return(false); // Do not remove handler }, IrcCode.ERR_BANNEDFROMCHAN)); // Automatically join configured channels _irc.AddHandler(new IrcCodeHandler(e => { foreach (string channel in _config.SelectNodes("//configuration/channels/channel") .Cast <XmlNode>().Select(n => n.InnerText)) { _irc.Join(channel); } return(true); // remove handler afterwards }, IrcCode.RPL_ENDOFMOTD)); // Initialize and run forum watcher _watcher = new ForumWatcher { ForumBaseUrl = new Uri(configuration.SelectSingleNode("//configuration/forum/baseurl").InnerText), ForumID = Convert.ToUInt32(configuration.SelectSingleNode("//configuration/forum/subforum-id").InnerText), CheckInterval = TimeSpan.Parse(configuration.SelectSingleNode("//configuration/forum/checkinterval").InnerText) }; _watcher.PostsIncoming += (s, e) => { try { foreach (XElement post in e.PostNodes) { foreach ( string channel in _config.SelectNodes("//configuration/channels/channel") .Cast <XmlNode>() .Select(n => n.InnerText)) { var target = new IrcTarget(channel); string published = post.Element("{http://www.w3.org/2005/Atom}published").Value; string updated = post.Element("{http://www.w3.org/2005/Atom}updated").Value; string title = post.Element("{http://www.w3.org/2005/Atom}title").Value; string author = post.Element("{http://www.w3.org/2005/Atom}author").Value; string href = post.Element("{http://www.w3.org/2005/Atom}link").Attribute("href").Value; string message = string.Format( "\x02{0}\x02: {1} {2} {3} - {4}", // "New post" Resources.NewPost, // Thread title title, // "by" Resources.By, // Author author, // URL to post href ); _irc.PrivateMessage( target, message ); } } } catch (Exception err) { Console.WriteLine(err); } }; }
public ChatPage FindPage(ChatPageType type, IrcSession session, IrcTarget target) { return(this.Items.Where((i) => i.Page.Type == type && i.Page.Session == session && i.Page.Target != null && i.Page.Target.Equals(target)).Select((i) => i.Page).FirstOrDefault()); }