예제 #1
0
        internal async Task HandleLine(string receivedData)
        {
            var parsedLine = new IrcMessage(receivedData);

            if (parsedLine.CommandMessage.Command == "CAP")
            {
                if (parsedLine.CommandMessage.Parameters[1] == "LS")
                {
                    var requirements      = "";
                    var compatibleFeatues = parsedLine.TrailMessage.TrailingContent;
                    if (compatibleFeatues.Contains("znc.in/server-time-iso"))
                    {
                        requirements += "znc.in/server-time-iso ";
                    }

                    if (compatibleFeatues.Contains("multi-prefix"))
                    {
                        requirements += "multi-prefix ";
                    }

                    WriteLine("CAP REQ :" + requirements);
                    WriteLine("CAP END");
                }
            }
            else if (parsedLine.CommandMessage.Command == "JOIN")
            {
                var channel = parsedLine.TrailMessage.TrailingContent;
                if (parsedLine.PrefixMessage.Nickname == this.server.username)
                {
                    AddChannel(channel);
                }
                else
                {
                    if (parsedLine.CommandMessage.Parameters != null)
                    {
                        channel = parsedLine.CommandMessage.Parameters[0];
                    }
                    Message msg = new Message();
                    msg.Type = MessageType.Info;
                    msg.User = parsedLine.PrefixMessage.Nickname;

                    msg.Text = String.Format("({0}) {1}", parsedLine.PrefixMessage.Prefix, "joined the channel");
                    AddMessage(channel, msg);
                    channelStore[channel].AddUser(parsedLine.PrefixMessage.Nickname, true);
                }
            }
            else if (parsedLine.CommandMessage.Command == "PART")
            {
                var channel = parsedLine.TrailMessage.TrailingContent;
                if (parsedLine.PrefixMessage.Nickname == this.server.username)
                {
                    RemoveChannel(channel);
                }
                else
                {
                    if (parsedLine.CommandMessage.Parameters.Count > 0)
                    {
                        channel = parsedLine.CommandMessage.Parameters[0];
                    }
                    Message msg = new Message();
                    msg.Type = MessageType.Info;
                    msg.User = parsedLine.PrefixMessage.Nickname;

                    msg.Text = String.Format("({0}) {1}", parsedLine.PrefixMessage.Prefix, "left the channel");
                    AddMessage(channel, msg);
                    channelStore[channel].RemoveUser(parsedLine.PrefixMessage.Nickname);
                }
            }
            else if (parsedLine.CommandMessage.Command == "PRIVMSG")
            {
                // handle messages to this irc client
                var destination = parsedLine.CommandMessage.Parameters[0];
                var content     = parsedLine.TrailMessage.TrailingContent;

                if (destination == server.username)
                {
                    destination = parsedLine.PrefixMessage.Nickname;
                }

                if (!channelList.Contains(destination))
                {
                    AddChannel(destination);
                }

                Message msg = new Message();

                msg.Type = MessageType.Normal;
                msg.User = parsedLine.PrefixMessage.Nickname;
                if (parsedLine.ServerTime != null)
                {
                    var time = DateTime.Parse(parsedLine.ServerTime);
                    msg.Timestamp = time.ToString("HH:mm");
                }

                if (content.Contains("ACTION"))
                {
                    msg.Text = content.Replace("ACTION ", "");
                    msg.Type = MessageType.Action;
                }
                else
                {
                    msg.Text = content;
                }

                if (parsedLine.TrailMessage.TrailingContent.Contains(server.username) || parsedLine.CommandMessage.Parameters[0] == server.username)
                {
                    var toast = CreateMentionToast(parsedLine.PrefixMessage.Nickname, destination, content);
                    toast.ExpirationTime = DateTime.Now.AddDays(2);
                    ToastNotificationManager.CreateToastNotifier().Show(toast);
                    msg.Mention = true;
                }

                AddMessage(destination, msg);
            }
            else if (parsedLine.CommandMessage.Command == "KICK")
            {
                // handle messages to this irc client
                var destination = parsedLine.CommandMessage.Parameters[0];
                var reciever    = parsedLine.CommandMessage.Parameters[1];
                var content     = parsedLine.TrailMessage.TrailingContent;
                if (!channelList.Contains(destination))
                {
                    AddChannel(destination);
                }

                Message msg = new Message();

                msg.Type = MessageType.Info;

                if (reciever == server.username)
                {
                    var kickTitle = String.Format("{0} kicked you from {1}", parsedLine.PrefixMessage.Nickname, destination);

                    var toast = CreateBasicToast(kickTitle, content);
                    toast.ExpirationTime = DateTime.Now.AddDays(2);
                    ToastNotificationManager.CreateToastNotifier().Show(toast);
                    msg.User = parsedLine.PrefixMessage.Nickname;
                    msg.Text = "kicked you from the channel: " + content;
                }
                else
                {
                    msg.User = parsedLine.PrefixMessage.Nickname;
                    msg.Text = String.Format("kicked {0} from the channel: {1}", reciever, content);
                }

                AddMessage(destination, msg);
            }
            else if (parsedLine.CommandMessage.Command == "353")
            {
                // handle /NAMES
                var list    = parsedLine.TrailMessage.TrailingContent.Split(' ').ToList();
                var channel = parsedLine.CommandMessage.Parameters[2];

                channelStore[channel].AddUsers(list);
            }
            else if (parsedLine.CommandMessage.Command == "332")
            {
                // handle /TOPIC
                var     topic   = parsedLine.TrailMessage.TrailingContent;
                var     channel = parsedLine.CommandMessage.Parameters[1];
                Message msg     = new Message();
                msg.Type = MessageType.Info;

                msg.User = "";
                msg.Text = String.Format("Topic for channel {0}: {1}", channel, topic);
                AddMessage(channel, msg);
                channelStore[channel].SetTopic(topic);
            }
            else if (parsedLine.CommandMessage.Command == "QUIT")
            {
                var username = parsedLine.PrefixMessage.Nickname;
                foreach (var channel in channelList)
                {
                    var users = channelStore[channel];
                    if (users.HasUser(username))
                    {
                        Message msg = new Message();
                        msg.Type = MessageType.Info;
                        msg.User = parsedLine.PrefixMessage.Nickname;
                        msg.Text = String.Format("({0}) {1}: {2}", parsedLine.PrefixMessage.Prefix, "quit the server", parsedLine.TrailMessage.TrailingContent);
                        AddMessage(channel, msg);
                        users.RemoveUser(username);
                    }
                }
            }
            else if (parsedLine.CommandMessage.Command == "MODE")
            {
                Debug.WriteLine(parsedLine.CommandMessage.Command + " - " + receivedData);

                if (parsedLine.CommandMessage.Parameters.Count > 2)
                {
                    var channel = parsedLine.CommandMessage.Parameters[0];

                    if (parsedLine.CommandMessage.Parameters.Count == 3)
                    {
                        string currentPrefix = channelStore[channel].GetPrefix(parsedLine.CommandMessage.Parameters[2]);
                        string prefix        = "";
                        string mode          = parsedLine.CommandMessage.Parameters[1];
                        if (mode == "+o")
                        {
                            if (currentPrefix[0] == '+')
                            {
                                prefix = "@+";
                            }
                            else
                            {
                                prefix = "@";
                            }
                        }
                        else if (mode == "-o")
                        {
                            if (currentPrefix[1] == '+')
                            {
                                prefix = "+";
                            }
                        }
                        else if (mode == "+v")
                        {
                            if (currentPrefix[0] == '@')
                            {
                                prefix = "@+";
                            }
                            else
                            {
                                prefix = "+";
                            }
                        }
                        else if (mode == "-v")
                        {
                            if (currentPrefix[0] == '@')
                            {
                                prefix = "@";
                            }
                            else
                            {
                                prefix = "";
                            }
                        }

                        channelStore[channel].ChangePrefix(parsedLine.CommandMessage.Parameters[2], prefix);
                    }

                    ClientMessage(channel, "Mode change: " + String.Join(" ", parsedLine.CommandMessage.Parameters));
                }
            }
            else if (parsedLine.CommandMessage.Command == "470")
            {
                RemoveChannel(parsedLine.CommandMessage.Parameters[1]);
                AddChannel(parsedLine.CommandMessage.Parameters[2]);
            }
            else if (WhoisCmds.Any(str => str.Contains(parsedLine.CommandMessage.Command)))
            {
                var cmd = parsedLine.CommandMessage.Command;
                if (currentWhois == "")
                {
                    currentWhois += "Whois for " + parsedLine.CommandMessage.Parameters[1] + ": \r\n";
                }

                var whoisLine = "";

                if (cmd == "330")
                {
                    whoisLine    += parsedLine.CommandMessage.Parameters[1] + " " + parsedLine.TrailMessage.TrailingContent + " " + parsedLine.CommandMessage.Parameters[2] + " ";
                    currentWhois += whoisLine + "\r\n";
                }
                else
                {
                    for (int i = 2; i < parsedLine.CommandMessage.Parameters.Count; i++)
                    {
                        whoisLine += parsedLine.CommandMessage.Command + " " + parsedLine.CommandMessage.Parameters[i] + " ";
                    }
                    currentWhois += whoisLine + parsedLine.TrailMessage.TrailingContent + "\r\n";
                }
            }
            else if (parsedLine.CommandMessage.Command == "318")
            {
                Debug.WriteLine(currentWhois);
                Message msg = new Message();
                msg.Text = currentWhois;
                msg.Type = MessageType.Info;
                AddMessage(currentChannel, msg);

                currentWhois = "";
            }
            else if (parsedLine.CommandMessage.Command == "376")
            {
                if (server.nickservPassword != null && server.nickservPassword != "")
                {
                    SendMessage("nickserv", "identify " + server.nickservPassword);
                }

                var channelsList = server.channels.Split(',');
                foreach (string channel in channelsList)
                {
                    JoinChannel(channel);
                }
            }
            else
            {
                if (!parsedLine.PrefixMessage.IsUser)
                {
                    if (!channelList.Contains("Server"))
                    {
                        await AddChannel("Server");
                    }

                    Message msg = new Message();
                    msg.Text = parsedLine.OriginalMessage;
                    msg.Type = MessageType.Info;
                    msg.User = "";
                    AddMessage("Server", msg);
                }
                Debug.WriteLine(parsedLine.CommandMessage.Command + " - " + receivedData);
            }

            //Debug.WriteLine(parsedLine.CommandMessage.Command + " - " + receivedData);
        }
