ircDotNet bot fails to get messages from IRC channel, long login/logout
我正在尝试为IRC通道编写bot,它将从通道读取消息,识别它们是否是命令,并根据发送的命令执行一些操作。我之所以选择ircdotnet,是因为它是唯一一个包含了一些如何使用它的示例的库,但是它们实际上已经非常过时了,只有一半是有效的。我在C和编程方面的经验不足,根本不允许我在没有好例子的情况下理解东西:(
所以我的程序现在做的是:
- 使用密码登录到服务器
- 加入通道
- 注销(非常麻烦)
我不能捕捉和发送任何来自和到一个频道的信息,我不能立即注销。
用于登录的全局类和事件中无处不在的IRCClient类示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
所有当前事件:
1 2 3 4 5 6 7 8 9 10 | 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());} } |
登录按钮代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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是否连接,并执行一些操作。然后在该操作之后,相应的事件将升起,再次启用该按钮。但退出功能工作很慢,或者根本不工作,bot将一直在通道中,直到我不关闭程序(也许我需要释放ircclient?)
连接和断开事件。在连接事件中,bot将加入通道。按下Connect(连接)按钮后约30秒,Bot出现在频道上,但在2-3秒后引发Connected(连接)事件。断开-断开事件也会很快发生,但bot在通道上停留的时间更长(约120秒)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 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(); } |
加入通道和消息接收事件。他们从不抚养孩子,不知道为什么。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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); } } |
所以,主要的问题是:我如何捕捉来自频道的消息,以及如何向频道发送消息?我会很感激任何例子。您可以在以下位置找到所有代码:http://pastebin.com/tbkfl3vq谢谢
在添加事件之前尝试加入频道。
1 2 | gIrcClient.Channels.Join("#my_channel"); gIrcClient.LocalUser.JoinedChannel += LocalUser_JoinedChannel; |
我的建议是先尝试添加事件,如下所示:
1 2 | gIrcClient.LocalUser.JoinedChannel += LocalUser_JoinedChannel; gIrcClient.Channels.Join("#my_channel"); |
irc.net库中有一个bug,twitch.tv使用的是一个非标准的消息回复,它正在触发irc.net。
我在这里创建了一个描述它的bug。但基本上抽搐发出"欢迎,GLHF!"作为RPL_欢迎信息。IRC RFC描述了"欢迎使用互联网中继网络"消息的格式。@。
irc.net将glhf从欢迎消息中解析为您的昵称,该昵称用于触发JoinedChannel和MessageReceived事件等操作。
我的解决方案是下载源代码,并在接收到RPL_欢迎信息时指出它在哪里设置了昵称。它从传递给ircclient构造函数的ircRegistrationInfo中正确设置昵称,不需要从twitch的欢迎消息中进行解析。不确定这是否适用于其他IRC服务器。
该函数在ircclientmessageprocessing.cs中称为processmessagereplywelcome:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /// <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在与您相关的消息中使用的大小写匹配。都是小写的。