首页 文章

ircDotNet bot无法从IRC Channels 获取消息,长时间登录/注销

提问于
浏览
1

我正在尝试为irc Channels 编写机器人,它将从 Channels 读取消息,识别它们是否是对他的命令并且执行某些操作取决于发送的命令 . 我选择了ircDotNet,因为它是唯一包含一些如何使用它的例子的库,但它们实际上已经过时了,只有一半有效 . 我缺乏C#和编程方面的经验并不能让我理解没有好例子的东西:(

那么我的程序现在做了什么:

  • 使用密码登录服务器

  • 加入 Channels

  • 退出(非常多)

我无法捕获并向 Channels 发送任何消息,我无法立即注销 .

用于登录的全局类和在事件中随处使用的IrcClient类示例

public IrcRegistrationInfo  irc_iri 
        {
            get
            {
                return new IrcUserRegistrationInfo()
                {
                    NickName = "jsBot",
                    UserName = "jsBot",
                    RealName = "jsBot",
                    Password = "oauth:p4$$w0rdH3Re48324729214812489"
                };
            }
        }
   public IrcClient gIrcClient = new IrcClient();

所有时事:

private void Form1_Load(object sender, EventArgs e)
    {
        try
        {
            gIrcClient.Connected += ircClient_Connected;
            gIrcClient.Disconnected += gIrcClient_Disconnected;
            gIrcClient.FloodPreventer = new IrcStandardFloodPreventer(1, 10000);
        }
        catch (Exception ex) { MessageBox.Show(ex.ToString());}
    }

登录按钮代码:

private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;

            if (!gIrcClient.IsConnected)
            {
                button1.Text = "Connecting...";
                gIrcClient.Connect("irc.twitch.tv", 6667, false, irc_iri);
            }
            else
            {
                button1.Text = "Disconnecting...";
                gIrcClient.Quit(5000, "bye");
            }
        }

逻辑是:程序检查ircClient是否连接,并执行一些操作 . 然后在该操作之后将提升相应的事件,再次启用该按钮 . 但是Quit功能运行速度非常慢或根本不起作用,机器人会留在通道直到我不关闭我的程序(也许我需要处理ircclient?)

连接和断开事件 . 在连接事件中,bot将加入 Channels . 按下连接按钮后约30秒后,Bot出现在 Channels ,但2-3秒后连接事件被提升 . 同样对于断开连接 - 断开连接事件会迅速提升,但是僵尸程序会在通道上停留更长时间(大约120秒) .

void ircClient_Connected(object sender, EventArgs e)
        {
            try
            {
                if (button1.InvokeRequired)
                {
                    MethodInvoker del = delegate { 
                        button1.Text = "Disconnect"; 
                        button1.Enabled = true; };
                    button1.Invoke(del);
                }
                else
                {
                    button1.Text = "Disconnect"; 
                    button1.Enabled = true;
                }
                gIrcClient.Channels.Join("#my_channel");   
                gIrcClient.LocalUser.JoinedChannel += LocalUser_JoinedChannel;             
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        void gIrcClient_Disconnected(object sender, EventArgs e)
        {
            if (!gIrcClient.IsConnected)
            {
                try
                {
                    if (button1.InvokeRequired)
                    {
                        MethodInvoker del = delegate
                        {
                            button1.Text = "Connect";
                            button1.Enabled = true;
                        };
                        button1.Invoke(del);
                    }
                    else
                    {
                        button1.Text = "Connect";
                        button1.Enabled = true;
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }
            else gIrcClient.Disconnect();
        }

加入 Channels 和消息接收事件 . 他们永远不会提高,也不知道为什么 .

void LocalUser_JoinedChannel(object sender, IrcChannelEventArgs e)
        {
            try
            {                
                gIrcClient.Channels[0].MessageReceived += Form1_MessageReceived;
                gIrcClient.LocalUser.SendMessage(e.Channel, "test");
                MessageBox.Show(gIrcClient.Channels[0].Users[0].User.NickName);
                MessageBox.Show("bot_join_channel_event_raised");
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        void Form1_MessageReceived(object sender, IrcMessageEventArgs e)
        {
            try
            {
                if (e.Text.Equals("asd"))
                    gIrcClient.LocalUser.SendMessage(e.Targets, "received");
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

所以主要问题是:我如何从 Channels 捕捉消息以及如何向 Channels 发送消息?我会很感激任何例子 . 你可以在这里找到所有代码:http://pastebin.com/TBkfL3Vq谢谢

2 回答

  • 1

    您尝试在添加事件之前加入 Channels .

    gIrcClient.Channels.Join("#my_channel");   
      gIrcClient.LocalUser.JoinedChannel += LocalUser_JoinedChannel;
    

    我的建议是尝试首先添加事件,如下所示:

    gIrcClient.LocalUser.JoinedChannel += LocalUser_JoinedChannel;
      gIrcClient.Channels.Join("#my_channel");
    
  • 0

    IRC.NET库中存在一个错误,twitch.tv使用的是非标准的消息回复,它正在使IRC.NET瘫痪 .

    我创建了一个描述它的错误here . 但基本上抽搐发送"Welcome, GLHF!"作为RPL_WELCOME消息 . IRC RFC描述了消息的格式为"Welcome to the Internet Relay Network !@" .

    IRC.NET将欢迎消息中的GLHF解析为您的昵称,用于触发JoinedChannel和MessageRecieved事件 .

    我的解决方案是下载源代码并在收到RPL_WELCOME消息时注释掉它设置昵称的位置 . 它从传递给IrcClient构造函数的IrcRegistrationInfo中正确设置了昵称,并且不需要从twitch的欢迎消息中解析 . 不确定其他IRC服务器是否属于这种情况 .

    该函数在IrcClientMessageProcessing.cs中称为ProcessMessageReplyWelcome:

    /// <summary>
        /// Process RPL_WELCOME responses from the server.
        /// </summary>
        /// <param name="message">The message received from the server.</param>
        [MessageProcessor("001")]
        protected void ProcessMessageReplyWelcome(IrcMessage message)
        {
            Debug.Assert(message.Parameters[0] != null);
    
            Debug.Assert(message.Parameters[1] != null);
            this.WelcomeMessage = message.Parameters[1];
    
            // Extract nick name, user name, and host name from welcome message. Use fallback info if not present.
            var nickNameIdMatch = Regex.Match(this.WelcomeMessage.Split(' ').Last(), regexNickNameId);
            //this.localUser.NickName = nickNameIdMatch.Groups["nick"].GetValue() ?? this.localUser.NickName;
            this.localUser.UserName = nickNameIdMatch.Groups["user"].GetValue() ?? this.localUser.UserName;
            this.localUser.HostName = nickNameIdMatch.Groups["host"].GetValue() ?? this.localUser.HostName;
    
            this.isRegistered = true;
            OnRegistered(new EventArgs());
        }
    

    一个更复杂的解决方案可能是改进昵称Regex,因此它与GLHF!不匹配,我认为这不是一个有效的昵称 .

    IRC.NET使用区分大小写的字符串比较来按昵称查找用户 . 因此,传入昵称的IrcRegistrationInfo的值必须与twitch在与您有关的消息中使用的大小写相匹配 . 这都是小写的 .

相关问题