Пример #1
0
        public Task InvokeConnectHandler(MqttClientConnectedEventArgs args, CancellationToken token = default)
        {
            Delegate[] invocations = OnConnect?.GetInvocationList();
            if (invocations == null)
                return Task.CompletedTask;

            Task[] tasks = new Task[invocations.Length];
            for (int index = 0; index < invocations.Length; index++)
            {
                Delegate invocation = invocations[index];
                tasks[index] = (Task)invocation.DynamicInvoke(args, token);
            }

            return Task.WhenAll(tasks);
        }
Пример #2
0
        public IrcClient()
        {
            ServerInfo = new ServerInfoType();

            Encoding    = new System.Text.UTF8Encoding(false);
            Registered  = false;
            LastMessage = DateTime.Now;
            Timeout     = new TimeSpan(0, 5, 0);
            Connected   = false;

            #region Register Delegates

            OnRawMessageReceived += ErrorHandler; // This one looks for ERROR messages
            OnRawMessageReceived += PingHandler;
            OnRawMessageReceived += NumericHandler;
            OnRawMessageReceived += PrivmsgHandler;
            OnRfcNumeric         += (sender, source, numeric, target, other) => { if (numeric == 1 && OnConnect != null)
                                                                                  {
                                                                                      foreach (var d in OnConnect.GetInvocationList())
                                                                                      {
                                                                                          Task.Run(() => d.DynamicInvoke(this));
                                                                                      }
                                                                                  }
            };
            OnRfcNumeric += (sender, source, numeric, target, other) =>
            {
                if (numeric == 353 && OnNamesReply != null)
                {
                    String[] words   = other.Split(' ');
                    String   channel = words[1];
                    foreach (var d in OnNamesReply.GetInvocationList())
                    {
                        Task.Run(() => d.DynamicInvoke(this, channel, other.Substring(other.IndexOf(':') + 1)));
                    }
                }
            };

            OnRfcNumeric += (sender, source, numeric, target, other) =>
            {
                if (numeric == 5 && OnISupport != null)
                {
                    Dictionary <String, String> parameters = new Dictionary <string, string>();
                    String[] tokens = other.Split(' ');
                    foreach (String token in tokens)
                    {
                        int equalIndex = token.IndexOf('=');
                        if (equalIndex >= 0)
                        {
                            parameters[token.Substring(0, equalIndex)] = token.Substring(equalIndex + 1);
                        }
                        else
                        {
                            parameters[token] = "";
                        }
                    }
                    foreach (var d in OnISupport.GetInvocationList())
                    {
                        Task.Run(() => d.DynamicInvoke(this, parameters));
                    }
                }
            };
            OnConnect  += (sender) => { lock (channels) { channels.Clear(); } };
            OnISupport += (sender, parameters) =>
            {
                try
                {
                    sender.ServerInfo.PREFIX = parameters["PREFIX"];
                }
                catch (KeyNotFoundException) { };

                try
                {
                    sender.ServerInfo.CHANMODES = parameters["CHANMODES"];
                }
                catch (KeyNotFoundException) { };
                if (parameters.ContainsKey("UHNAMES"))
                {
                    var task = SendRawMessage("PROTOCTL UHNAMES");
                }


                if (parameters.ContainsKey("NAMESX"))
                {
                    var task = SendRawMessage("PROTOCTL NAMESX");
                }
            };

            OnRawMessageReceived += (source, message) =>
            {
                String[] tokens = message.Split(' ');
                if (OnRfcJoin != null && tokens.Length >= 3 && tokens[1].Equals("JOIN"))
                {
                    foreach (var d in OnRfcJoin.GetInvocationList())
                    {
                        Task.Run(() => d.DynamicInvoke(this, tokens[0].Replace(":", ""), tokens[2].Replace(":", "")));
                    }
                }
            };

            OnRfcJoin += (sender, source, channellist) =>
            {
                /// If the user joining is me, add it to the channel list.
                /// If we have a channel already, add the guy to it.


                foreach (String channelName in channellist.Split(','))
                {
                    Channel c = null;
                    lock (channels)
                    {
                        channels.TryGetValue(channelName.ToLower(), out c);
                        if (c == null && ChannelUser.GetNickFromFullAddress(source).Equals(Nick, StringComparison.CurrentCultureIgnoreCase))
                        {
                            c = new Channel(channelName);
                            channels[channelName.ToLower()] = c;
                        }

                        if (c != null)
                        {
                            ChannelUser u = new ChannelUser(source, c);
                            c.Users[u.Nick.ToLower()] = u;
                        }
                    }
                }
            };

            OnRawMessageReceived += (sender, message) =>
            {
                String[] tokens = message.Split(' ');
                if (tokens.Length >= 5 && tokens[1].Equals("KICK"))
                {
                    String source = tokens[0].Replace(":", ""), channel = tokens[2], target = tokens[3];
                    String reason = message.Substring(message.IndexOf(':', 1));
                    if (OnRfcKick != null)
                    {
                        foreach (var d in OnRfcKick.GetInvocationList())
                        {
                            Task.Run(() => d.DynamicInvoke(this, source, target, channel, reason));
                        }
                    }
                }
            };
            // Catches a part
            OnRawMessageReceived += (sender, message) =>
            {
                String[] tokens = message.Split(' ');
                if (OnRfcPart != null && tokens.Length >= 3 && tokens[1].Equals("PART"))
                {
                    String reason = tokens.Length >= 4 ? message.Substring(message.IndexOf(':', 1)) : null;
                    foreach (var d in OnRfcPart.GetInvocationList())
                    {
                        Task.Run(() => d.DynamicInvoke(this, tokens[0].Replace(":", ""), tokens[2], reason));
                    }
                }
            };
            OnRawMessageReceived += (sender, message) =>
            {
                String[] tokens = message.Split(' ');
                if (tokens.Length >= 4 && tokens[1].Equals("MODE") && OnRfcMode != null)
                {
                    foreach (var d in OnRfcMode.GetInvocationList())
                    {
                        Task.Run(() => d.DynamicInvoke(sender, tokens[0].Replace(":", ""), tokens[2], message.Substring(message.IndexOf(tokens[2]) + tokens[2].Length + 1)));
                    }
                }
            };

            // On part, we should remove the nick from the channel. If it's US parting, we should remove the channel from channels
            OnRfcPart += (sender, source, channel, reason) =>
            {
                Channel channelObject = null;
                lock (channels)
                {
                    channels.TryGetValue(channel.ToLower(), out channelObject);
                    if (channelObject != null)
                    {
                        if (ChannelUser.GetNickFromFullAddress(source).Equals(Nick, StringComparison.CurrentCultureIgnoreCase))
                        {
                            channels.Remove(channel.ToLower());
                        }
                        else
                        {
                            try
                            {
                                channelObject.Users.Remove(ChannelUser.GetNickFromFullAddress(source));
                            }
                            catch (Exception) { }
                        }
                    }
                }
            };

            OnRfcKick += (sender, source, target, channel, reason) =>
            {
                Channel channelObject = null;
                channels.TryGetValue(channel.ToLower(), out channelObject);
                if (channelObject != null)
                {
                    if (Nick.Equals(target, StringComparison.CurrentCultureIgnoreCase)) // If it's us, remove the channel
                    {
                        channels.Remove(channel.ToLower());
                    }
                    else // else remove the nick from the channel
                    {
                        try
                        {
                            channelObject.Users.Remove(target.ToLower());
                        }
                        catch (Exception) { }
                    }
                }
            };
            OnRawMessageReceived += (source, message) => { LastMessage = DateTime.Now; };
            OnNamesReply         += NamesReplyHandler;

            // Updates prefix list for users of a channel when modes are changed
            OnRfcMode += (sender, source, target, modes) =>
            {
                Channel channel = null;
                channels.TryGetValue(target.ToLower(), out channel);
                if (channels == null)
                {
                    return;
                }


                String[] tokens = modes.Split(' ');

                bool isSet = false;
                for (int modeIndex = 0, parameterIndex = 1; modeIndex < tokens[0].Length; ++modeIndex)
                {
                    char mode = tokens[0][modeIndex];
                    if (mode == '+')
                    {
                        isSet = true;
                    }
                    else if (mode == '-')
                    {
                        isSet = false;
                    }
                    else if (ServerInfo.CHANMODES_parameterNever.Contains(mode))
                    {
                        continue;
                    }
                    else if (ServerInfo.CHANMODES_paramaterToSet.Contains(mode))
                    {
                        if (isSet)
                        {
                            ++parameterIndex;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        try
                        {
                            // If it's a user access mode
                            if (ServerInfo.PREFIX_modes.Contains(mode))
                            {
                                ChannelUser user = null;
                                channel.Users.TryGetValue(tokens[parameterIndex].ToLower(), out user);
                                if (user != null)
                                {
                                    char prefix = ServerInfo.PREFIX_symbols[ServerInfo.PREFIX_modes.IndexOf(mode)];
                                    if (isSet)
                                    {
                                        user.InsertPrefix(ServerInfo, target, prefix);
                                    }
                                    else
                                    {
                                        user.DeletePrefix(target, prefix);
                                    }
                                }
                            }
                        }
                        catch (Exception) { }
                        finally
                        {
                            // These modes always have parameters so we need to always increase the index at the end
                            ++parameterIndex;
                        }
                    }
                }
            };

            OnRawMessageReceived += (sender, message) =>
            {
                String[] tokens = message.Split(' ');
                if (tokens.Length >= 3 && tokens[1].Equals("NICK") && OnRfcNick != null)
                {
                    foreach (var d in OnRfcNick.GetInvocationList())
                    {
                        Task.Run(() => d.DynamicInvoke(sender, tokens[0].Replace(":", ""), tokens[2].Replace(":", "")));
                    }
                }
            };

            OnRfcNick += (sender, source, newnick) =>
            {
                String      oldnick = ChannelUser.GetNickFromFullAddress(source).ToLower();
                ChannelUser user    = null;
                foreach (Channel c in channels.Values)
                {
                    c.Users.TryGetValue(oldnick, out user);
                    if (user != null)
                    {
                        user.Nick = newnick;
                        c.Users.Remove(oldnick);
                        c.Users[newnick] = user;
                    }
                }
            };

            OnRawMessageReceived += (sender, message) =>
            {
                String[] tokens = message.Split(' ');
                if (tokens.Length >= 3 && OnRfcQuit != null && tokens[1].Equals("QUIT"))
                {
                    foreach (var d in OnRfcQuit.GetInvocationList())
                    {
                        Task.Run(() => d.DynamicInvoke(sender, tokens[0].Replace(":", ""), message.Substring(message.IndexOf(":", 1))));
                    }
                }
            };
            OnRfcQuit += (sender, source, message) =>
            {
                String nick = ChannelUser.GetNickFromFullAddress(source);
                foreach (Channel c in channels.Values)
                {
                    try { c.Users.Remove(nick.ToLower()); }
                    catch (Exception) { }
                }
            };
            #endregion Register Delegates
        }