예제 #2
0
파일: Irc.cs 프로젝트: owensdj/WinIRC
        internal async Task HandleLine(string receivedData)
        {
            if (receivedData.Contains("Nickname is already in use"))
            {
                this.server.username += "_";
                AttemptAuth();
                return;
            }

            if (receivedData.StartsWith("ERROR"))
            {
                if (!IsReconnecting)
                {
                    ReadOrWriteFailed = true;

                    var autoReconnect = Config.GetBoolean(Config.AutoReconnect);

                    var msg = autoReconnect
                        ? "Attempting to reconnect..."
                        : "Please try again later.";

                    AddError("Error with connection: \n" + msg);

                    DisconnectAsync(attemptReconnect: autoReconnect);
                }
                return;
            }

            if (receivedData.StartsWith("PING"))
            {
                await WriteLine(writer, receivedData.Replace("PING", "PONG"));

                return;
            }

            var parsedLine = new IrcMessage(receivedData);

            ReconnectionAttempts = 0;

            if (parsedLine.CommandMessage.Command == "CAP")
            {
                if (parsedLine.CommandMessage.Parameters[1] == "LS")
                {
                    var requirements      = "";
                    var compatibleFeatues = parsedLine.TrailMessage.TrailingContent;

                    if (compatibleFeatues.Contains("znc"))
                    {
                        IsBouncer = true;
                    }

                    if (compatibleFeatues.Contains("znc.in/server-time-iso"))
                    {
                        requirements += "znc.in/server-time-iso ";
                    }

                    if (compatibleFeatues.Contains("multi-prefix"))
                    {
                        requirements += "multi-prefix ";
                    }


                    WriteLine("CAP REQ :" + requirements);
                    WriteLine("CAP END");
                }
            }
            else if (parsedLine.CommandMessage.Command == "JOIN")
            {
                var channel = parsedLine.TrailMessage.TrailingContent;
                if (parsedLine.PrefixMessage.Nickname == this.server.username)
                {
                    await AddChannel(channel);
                }

                if (parsedLine.CommandMessage.Parameters != null)
                {
                    channel = parsedLine.CommandMessage.Parameters[0];
                }

                if ((!Config.Contains(Config.IgnoreJoinLeave)) || (!Config.GetBoolean(Config.IgnoreJoinLeave)))
                {
                    Message msg = new Message();
                    msg.Type = MessageType.Info;
                    msg.User = parsedLine.PrefixMessage.Nickname;

                    msg.Text = String.Format("({0}) {1}", parsedLine.PrefixMessage.Prefix, "joined the channel");
                    await AddMessage(channel, msg);
                }

                channelStore[channel].AddUser(parsedLine.PrefixMessage.Nickname, true);
            }
            else if (parsedLine.CommandMessage.Command == "PART")
            {
                var channel = parsedLine.TrailMessage.TrailingContent;
                if (parsedLine.PrefixMessage.Nickname == this.server.username)
                {
                    RemoveChannel(channel);
                }
                else
                {
                    if (parsedLine.CommandMessage.Parameters.Count > 0)
                    {
                        channel = parsedLine.CommandMessage.Parameters[0];
                    }

                    if ((!Config.Contains(Config.IgnoreJoinLeave)) || (!Config.GetBoolean(Config.IgnoreJoinLeave)))
                    {
                        Message msg = new Message();
                        msg.Type = MessageType.Info;
                        msg.User = parsedLine.PrefixMessage.Nickname;

                        msg.Text = String.Format("({0}) {1}", parsedLine.PrefixMessage.Prefix, "left the channel");
                        await AddMessage(channel, msg);
                    }

                    channelStore[channel].RemoveUser(parsedLine.PrefixMessage.Nickname);
                }
            }
            else if (parsedLine.CommandMessage.Command == "PRIVMSG")
            {
                // handle messages to this irc client
                var destination = parsedLine.CommandMessage.Parameters[0];
                var content     = parsedLine.TrailMessage.TrailingContent;

                if (destination == server.username)
                {
                    destination = parsedLine.PrefixMessage.Nickname;
                }

                if (!channelList.Contains(destination))
                {
                    await AddChannel(destination);
                }

                Message msg = new Message();

                msg.Type = MessageType.Normal;
                msg.User = parsedLine.PrefixMessage.Nickname;
                if (parsedLine.ServerTime != null)
                {
                    var time = DateTime.Parse(parsedLine.ServerTime);
                    msg.Timestamp = time.ToString("HH:mm");
                }

                if (content.Contains("ACTION"))
                {
                    msg.Text = content.Replace("ACTION ", "");
                    msg.Type = MessageType.Action;
                }
                else
                {
                    msg.Text = content;
                }

                var key  = Config.PerChannelSetting(this.server.name, destination, Config.AlwaysNotify);
                var ping = Config.GetBoolean(key, false);

                if (parsedLine.TrailMessage.TrailingContent.Contains(server.username) || parsedLine.CommandMessage.Parameters[0] == server.username || ping)
                {
                    if (currentChannel != destination || (App.Current as App).IncrementPings == true || MainPage.instance.currentServer == this.server.name || ping)
                    {
                        var toast = CreateMentionToast(parsedLine.PrefixMessage.Nickname, destination, content);
                        toast.ExpirationTime = DateTime.Now.AddDays(2);
                        ToastNotificationManager.CreateToastNotifier().Show(toast);
                        (App.Current as App).NumberPings++;
                    }

                    msg.Mention = parsedLine.TrailMessage.TrailingContent.Contains(server.username) || parsedLine.CommandMessage.Parameters[0] == server.username;
                }

                await AddMessage(destination, msg);
            }
            else if (parsedLine.CommandMessage.Command == "KICK")
            {
                // handle messages to this irc client
                var destination = parsedLine.CommandMessage.Parameters[0];
                var reciever    = parsedLine.CommandMessage.Parameters[1];
                var content     = parsedLine.TrailMessage.TrailingContent;
                if (!channelList.Contains(destination))
                {
                    AddChannel(destination);
                }

                Message msg = new Message();

                msg.Type = MessageType.Info;

                if (reciever == server.username)
                {
                    var kickTitle = String.Format("{0} kicked you from {1}", parsedLine.PrefixMessage.Nickname, destination);

                    var toast = CreateBasicToast(kickTitle, content);
                    toast.ExpirationTime = DateTime.Now.AddDays(2);
                    ToastNotificationManager.CreateToastNotifier().Show(toast);
                    msg.User = parsedLine.PrefixMessage.Nickname;
                    msg.Text = "kicked you from the channel: " + content;
                }
                else
                {
                    msg.User = parsedLine.PrefixMessage.Nickname;
                    msg.Text = String.Format("kicked {0} from the channel: {1}", reciever, content);
                }

                await AddMessage(destination, msg);
            }
            else if (parsedLine.CommandMessage.Command == "353")
            {
                // handle /NAMES
                var list    = parsedLine.TrailMessage.TrailingContent.Split(' ').ToList();
                var channel = parsedLine.CommandMessage.Parameters[2];

                if (!channelList.Contains(channel))
                {
                    await AddChannel(channel);
                }

                channelStore[channel].AddUsers(list);

                if (!IsBouncer)
                {
                    channelStore[channel].SortUsers();
                }
            }
            else if (parsedLine.CommandMessage.Command == "332")
            {
                // handle initial topic recieve
                var topic   = parsedLine.TrailMessage.TrailingContent;
                var channel = parsedLine.CommandMessage.Parameters[1];

                if (!channelList.Contains(channel))
                {
                    await AddChannel(channel);
                }

                Message msg = new Message();
                msg.Type = MessageType.Info;

                msg.User = "";
                msg.Text = String.Format("Topic for channel {0}: {1}", channel, topic);
                await AddMessage(channel, msg);

                channelStore[channel].SetTopic(topic);
            }
            else if (parsedLine.CommandMessage.Command == "TOPIC")
            {
                // handle topic recieved
                var topic   = parsedLine.TrailMessage.TrailingContent;
                var channel = parsedLine.CommandMessage.Parameters[0];

                if (!channelList.Contains(channel))
                {
                    await AddChannel(channel);
                }

                Message msg = new Message();
                msg.Type = MessageType.Info;

                msg.User = "";
                msg.Text = String.Format("Topic for channel {0}: {1}", channel, topic);
                await AddMessage(channel, msg);

                channelStore[channel].SetTopic(topic);
            }
            else if (parsedLine.CommandMessage.Command == "QUIT")
            {
                var username = parsedLine.PrefixMessage.Nickname;
                foreach (var channel in channelList)
                {
                    var users = channelStore[channel.Name];
                    if (users.HasUser(username))
                    {
                        if ((!Config.Contains(Config.IgnoreJoinLeave)) || (!Config.GetBoolean(Config.IgnoreJoinLeave)))
                        {
                            Message msg = new Message();
                            msg.Type = MessageType.Info;
                            msg.User = parsedLine.PrefixMessage.Nickname;
                            msg.Text = String.Format("({0}) {1}: {2}", parsedLine.PrefixMessage.Prefix, "quit the server", parsedLine.TrailMessage.TrailingContent);
                            await AddMessage(channel.Name, msg);
                        }

                        users.RemoveUser(username);
                    }
                }
            }
            else if (parsedLine.CommandMessage.Command == "MODE")
            {
                Debug.WriteLine(parsedLine.CommandMessage.Command + " - " + receivedData);

                if (parsedLine.CommandMessage.Parameters.Count > 2)
                {
                    var channel = parsedLine.CommandMessage.Parameters[0];

                    if (parsedLine.CommandMessage.Parameters.Count == 3)
                    {
                        string currentPrefix = channelStore[channel].GetPrefix(parsedLine.CommandMessage.Parameters[2]);
                        string prefix        = "";
                        string mode          = parsedLine.CommandMessage.Parameters[1];
                        if (mode == "+o")
                        {
                            if (currentPrefix.Length > 0 && currentPrefix[0] == '+')
                            {
                                prefix = "@+";
                            }
                            else
                            {
                                prefix = "@";
                            }
                        }
                        else if (mode == "-o")
                        {
                            if (currentPrefix.Length > 0 && currentPrefix[1] == '+')
                            {
                                prefix = "+";
                            }
                        }
                        else if (mode == "+v")
                        {
                            if (currentPrefix.Length > 0 && currentPrefix[0] == '@')
                            {
                                prefix = "@+";
                            }
                            else
                            {
                                prefix = "+";
                            }
                        }
                        else if (mode == "-v")
                        {
                            if (currentPrefix.Length > 0 && currentPrefix[0] == '@')
                            {
                                prefix = "@";
                            }
                            else
                            {
                                prefix = "";
                            }
                        }

                        channelStore[channel].ChangePrefix(parsedLine.CommandMessage.Parameters[2], prefix);
                    }

                    ClientMessage(channel, "Mode change: " + String.Join(" ", parsedLine.CommandMessage.Parameters));
                }
            }
            else if (parsedLine.CommandMessage.Command == "470")
            {
                RemoveChannel(parsedLine.CommandMessage.Parameters[1]);
                AddChannel(parsedLine.CommandMessage.Parameters[2]);
            }
            else if (WhoisCmds.Any(str => str.Contains(parsedLine.CommandMessage.Command)))
            {
                var cmd = parsedLine.CommandMessage.Command;
                if (currentWhois == "")
                {
                    currentWhois += "Whois for " + parsedLine.CommandMessage.Parameters[1] + ": \r\n";
                }

                var whoisLine = "";

                if (cmd == "330")
                {
                    whoisLine    += parsedLine.CommandMessage.Parameters[1] + " " + parsedLine.TrailMessage.TrailingContent + " " + parsedLine.CommandMessage.Parameters[2] + " ";
                    currentWhois += whoisLine + "\r\n";
                }
                else
                {
                    for (int i = 2; i < parsedLine.CommandMessage.Parameters.Count; i++)
                    {
                        whoisLine += parsedLine.CommandMessage.Command + " " + parsedLine.CommandMessage.Parameters[i] + " ";
                    }
                    currentWhois += whoisLine + parsedLine.TrailMessage.TrailingContent + "\r\n";
                }
            }
            else if (parsedLine.CommandMessage.Command == "318")
            {
                Debug.WriteLine(currentWhois);
                Message msg = new Message();
                msg.Text = currentWhois;
                msg.Type = MessageType.Info;
                await AddMessage(currentChannel, msg);

                currentWhois = "";
            }
            else if (parsedLine.CommandMessage.Command == "376")
            {
                if (server.nickservPassword != null && server.nickservPassword != "")
                {
                    SendMessage("nickserv", "identify " + server.nickservPassword);
                }

                if (server.channels != null && server.channels != "")
                {
                    var channelsList = server.channels.Split(',');
                    foreach (string channel in channelsList)
                    {
                        JoinChannel(channel);
                    }
                }
            }
            else
            {
                if (!parsedLine.PrefixMessage.IsUser)
                {
                    if (!channelList.Contains("Server"))
                    {
                        AddChannel("Server");
                    }

                    Message msg = new Message();
                    msg.Text = parsedLine.OriginalMessage;
                    msg.Type = MessageType.Info;
                    msg.User = "";
                    await AddMessage("Server", msg);
                }
                Debug.WriteLine(parsedLine.CommandMessage.Command + " - " + receivedData);
            }

            //Debug.WriteLine(parsedLine.CommandMessage.Command + " - " + receivedData);
        }