您的代码中存在一个根本缺陷,必须先修复才能进一步了解。
IRC 是基于行的协议,但您不是逐行阅读。相反,您一次最多读取 4096 个字节。这可以返回一行的前半部分,或者一行的中间三分之一,或者一行的最后三分之一,然后是两行完整的行和第四行的前两个字符。
如果你不明白为什么这是个问题:想象一下,一个read
返回以 结尾的东西'\r\nPI'
,而下一个返回以 开头的东西'NG foo\r\n'
。这些都不匹配你的find('PING')
,所以你会错过命令。
解决此问题的最简单方法是将循环更改为以下内容:
for line in irc.makefile():
作为一个小提示,您可能想要'!quit' in data
而不是data.find ('!quit') != -1
.
最后,我认为这不是您真正想要的(尽管我可能是错的):
if data.find ('!enc %s\r\n' % werd) != -1:
irc.send ("PRIVMSG %s :%s\r\n" % (channel,werd))
如果是来自其他地方的静态字符串,这将起作用werd
,但是根据您的描述,听起来您希望能够捕获任何命令!enc foo\r\n
并返回PRIVMSG #chan: foo\r\n
,并且还捕获!enc bar\r\n
并返回PRIVMSG #chan: bar\r\n
,等等,以应对某人可能的任何其他可能性类型。为此,您可能需要一个正则表达式,或者您可能只需要稍微复杂的字符串处理代码(例如,data
用空格分隔,如果任何元素匹配'!enc'
,则下一个元素是要发回的单词)。
这是一种方法的示例,它可能会或可能不会像您正在尝试做的事情:
m = re.search(r'!enc (.*)\r\n', line)
if m:
irc.send('PRIVMSG %s: %s\r\n' % (channel, m.group(1)))
我想要这样的东西:“!test word”并让它输出类似“word2”的东西
好的,那么当给定“word”时,它如何确定您想要“word2”?无论规则是什么,您显然都必须在某个地方对该规则进行编码。或者,如果您需要编码帮助,您必须向我们描述。
从评论:
我只想要“!test x”。用户输入“!test x”,我对“x”做一些事情并输出更改
我假设您在x
这里使用的是元变量,而不是文字——也就是说,如果用户对"!test x"
做事"x"
,如果用户对"!test y"
做事"y"
,等等。如果我错了,请告诉我.
显然,上面的代码不会捕捉到这一点,因为它正在搜索“enc”而不是“test”。但这是一个微不足道的变化:
m = re.search(r'!test (.*)\r\n', line)
至于在输出之前对 x “做点什么”,m.group(1)
就是x
上面的,所以:
if m:
irc.send('PRIVMSG %s: %s\r\n' % (channel, do_stuff_to(m.group(1))))
如果你不确定你在发送、接收和解析什么,你总是可以添加一个 print 语句来测试一下:
m = re.search(r'!test (.*)\r\n', line)
print m, m.groups() if m else ''
if m:
print 'got %s, sending %s' % (m.group(1), do_stuff_to(m.group(1))))
irc.send('PRIVMSG %s: %s\r\n' % (channel, do_stuff_to(m.group(1))))
如果您想查看套接字上发生的事情,有两种方法可以做到这一点:安装wireshark并使用它来监视网络上的消息,或者使用netcat设置假服务器。前者我就不解释了,因为要解释的太多了,而且已经有很好的教程了。但对于后者,就这么简单:打开终端并运行nc -kl 8888
. 然后让你的机器人连接到localhost:8888
而不是远程服务器。观察机器人发送给您的内容,然后将回复键入或粘贴到终端窗口中。(在除 Windows 之外的几乎所有平台上,nc 都是内置的;在 Windows 上,您需要从某个地方获取 netcat 或 ncat,但我很确定 Wikipedia 页面有链接。)如果您需要进行大量调试,您可以将 netcat 设置为代理,仅在您的机器人和真实服务器之间来回转发消息并打印出所有通过的信息。